设置首页收藏本站
开启左侧

端子宽度测量

[复制链接]
hanfang 发表于 2025-8-8 20:32:24 | 显示全部楼层 |阅读模式
求助各位大佬,有没有相对简单的办法测量一下端子的最宽距离(如图我画红线的宽度)另外一边不一定是直线,部分端子存在胶水所以精度不是很高,上料的角度不固定会旋转,后面的几张图片,哪位大佬能提供一下解决思路,谢谢!
捕获.PNG
6.png
5.png
4.png
3.png
奖励计划已经开启,本站鼓励作者发布最擅长的技术内容和资源,流量变现就在现在,[点我]加入吧~~~Go
大凡光学,专注标定板提供
雾里看花 发表于 2025-8-9 08:02:15 | 显示全部楼层
最小外接矩形,矩形宽度就是你 要的东西啦
奖励计划已经开启,本站鼓励作者发布最擅长的技术内容和资源,流量变现就在现在,[点我]加入吧~~~Go
小马哥 发表于 2025-8-9 08:52:41 | 显示全部楼层
这么考虑下:
1、直接阈值分割找到整个端子区域 ※因为上料角度随机,所以考虑BLOB
2、开运算去掉小尾巴
3、找剩下区域的最小外接旋转矩形,取小边长
奖励计划已经开启,本站鼓励作者发布最擅长的技术内容和资源,流量变现就在现在,[点我]加入吧~~~Go
回复 支持 1 反对 0

使用道具 举报

UKimiF 发表于 2025-8-9 16:57:12 | 显示全部楼层
  1. read_image (Image, './1.png')
  2. *//获得区域
  3. decompose3 (Image, R, G, B)
  4. threshold (G, RegionO, 123, 255)
  5. fill_up (RegionO, RegionO)
  6. opening_circle (RegionO, RegionO, 10.5)

  7. *//Mode1:1代表思路一,2代表思路2
  8. Mode1:=2
  9. if(Mode1==1)
  10.     *//思路一
  11.     *//获得基准角度
  12.     smallest_rectangle2 (RegionO, Row, Column, Phi, Length1, Length2)
  13.     *//仿射变换
  14.     hom_mat2d_identity (HomMat2D)
  15.     hom_mat2d_rotate (HomMat2D, -Phi-rad(90), Row, Column, HomMat2DR)
  16.     hom_mat2d_identity (HomMat2DI)
  17.     hom_mat2d_rotate (HomMat2DI, Phi+rad(90), Row, Column, HomMat2DRI)
  18.     affine_trans_region (RegionO, RegionOAF, HomMat2DR, 'nearest_neighbor')
  19.     *//Mode2获得转正后的区域每行的起点和终点的两种方法
  20.     *//个人推荐第二种,用纯形态学计算边缘性能会高很多
  21.     Mode2:=1
  22.     if(Mode2==1)
  23.         *1.使用Halcon自带的算子实现
  24.         get_region_runs (RegionOAF, Row1, ColB, ColE)
  25.     elseif(Mode2==2)
  26.         *2.使用自定义算子实现
  27.         *//get_region_ud_edge:目的:获取区域指定方向的边缘,输入区域,输出指定方向的边缘点
  28.         get_region_ud_edge (RegionOAF, 'Left', Row1, ColB)
  29.         get_region_ud_edge (RegionOAF, 'Right', Row1, ColE)
  30.     endif
  31.     *//获得每行的宽度并找到最大的值和对应的下标
  32.     tuple_sub (ColE, ColB, Width)
  33.     tuple_max (Width, WidthMax)
  34.     tuple_find_first (Width, WidthMax, WidthMaxIdx)
  35.     gen_arrow_contour_xld (ArrowS, Row1[WidthMaxIdx], ColB[WidthMaxIdx], Row1[WidthMaxIdx], ColE[WidthMaxIdx], 5, 5)
  36.     affine_trans_contour_xld (ArrowS, ContS, HomMat2DRI)
  37. elseif(Mode1==2)
  38.     *//思路二
  39.     *//这一步直接就得到结果了,下面的步骤都是用于可视化的
  40.     smallest_rectangle2 (RegionO, Row, Column, Phi, Length1, WidthMax)
  41.     *//get_rect2_vertex:目的:获得旋转矩形的四个拐点,输入旋转矩形的五个参数
  42.     get_rect2_vertex (Row, Column, Phi, Length1-1, WidthMax-1,\
  43.                       RowTL, ColTL, RowTR, ColTR, RowBL, ColBL, RowBR, ColBR)
  44.     distance_pp (RowTL, ColTL, RowTR, ColTR, Dis1)
  45.     distance_pp (RowTL, ColTL, RowBL, ColBL, Dis2)
  46.     if(Dis1>=Dis2)
  47.         *//上下边缘为长边
  48.         gen_contour_polygon_xld (ContL1, [RowTL,RowTR], [ColTL,ColTR])
  49.         gen_contour_polygon_xld (ContL2, [RowBL,RowBR], [ColBL,ColBR])
  50.         concat_obj (ContL1, ContL2, ContS)
  51.         gen_arrow_contour_xld (ArrowS1, (RowTL+RowTR)/2, (ColTL+ColTR)/2, (RowBL+RowBR)/2, (ColBL+ColBR)/2, 5, 5)
  52.         gen_arrow_contour_xld (ArrowS2, (RowBL+RowBR)/2, (ColBL+ColBR)/2, (RowTL+RowTR)/2, (ColTL+ColTR)/2, 5, 5)
  53.         concat_obj (ArrowS1, ArrowS2, ArrowS)
  54.     else
  55.         *//左右边缘为长边
  56.         gen_contour_polygon_xld (ContL1, [RowTL,RowBL], [ColTL,ColBL])
  57.         gen_contour_polygon_xld (ContL2, [RowTR,RowBR], [ColTR,ColBR])
  58.         concat_obj (ContL1, ContL2, ContS)
  59.         gen_arrow_contour_xld (ArrowS1, (RowTL+RowBL)/2, (ColTL+ColBL)/2, (RowTR+RowBR)/2, (ColTR+ColBR)/2, 5, 5)
  60.         gen_arrow_contour_xld (ArrowS2, (RowTR+RowBR)/2, (ColTR+ColBR)/2, (RowTL+RowBL)/2, (ColTL+ColBL)/2, 5, 5)
  61.         concat_obj (ArrowS1, ArrowS2, ArrowS)
  62.     endif
  63.     concat_obj (ArrowS, ContS, ContS)
  64.     WidthMax:=WidthMax*2
  65. endif

  66. *//可视化
  67. dev_clear_window ()
  68. dev_display (Image)
  69. dev_set_color ('red')
  70. dev_display (ContS)
  71. disp_message (200000, 'MaxWidth: '+WidthMax+' pix', 'window', 10, 10, 'green', 'false')
复制代码

效果1.png
效果2.png
奖励计划已经开启,本站鼓励作者发布最擅长的技术内容和资源,流量变现就在现在,[点我]加入吧~~~Go
回复 支持 1 反对 0

使用道具 举报

UKimiF 发表于 2025-8-9 16:59:01 | 显示全部楼层
其中get_region_ud_edge算子是我自己封装的算子,作用是获得区域的指定方向的所有边缘点,内容如下:
  1. set_system ('clip_region', 'false')
  2. smallest_rectangle1 (Region, Row1, Column1, Row2, Column2)
  3. if(Direction=='Up')
  4.     gen_region_line (RegionL, Row2, Column1+1, Row2, Column2-1)
  5. elseif(Direction=='Down')
  6.     gen_region_line (RegionL, Row1, Column1+1, Row1, Column2-1)
  7. elseif(Direction=='Left')
  8.     gen_region_line (RegionL, Row1+1, Column2, Row2-1, Column2)
  9. elseif(Direction=='Right')
  10.     gen_region_line (RegionL, Row1+1, Column1, Row2-1, Column1)
  11. endif

  12. union2 (Region, RegionL, Region)
  13. if(Direction=='Up' or Direction=='Down')
  14.     closing_rectangle1 (Region, Region, 1, (Row2-Row1))
  15. else
  16.     closing_rectangle1 (Region, Region, (Column2-Column1), 1)
  17. endif

  18. if(Direction=='Up')
  19.     move_region (Region, RegionM, 1, 0)
  20. elseif(Direction=='Down')
  21.     move_region (Region, RegionM, -1, 0)
  22. elseif(Direction=='Left')
  23.     move_region (Region, RegionM, 0, 1)
  24. elseif(Direction=='Right')
  25.     move_region (Region, RegionM, 0, -1)
  26. endif

  27. difference (Region, RegionM, Region)
  28. get_region_points (Region, Rows_Res, Cols_Res)

  29. if(Direction=='Up' or Direction=='Down')
  30.     tuple_sort_index (Cols_Res, Cols_ResIndices)
  31.     tuple_sort (Cols_Res, Cols_Res)
  32.     tuple_select (Rows_Res, Cols_ResIndices, Rows_Res)
  33. else
  34.     tuple_sort_index (Rows_Res, Rows_ResIndices)
  35.     tuple_sort (Rows_Res, Rows_Res)
  36.     tuple_select (Cols_Res, Rows_ResIndices, Cols_Res)
  37. endif

  38. if(Direction=='Up')
  39.     Rows_Res:=Rows_Res-0.5
  40. elseif(Direction=='Down')
  41.     Rows_Res:=Rows_Res+0.5
  42. elseif(Direction=='Left')
  43.     Cols_Res:=Cols_Res-0.5
  44. elseif(Direction=='Right')
  45.     Cols_Res:=Cols_Res+0.5
  46. endif
  47. return ()
复制代码

另外get_rect2_vertex也是我自己封装的算子,作用是获得旋转矩形的四个拐点,内容如下:
  1. gen_rectangle2 (Rectangle, Row, Column, Phi, Length1, Length2)
  2. smallest_rectangle2 (Rectangle, Row, Column, Phi, Length1, Length2)
  3. if(abs(deg(Phi))>45)
  4.     Phi:=rad(deg(Phi)-90*(Phi/abs(Phi)))
  5.     Tmp:=Length1
  6.     Length1:=Length2
  7.     Length2:=Tmp
  8. endif

  9. tuple_sin (Phi, Sin)
  10. tuple_cos (Phi, Cos)

  11. *左上角
  12. TopLeft_X := -Length1*Cos - Length2*Sin
  13. TopLeft_Y := -Length1*Sin + Length2*Cos
  14. RowTL := Row - TopLeft_Y
  15. ColTL := Column + TopLeft_X

  16. *右上角
  17. TopRight_X := Length1*Cos - Length2*Sin
  18. TopRight_Y := Length1*Sin + Length2*Cos
  19. RowTR := Row - TopRight_Y
  20. ColTR := Column + TopRight_X

  21. *右下角
  22. LowerRight_X := Length1*Cos + Length2*Sin
  23. LowerRight_Y := Length1*Sin - Length2*Cos
  24. RowBR := Row - LowerRight_Y
  25. ColBR := Column + LowerRight_X

  26. *左下角
  27. LowerLeft_X := -Length1*Cos + Length2*Sin
  28. LowerLeft_Y := -Length1*Sin - Length2*Cos
  29. RowBL := Row - LowerLeft_Y
  30. ColBL := Column + LowerLeft_X
  31. return ()
复制代码
奖励计划已经开启,本站鼓励作者发布最擅长的技术内容和资源,流量变现就在现在,[点我]加入吧~~~Go
回复 支持 1 反对 0

使用道具 举报

luhu326 发表于 2025-8-13 15:55:42 | 显示全部楼层
大佬牛批
奖励计划已经开启,本站鼓励作者发布最擅长的技术内容和资源,流量变现就在现在,[点我]加入吧~~~Go
Zcy1023 发表于 2025-8-13 16:11:55 | 显示全部楼层
感谢分享
奖励计划已经开启,本站鼓励作者发布最擅长的技术内容和资源,流量变现就在现在,[点我]加入吧~~~Go
 楼主| hanfang 发表于 2025-8-18 09:39:23 | 显示全部楼层
UKimiF 发表于 2025-8-9 16:59
其中get_region_ud_edge算子是我自己封装的算子,作用是获得区域的指定方向的所有边缘点,内容如下:

另外 ...

感谢大佬的指导
奖励计划已经开启,本站鼓励作者发布最擅长的技术内容和资源,流量变现就在现在,[点我]加入吧~~~Go
xah 发表于 2025-9-1 10:57:38 | 显示全部楼层
牛牛牛
奖励计划已经开启,本站鼓励作者发布最擅长的技术内容和资源,流量变现就在现在,[点我]加入吧~~~Go
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表