电路板金手指间距测量工业视觉项目源代码
最近结束了一项目,项目要实现的功能是计算上图中两金手指的间距,
将间距传递给执行机构,让上下两块板对齐。
实现的思路也是简单,如上图,
1.先是提取上边金手指,拟合成矩形,获取矩形相关几何参数。
然后是获取下边金手指区域,拟合成矩形,获取矩形相关几何参数。
2.计算下矩形中心线起点与上矩形中心线的垂直点坐标点,此点与下矩形中心线距离就为要求得的间距。
3.计算所得的间距 单位是像素单位,所以最终还得进行转换。
我们事先已知上边两金手指间距为100毫米,(厂家产品规格确定)。计算出其间隔像素单位,
这样像素毫米关系就确定,也就是间距的像素单位就可以进行转换为毫米单位。
下面为步骤2,步骤3实现的halcon代码,同时附件为一张产品图片供大家下载测试学习
如果您认可,可联系功能定制! 如果您着急,充值会员可直接联系发您资料!
- dev_close_window ()
- read_image (Image1, '1.bmp')
- dev_open_window_fit_image (Image1, 0, 0, -1, -1, WindowHandle)
- dev_display (Image1)
- get_image_size (Image1, ImageWidth, ImageHeight)
- rgb1_to_gray (Image1, Image)
- binary_threshold (Image, IconTemp, 'max_separability', 'light', UsedThreshold)
- connection (IconTemp, Icon)
- *筛选全部白色区域
- select_shape (Icon, IconTemp, ['area','ratio','column'], 'and', [2000,3,0], [999999,20,ImageWidth*0.95])
- select_shape(IconTemp, Icon, 'row1', 'and', 0, 100)
- union1 (Icon, IconTemp)
- smallest_rectangle1 (IconTemp, Row, Column, Row1, Column1)
- gen_rectangle1 (Rectangle, Row, Column, Row1/2, ImageWidth)
- reduce_domain(Image, Rectangle, IconTemp)
- binary_threshold (IconTemp, Icon, 'smooth_histo', 'dark', UsedThreshold)
- connection (Icon, IconTemp)
- select_shape (IconTemp, Icon, ['area','ratio','column'], 'and', [500,3,0], [999999,20,ImageWidth*0.95])
- sort_region (Icon, IconTemp2, 'upper_right', 'false', 'column')
- select_obj(IconTemp2, Icon, 1)
- gen_contour_region_xld (Icon, IconTemp, 'border')
- fit_rectangle2_contour_xld (IconTemp, 'regression', -1, 0, 0, 3, 2, Row, Column, Phi, Length1, Length2, PointOrder)
- *提取矩形中心线为上参考线
- get_rectangle2_points (Row, Column, Phi, Length1, Length2, CornerY, CornerX, LineCenterY, LineCenterX)
- if( Phi<=0)
- XValue := LineCenterX[3]
- YValue := LineCenterY[3]
- XValue1:= LineCenterX[1]
- YValue1:= LineCenterY[1]
- else
- XValue := LineCenterX[1]
- YValue := LineCenterY[1]
- XValue1:= LineCenterX[3]
- YValue1:= LineCenterY[3]
- endif
- *
- select_obj(IconTemp2, Icon, 2)
- gen_contour_region_xld (Icon, IconTemp, 'border')
- fit_rectangle2_contour_xld (IconTemp, 'regression', -1, 0, 0, 3, 2, Row, Column, Phi, Length1, Length2, PointOrder)
- *提取矩形中心线为上参考线
- get_rectangle2_points (Row, Column, Phi, Length1, Length2, CornerY, CornerX, LineCenterY, LineCenterX)
- if( Phi<=0)
- XValue2 := LineCenterX[3]
- YValue2 := LineCenterY[3]
- XValue3:= LineCenterX[1]
- YValue3:= LineCenterY[1]
- else
- XValue2 := LineCenterX[1]
- YValue2 := LineCenterY[1]
- XValue3:= LineCenterX[3]
- YValue3:= LineCenterY[3]
- endif
- distance_pp(YValue1, XValue1,YValue3, XValue3,Distance)
- *显示距离
- gen_contour_polygon_xld(LineXLD,[YValue,YValue1],[XValue,XValue1])
- gen_contour_polygon_xld(LineXLD1,[YValue2,YValue3],[XValue2,XValue3])
- gen_arrow_contour_xld(Arrow, YValue1, XValue1, YValue3, XValue3, 10, 10)
- gen_arrow_contour_xld(Arrow1, YValue3, XValue3, YValue1, XValue1, 10, 10)
- dev_display(Image)
- dev_set_color('red')
- dev_display(LineXLD)
- dev_display(LineXLD1)
- dev_set_color('green')
- dev_display(Arrow1)
- dev_display(Arrow)
- message := Distance[code]dev_close_window ()
- read_image (Image1, '1.bmp')
- dev_open_window_fit_image (Image1, 0, 0, -1, -1, WindowHandle)
- dev_display (Image1)
- get_image_size (Image1, ImageWidth, ImageHeight)
- rgb1_to_gray (Image1, Image)
- binary_threshold (Image, IconTemp, 'max_separability', 'light', UsedThreshold)
- connection (IconTemp, Icon)
- *筛选全部白色区域
- select_shape (Icon, IconTemp, ['area','ratio','column'], 'and', [2000,3,0], [999999,20,ImageWidth*0.95])
- *筛选上,下白色区
- select_shape(IconTemp, Icon, 'row1', 'and', 0, 100)
- difference (IconTemp, Icon, IconTemp2)
- *处理上白色
- union1 (Icon, IconTemp)
- smallest_rectangle1 (IconTemp, Row, Column, Row1, Column1)
- gen_rectangle1 (Rectangle, Row, Column, Row1/2, ImageWidth)
- reduce_domain(Image, Rectangle, IconTemp)
- binary_threshold (IconTemp, Icon, 'smooth_histo', 'dark', UsedThreshold)
- connection (Icon, IconTemp)
- select_shape (IconTemp, Icon, ['area','ratio','column','rectangularity'], 'and', [500,3,0,0.8], [999999,20,ImageWidth*0.95,1])
- sort_region (Icon, IconTemp, 'upper_right', 'false', 'column')
- select_obj(IconTemp, Icon, 1)
- gen_contour_region_xld (Icon, IconTemp, 'border')
- fit_rectangle2_contour_xld (IconTemp, 'regression', -1, 0, 0, 3, 2, Row, Column, Phi, Length1, Length2, PointOrder)
- gen_rectangle2_contour_xld(Rect, Row, Column, Phi, Length1, Length2)
- *提取矩形中心线为上参考线
- get_rectangle2_points (Row, Column, Phi, Length1, Length2, CornerY, CornerX, LineCenterY, LineCenterX)
- if( Phi<=0)
- XValue := LineCenterX[3]
- YValue := LineCenterY[3]
- XValue1:= LineCenterX[1]
- YValue1:= LineCenterY[1]
- else
- XValue := LineCenterX[1]
- YValue := LineCenterY[1]
- XValue1:= LineCenterX[3]
- YValue1:= LineCenterY[3]
- endif
- *处理下白色区
- union1 (IconTemp2, IconTemp)
- smallest_rectangle1 (IconTemp, Row, Column, Row1, Column1)
- *gen_rectangle1 (Rectangle, Row-(Row1-Row)*0.1, Column, Row1+(Row1-Row)*0.1, ImageWidth)
- gen_rectangle1 (Rectangle, Row, Column, Row1, ImageWidth)
- reduce_domain(Image, Rectangle, IconTemp)
- auto_threshold (IconTemp, Icon, 5)
- * binary_threshold (IconTemp, Icon, 'smooth_histo', 'light', UsedThreshold)
- connection (Icon, IconTemp)
- fill_up(IconTemp, IconTemp)
- select_shape (IconTemp, Icon, ['area','ratio','column','rectangularity'], 'and', [500,3,0,0.8], [999999,20,ImageWidth*0.95,1])
- sort_region (Icon, IconTemp, 'upper_right', 'false', 'column')
- select_obj(IconTemp, Icon, 1)
- gen_contour_region_xld (Icon, IconTemp, 'border')
- fit_rectangle2_contour_xld (IconTemp, 'regression', -1, 0, 0, 3, 2, Row, Column, Phi, Length1, Length2, PointOrder)
- gen_rectangle2_contour_xld(Rect1, Row, Column, Phi, Length1, Length2)
- get_rectangle2_points (Row, Column, Phi, Length1, Length2, CornerY, CornerX, LineCenterY, LineCenterX)
- if( Phi<=0)
- XValue2 := LineCenterX[3]
- YValue2 := LineCenterY[3]
- XValue3 := LineCenterX[1]
- YValue3 := LineCenterY[1]
- else
- XValue2 := LineCenterX[1]
- YValue2 := LineCenterY[1]
- XValue3 := LineCenterX[3]
- YValue3 := LineCenterY[3]
- endif
- *下金手指中心线顶点到上金手指中心线的投影。
- projection_pl(YValue2,XValue2,YValue,XValue,YValue1,XValue1,YValue1,XValue1)
- *投影点到下金手指中心线距离
- distance_pl(YValue1,XValue1,YValue2,XValue2,YValue3,XValue3,Distance)
- if(|Distance|==0)
- return()
- endif
- *投影点在下金手指中心线右侧,表示上板要往左移,距离为负,反之则反
- if(XValue1>XValue2)
- Distance := -Distance
- endif
- *显示结果
- gen_contour_polygon_xld(LineXLD,[YValue,YValue1],[XValue,XValue1])
- gen_contour_polygon_xld(LineXLD1,[YValue2,YValue3],[XValue2,XValue3])
- gen_arrow_contour_xld(Arrow, YValue1, XValue1, YValue2, XValue2, 10, 10)
- gen_arrow_contour_xld(Arrow1, YValue2, XValue2, YValue1, XValue1, 10, 10)
- dev_display(Image1)
- dev_set_line_width (2)
- dev_set_draw ('margin')
- dev_set_color('red')
- dev_display(Rect)
- dev_display(Rect1)
- dev_set_color('magenta')
- dev_display(LineXLD)
- dev_display(LineXLD1)
- dev_set_color('green')
- dev_display(Arrow)
- dev_display(Arrow1)
- message := Distance
- .3f'+'Pix'
- get_string_extents(WindowHandle, message, Ascent, Descent, Width, Height)
- dev_disp_text(message, 'image', YValue1-Height*2, XValue1, 'green', ['box'], ['false'])
复制代码- dev_close_window ()
- read_image (Image1, '1.bmp')
- dev_open_window_fit_image (Image1, 0, 0, -1, -1, WindowHandle)
- dev_display (Image1)
- get_image_size (Image1, ImageWidth, ImageHeight)
- rgb1_to_gray (Image1, Image)
- binary_threshold (Image, IconTemp, 'max_separability', 'light', UsedThreshold)
- connection (IconTemp, Icon)
- *筛选全部白色区域
- select_shape (Icon, IconTemp, ['area','ratio','column'], 'and', [2000,3,0], [999999,20,ImageWidth*0.95])
- *筛选上,下白色区
- select_shape(IconTemp, Icon, 'row1', 'and', 0, 100)
- difference (IconTemp, Icon, IconTemp2)
- *处理上白色
- union1 (Icon, IconTemp)
- smallest_rectangle1 (IconTemp, Row, Column, Row1, Column1)
- gen_rectangle1 (Rectangle, Row, Column, Row1/2, ImageWidth)
- reduce_domain(Image, Rectangle, IconTemp)
- binary_threshold (IconTemp, Icon, 'smooth_histo', 'dark', UsedThreshold)
- connection (Icon, IconTemp)
- select_shape (IconTemp, Icon, ['area','ratio','column','rectangularity'], 'and', [500,3,0,0.8], [999999,20,ImageWidth*0.95,1])
- sort_region (Icon, IconTemp, 'upper_right', 'false', 'column')
- select_obj(IconTemp, Icon, 1)
- gen_contour_region_xld (Icon, IconTemp, 'border')
- fit_rectangle2_contour_xld (IconTemp, 'regression', -1, 0, 0, 3, 2, Row, Column, Phi, Length1, Length2, PointOrder)
- gen_rectangle2_contour_xld(Rect, Row, Column, Phi, Length1, Length2)
- *提取矩形中心线为上参考线
- get_rectangle2_points (Row, Column, Phi, Length1, Length2, CornerY, CornerX, LineCenterY, LineCenterX)
- if( Phi<=0)
- XValue := LineCenterX[3]
- YValue := LineCenterY[3]
- XValue1:= LineCenterX[1]
- YValue1:= LineCenterY[1]
- else
- XValue := LineCenterX[1]
- YValue := LineCenterY[1]
- XValue1:= LineCenterX[3]
- YValue1:= LineCenterY[3]
- endif
- *处理下白色区
- union1 (IconTemp2, IconTemp)
- smallest_rectangle1 (IconTemp, Row, Column, Row1, Column1)
- *gen_rectangle1 (Rectangle, Row-(Row1-Row)*0.1, Column, Row1+(Row1-Row)*0.1, ImageWidth)
- gen_rectangle1 (Rectangle, Row, Column, Row1, ImageWidth)
- reduce_domain(Image, Rectangle, IconTemp)
- auto_threshold (IconTemp, Icon, 5)
- * binary_threshold (IconTemp, Icon, 'smooth_histo', 'light', UsedThreshold)
- connection (Icon, IconTemp)
- fill_up(IconTemp, IconTemp)
- select_shape (IconTemp, Icon, ['area','ratio','column','rectangularity'], 'and', [500,3,0,0.8], [999999,20,ImageWidth*0.95,1])
- sort_region (Icon, IconTemp, 'upper_right', 'false', 'column')
- select_obj(IconTemp, Icon, 1)
- gen_contour_region_xld (Icon, IconTemp, 'border')
- fit_rectangle2_contour_xld (IconTemp, 'regression', -1, 0, 0, 3, 2, Row, Column, Phi, Length1, Length2, PointOrder)
- gen_rectangle2_contour_xld(Rect1, Row, Column, Phi, Length1, Length2)
- get_rectangle2_points (Row, Column, Phi, Length1, Length2, CornerY, CornerX, LineCenterY, LineCenterX)
- if( Phi<=0)
- XValue2 := LineCenterX[3]
- YValue2 := LineCenterY[3]
- XValue3 := LineCenterX[1]
- YValue3 := LineCenterY[1]
- else
- XValue2 := LineCenterX[1]
- YValue2 := LineCenterY[1]
- XValue3 := LineCenterX[3]
- YValue3 := LineCenterY[3]
- endif
- *下金手指中心线顶点到上金手指中心线的投影。
- projection_pl(YValue2,XValue2,YValue,XValue,YValue1,XValue1,YValue1,XValue1)
- *投影点到下金手指中心线距离
- distance_pl(YValue1,XValue1,YValue2,XValue2,YValue3,XValue3,Distance)
- if(|Distance|==0)
- return()
- endif
- *投影点在下金手指中心线右侧,表示上板要往左移,距离为负,反之则反
- if(XValue1>XValue2)
- Distance := -Distance
- endif
- *显示结果
- gen_contour_polygon_xld(LineXLD,[YValue,YValue1],[XValue,XValue1])
- gen_contour_polygon_xld(LineXLD1,[YValue2,YValue3],[XValue2,XValue3])
- gen_arrow_contour_xld(Arrow, YValue1, XValue1, YValue2, XValue2, 10, 10)
- gen_arrow_contour_xld(Arrow1, YValue2, XValue2, YValue1, XValue1, 10, 10)
- dev_display(Image1)
- dev_set_line_width (2)
- dev_set_draw ('margin')
- dev_set_color('red')
- dev_display(Rect)
- dev_display(Rect1)
- dev_set_color('magenta')
- dev_display(LineXLD)
- dev_display(LineXLD1)
- dev_set_color('green')
- dev_display(Arrow)
- dev_display(Arrow1)
- message := Distance
- .2f'+'pix'
- get_string_extents(WindowHandle, message, Ascent, Descent, Width1, Height1)
- dev_disp_text(message, 'image', YValue2-Height1*2, XValue2, 'green', ['box'], ['false'])
复制代码
.3f'+'Pix'
get_string_extents(WindowHandle, message, Ascent, Descent, Width, Height)
dev_disp_text(message, 'image', YValue1-Height*2, XValue1, 'green', ['box'], ['false'])
[/code][ DISCUZ_CODE_25 ]
.2f'+'pix'
get_string_extents(WindowHandle, message, Ascent, Descent, Width1, Height1)
dev_disp_text(message, 'image', YValue2-Height1*2, XValue2, 'green', ['box'], ['false'])
[/code]
.2f'+'pix'
get_string_extents(WindowHandle, message, Ascent, Descent, Width1, Height1)
dev_disp_text(message, 'image', YValue2-Height1*2, XValue2, 'green', ['box'], ['false'])
[/code]
.3f'+'Pix'
get_string_extents(WindowHandle, message, Ascent, Descent, Width, Height)
dev_disp_text(message, 'image', YValue1-Height*2, XValue1, 'green', ['box'], ['false'])
[/code][ DISCUZ_CODE_25 ]
|