我明白楼主的想法,其他铁子一直跟你说用测量工具,这确实是正解。你应该是想了解一下首先自己该如何精确定位然后配合卡尺工具是吧?
他们写的一些阈值方法工业上一般不用,我下面这个刚好最近项目用到,你可以看一下。
开头代码:
read_image (ImageFull, 'C:/Users/SYKJ/Desktop/dlRes/1.1.jpg')
get_image_size(ImageFull, Width, Height)
crop_part(ImageFull, ImagePart, 0, 0, Width, 100)
*封装抓边函数&&
CalDetectEdges (ImagePart, ContourLeftPosi, ContourRightPosi, [0], 0, 0, Row1PosiLeft, Col1PosiLeft, Row2PosiRight, Col2PosiRight)
/////////////////////////////////
函数CalDetectEdges 详细如下:
* 数据清洗
RowLeft := []
ColLeft := []
RowRight := []
ColRight := []
get_image_size (InputImg, Width, Height)
* 第一次常规检测
CalDetectAreaEdgePart (InputImg, 25, Width, Height, InParam[0], Row1Detect, Col1Detect, Row2Detect, Col2Detect, iResultDetect)
* 第三次降低阈值检测
if (iResultDetect == -1)
CalDetectAreaEdgePart (InputImg, 18, Width, Height, InParam[0], Row1Detect, Col1Detect, Row2Detect, Col2Detect, iResultDetect)
endif
* 显示边缘点
** gen_cross_contour_xld (Cross, Row1Detect, Col1Detect, 100, 0.785398)
** gen_cross_contour_xld (Cross, Row2Detect, Col2Detect, 100, 0.785398)
* 剪裁边缘以进行检测
crop_part (InputImg, ImagePartLeft, 0, Col1Detect-40, 80, Height)
crop_part (InputImg, ImagePartRight, 0, Col2Detect-40, 80, Height)
CalGrabLineAreaEdgePart (ImagePartLeft, 0, 39, Height-1, 39, InParam[0], InParam[0], 40, 40, 15, 40, 25, LineOutBeginRow1, LineOutBeginCol1, LineOutEndRow2, LineOutEndCol2, iResultLeft)
if (iResultLeft == -1)
* 失败后的第二次查找
CalGrabLineAreaEdgePart (ImagePartLeft, 0, 39, Height-1, 39, InParam[0], InParam[0], 40, 40, 10, 40, 25, LineOutBeginRow1, LineOutBeginCol1, LineOutEndRow2, LineOutEndCol2, iResultLeft)
endif
CalGrabLineAreaEdgePart (ImagePartRight, 0, 39, Height-1, 39, InParam[0], InParam[0], 40, 40, 15, 40, 25, LineOutBeginRow3, LineOutBeginCol3, LineOutEndRow4, LineOutEndCol4, iResultRight)
if (iResultRight == -1)
* 失败后的第二次查找
CalGrabLineAreaEdgePart (ImagePartRight, 0, 39, Height-1, 39, InParam[0], InParam[0], 40, 40, 10, 40, 25, LineOutBeginRow3, LineOutBeginCol3, LineOutEndRow4, LineOutEndCol4, iResultRight)
endif
* 添加一下保护
if (iResultLeft == 0)
* 直接返回坐标即可
RowLeft := [LineOutBeginRow1, LineOutEndRow2] + ReturnRow
ColLeft := [LineOutBeginCol1+Col1Detect-40, LineOutEndCol2+Col1Detect-40] + ReturnCol
SortPoints (RowLeft, ColLeft, 0, 'Row', RowLeft, ColLeft)
gen_contour_polygon_xld (ContourLeft, RowLeft, ColLeft)
else
RowLeft := [0, Height-1]
ColLeft := [0, 0]
endif
if (iResultRight == 0)
RowRight := [LineOutBeginRow3, LineOutEndRow4] + ReturnRow
ColRight := [LineOutBeginCol3+Col2Detect-40, LineOutEndCol4+Col2Detect-40] + ReturnCol
SortPoints (RowRight, ColRight, 0, 'Row', RowRight, ColRight)
* 显示结果
gen_contour_polygon_xld (ContourRight, RowRight, ColRight)
else
RowRight := [0, Height-1]
ColRight := [Width-1, Width-1]
endif
return ()
/////////////////////////////////
函数CalDetectAreaEdgePart详细如下:
try
iResultDetect := 0
* 数据初始化
Row1 := 0
Col1 := 0
Row2 := 0
Col2 := 0
* 图像缩放以减小时间
zoom_image_size (InputImg, ImageZoom, Width*0.125, Height*0.125, 'constant')
get_image_size (ImageZoom, WidthZoom, HeightZoom)
* 使用整张图像做测量
** gen_rectangle2 (Rectangle1, (HeightZoom)/2, (WidthZoom)/2, 0, (WidthZoom)/2, (HeightZoom)/2)
gen_measure_rectangle2 ((HeightZoom)/2, (WidthZoom)/2, 0, (WidthZoom)/2, (HeightZoom)/2, WidthZoom, HeightZoom, 'nearest_neighbor', MeasureHandleUp)
measure_pos (ImageZoom, MeasureHandleUp, 1, DetectThresh, 'all', 'all', RowEdgeFirstUp, ColumnEdgeFirstUp, Amplitude, Distance)
** gen_contour_polygon_xld (Contour1, [0, HeightZoom-1], [ColumnEdgeFirstUp[0], ColumnEdgeFirstUp[0]])
** gen_contour_polygon_xld (Contour2, [0, HeightZoom-1], [ColumnEdgeFirstUp[1], ColumnEdgeFirstUp[1]])
* 如果检测出多个点则使用按照Col值
if (|RowEdgeFirstUp| <= 1)
iResultDetect := -1
return ()
else
* 如果有抓取到2个以上的点则进行排序
SortPoints (RowEdgeFirstUp, ColumnEdgeFirstUp, 0, 'Col', RowEdgeFirstUp, ColumnEdgeFirstUp)
* 左右端点如下:
* 还原检测区域
Row1 := Height/2-1
Col1 := ColumnEdgeFirstUp[0]/0.125
Row2 := Height/2-1
Col2 := ColumnEdgeFirstUp[|ColumnEdgeFirstUp|-1]/0.125
endif
** dev_display (InputImg)
** gen_cross_contour_xld (Cross, Row1, Col1, 100, 0.785398)
** gen_cross_contour_xld (Cross, Row2, Col2, 100, 0.785398)
** stop ()
return ()
catch (Exception)
iResultDetect := -1
return ()
endtry
/////////////////////////////////
函数CalGrabLineAreaEdgePart详细如下:
try
iResult := 0
get_image_size (ImageInput, Width, Height)
distance_pp (BeginRow, BeginCol, EndRow, EndCol, Distance)
** gen_cross_contour_xld (Cross1, BeginRow, BeginCol, 100, 0.785398)
** gen_cross_contour_xld (Cross1, EndRow, EndCol, 100, 0.785398)
measureRecLen1 := MeasureLength
measureRecLen2 := MeasureLength2
* 测量步长--移动矩形的步数
RowStepLength := 0
ColumnStepLength := 0
if (PhiCC == 90 or PhiCC == 270)
RowStepLength := 0
if (BeginCol <EndCol)
ColumnStepLength := int(Distance/Steps)
else
ColumnStepLength := -int(Distance/Steps)
endif
else
if (BeginRow > EndRow)
RowStepLength := -int(Distance/Steps)
else
RowStepLength := int(Distance/Steps)
endif
ColumnStepLength := 0
endif
* 测量矩形总的移动步数
measureSteps := Steps
** gen_cross_contour_xld (Cross, (BeginRow+EndRow)/2, (BeginCol+EndCol)/2, 100, 0.785398)
** gen_rectangle2 (Rectangle, (BeginRow+EndRow)/2, (BeginCol+EndCol)/2, rad(Phi), measureRecLen1, measureRecLen2)
gen_measure_rectangle2 ((BeginRow+EndRow)/2, (BeginCol+EndCol)/2, rad(Phi), measureRecLen1, measureRecLen2, Width, Height, 'nearest_neighbor', MeasureHandle)
EdgeLineRow := []
EdgeLineCol := []
for step := 0 to measureSteps by 1
translate_measure (MeasureHandle, BeginRow + step*RowStepLength, BeginCol + step*ColumnStepLength)
measure_pos (ImageInput, MeasureHandle, 1, ThreshGrab, 'all', 'all', RowEdgeFirst, ColumnEdgeFirst, Amplitude, Distance1)
if (|RowEdgeFirst| == 1)
tuple_concat (EdgeLineRow, RowEdgeFirst[0], EdgeLineRow)
tuple_concat (EdgeLineCol, ColumnEdgeFirst[0], EdgeLineCol)
elseif (|RowEdgeFirst| > 1)
FindClosePoint (RowEdgeFirst[0], StandCol, RowEdgeFirst, ColumnEdgeFirst, 0, fitRow, fitCol)
tuple_concat (EdgeLineRow, fitRow, EdgeLineRow)
tuple_concat (EdgeLineCol, fitCol, EdgeLineCol)
else
continue
endif
endfor
* 如果没有找到线段则返回失败
if (|EdgeLineRow| == 0)
iResult := -1
return ()
endif
* 拟合直线
gen_contour_polygon_xld (ContourLine, EdgeLineRow, EdgeLineCol)
fit_line_contour_xld (ContourLine, 'tukey', -1, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist)
* 返回结果
LineOutBeginRow := RowBegin
LineOutBeginCol := ColBegin
LineOutEndRow := RowEnd
LineOutEndCol := ColEnd
return ()
catch (Exception)
iResult := -1
return ()
endtry
/////////////////////////////////
函数SortPoints详细如下:
if (OrderBy == 'Col')
tuple_sort_index (Cols, Idx)
elseif (OrderBy == 'Row')
tuple_sort_index (Rows, Idx)
endif
if (IncOrDec == 0)
SortedRows := subset(Rows, Idx)
SortedCols := subset(Cols, Idx)
return ()
else
* 先进行升序
TempRows := subset(Rows, Idx)
TempCols := subset(Cols, Idx)
* 反转
tuple_inverse (TempRows, InvertedRows)
tuple_inverse (TempCols, InvertedCols)
SortedRows := InvertedRows
SortedCols := InvertedCols
return ()
endif
return ()
/////////////////////////////////
函数FindClosePoint详细如下:
tuple_length (Rows, Length)
distance := []
for I := 0 to Length-1 by 1
distance_pp (RowObj, ColObj, Rows[I], Cols[I], Dis)
tuple_concat (distance, Dis, distance)
endfor
tuple_sort_index (distance, Indices)
Rows := subset(Rows, Indices)
Cols := subset(Cols, Indices)
if (MinOrMax == 0)
* 最近
OutRow := Rows[0]
OutCol := Cols[0]
else
* 最远
OutRow := Rows[Length-1]
OutCol := Cols[Length-1]
endif
return ()
|