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

求助,旋转网格到标准方向,使所有菱形呈水平/垂直对齐

[复制链接]
zczc123 发表于 2025-9-5 17:06:26 | 显示全部楼层 |阅读模式
我想将图像中的网格调正,我自己针对其中一块菱形求最小外接矩阵来判断方向,但效果不是很理想。请教下大佬们有什么好方法。
5.png

奖励计划已经开启,本站鼓励作者发布最擅长的技术内容和资源,流量变现就在现在,[点我]加入吧~~~Go
大凡光学,专注标定板提供
gaoan3210 发表于 2025-9-6 09:43:17 | 显示全部楼层

我把直线拟合了 算一算 直线 与直线之间的交点 用交点花小菱形 之后在计算各自的ju'l

本帖最后由 gaoan3210 于 2025-9-6 09:45 编辑
  1. dev_get_window (WindowHandle)
  2. read_image (Image, '1.png')
  3. * edges_sub_pix (Image1, Edges, 'canny', 1, 20, 40)
  4. * segment_contour_attrib_xld (Edges, ContourPart, 'edge_direction', 'and', rad(0), rad(180))
  5. binary_threshold (Image, Region, 'max_separability', 'dark', UsedThreshold)
  6. opening_circle (Region, RegionOpening, 10)
  7. difference ( Region, RegionOpening,RegionDifference)
  8. connection (RegionDifference, ConnectedRegions)
  9. select_shape (ConnectedRegions, SelectedRegions, 'area', 'and',40000, 99999)
  10. skeleton (SelectedRegions, Skeleton)
  11. dev_clear_window ()
  12. gen_contour_region_xld (Skeleton, Contours, 'border_holes')
  13. segment_contours_xld (Contours, ContoursSplit, 'lines', 5,4, 2)
  14. dev_clear_window ()
  15. select_shape_xld (ContoursSplit, SelectedXLD, 'area', 'and', 10,50)
  16. union_collinear_contours_xld (ContoursSplit, UnionContours, 10, 0.8, 4, 0.3, 'attr_keep')



  17. gen_empty_obj (linses)
  18. dev_display (Image)
  19. dev_clear_window ()
  20. fit_line_contour_xld (UnionContours, 'tukey', -1, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist)
  21. for i := 0 to |RowBegin| - 1 by 1
  22.     gen_contour_polygon_xld (Contour, [RowBegin[i],RowEnd[i]], [ColBegin[i],ColEnd[i]])
  23.     concat_obj (linses, Contour, linses)
  24.     dev_display (Contour)
  25. endfor

  26. dev_display (Image)
  27. dev_display (linses)



复制代码
33.png
奖励计划已经开启,本站鼓励作者发布最擅长的技术内容和资源,流量变现就在现在,[点我]加入吧~~~Go
UKimiF 发表于 2025-9-6 10:09:15 | 显示全部楼层
本质也是抓直线拟合然后计算角度,很简单的需求,代码如下:
  1. read_image (Image, './1.png')
  2. rgb1_to_gray (Image, Image)
  3. set_system ('clip_region', 'false')

  4. *//提取最大的基准区域
  5. threshold (Image, RegionA, 0, 198)
  6. connection (RegionA, RegionA)
  7. select_shape_std (RegionA, RegionA, 'max_area', 70)

  8. *//形态学获得角度计算的基准区域
  9. opening_circle (RegionA, RegionB, 10.5)
  10. connection (RegionB, RegionB)
  11. sort_region (RegionB, RegionB, 'first_point', 'true', 'column')
  12. select_obj (RegionB, RegionB1, 1)
  13. select_obj (RegionB, RegionB2, 2)

  14. *//获得基准点集
  15. get_region_ud_edge (RegionB1, 'Right', RowsB1, ColsB1)
  16. get_region_ud_edge (RegionB2, 'Left', RowsB2, ColsB2)

  17. *//拟合直线
  18. gen_contour_polygon_xld (ContLB1, RowsB1, ColsB1)
  19. fit_line_contour_xld (ContLB1, 'tukey', -1, 0, 5, 2, RowB1, ColB1, RowE1, ColE1, Nr, Nc, Dist)
  20. gen_arrow_contour_xld (ArrowB1, RowB1, ColB1, RowE1, ColE1, 5, 5)
  21. gen_contour_polygon_xld (ContLB2, RowsB2, ColsB2)
  22. fit_line_contour_xld (ContLB2, 'tukey', -1, 0, 5, 2, RowB2, ColB2, RowE2, ColE2, Nr, Nc, Dist)
  23. gen_arrow_contour_xld (ArrowB2, RowB2, ColB2, RowE2, ColE2, 5, 5)

  24. *//计算中线
  25. RowBM:=(RowB1+RowB2)/2
  26. ColBM:=(ColB1+ColB2)/2
  27. RowEM:=(RowE1+RowE2)/2
  28. ColEM:=(ColE1+ColE2)/2
  29. gen_arrow_contour_xld (ArrowBM, RowBM, ColBM, RowEM, ColEM, 5, 5)
  30. *//计算仿射变换
  31. RowC:=(RowBM+RowEM)/2
  32. ColC:=(ColBM+ColEM)/2
  33. angle_lx (RowBM, ColBM, RowEM, ColEM, AngleB)
  34. hom_mat2d_identity (HomMat2DI)
  35. hom_mat2d_rotate (HomMat2DI, -AngleB+rad(90), RowC, ColC, HomMat2DR)
  36. affine_trans_image (Image, ImageAF, HomMat2DR, 'constant', 'false')


复制代码


其中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 ()
复制代码
效果1.png
效果2.png
奖励计划已经开启,本站鼓励作者发布最擅长的技术内容和资源,流量变现就在现在,[点我]加入吧~~~Go
小马哥 发表于 2025-9-6 17:07:47 | 显示全部楼层
一个字,绝
奖励计划已经开启,本站鼓励作者发布最擅长的技术内容和资源,流量变现就在现在,[点我]加入吧~~~Go
xah 发表于 2025-9-8 10:05:05 | 显示全部楼层
牛牛牛牛啊
奖励计划已经开启,本站鼓励作者发布最擅长的技术内容和资源,流量变现就在现在,[点我]加入吧~~~Go
 楼主| zczc123 发表于 2025-9-8 13:48:38 | 显示全部楼层
UKimiF 发表于 2025-9-6 10:09
本质也是抓直线拟合然后计算角度,很简单的需求,代码如下:

大佬谢谢,我研究了下,您的计算获得基准点集是以左右两块黑色区域为输入,拟合的线也是黑色区域的边线。但对于以下图片,黑色区域方向不变,只是银网方向改变,使用您的方法效果不是很好,我想再请教下对于这种有什么方法,谢谢。
2.jpg
奖励计划已经开启,本站鼓励作者发布最擅长的技术内容和资源,流量变现就在现在,[点我]加入吧~~~Go
 楼主| zczc123 发表于 2025-9-8 16:47:25 | 显示全部楼层

所拟合的直线很多都没有与另一条直线相交,求不出两者的交点,这种情况应该怎么办
奖励计划已经开启,本站鼓励作者发布最擅长的技术内容和资源,流量变现就在现在,[点我]加入吧~~~Go
UKimiF 发表于 2025-9-9 09:09:20 | 显示全部楼层
zczc123 发表于 2025-9-8 13:48
大佬谢谢,我研究了下,您的计算获得基准点集是以左右两块黑色区域为输入,拟合的线也是黑色区域的边线。 ...

也很简单,首先把基准区域从两边换成中间空心的菱形网格,针对空心区域且边缘较细的情况,我们只需要用基准区域跟开运算做差集即可获得,代码如下:
  1. read_image (Image, './2.jpg')
  2. rgb1_to_gray (Image, Image)

  3. *//提取基准区域
  4. threshold (Image, RegionB, 0, 96)
  5. connection (RegionB, RegionB)
  6. select_shape_std (RegionB, RegionB, 'max_area', 70)

  7. *//开运算与原来的区域做差集获得网格区域
  8. opening_circle (RegionB, RegionBO, 10.5)
  9. difference (RegionB, RegionBO, RegionO)
  10. connection (RegionO, RegionO)
  11. select_shape_std (RegionO, RegionO, 'max_area', 70)

  12. *//第一次校正
  13. smallest_rectangle2 (RegionO, RowO, ColO, PhiO, L1O, L2O)
  14. hom_mat2d_identity (HomMat2DI)
  15. hom_mat2d_rotate (HomMat2DI, -PhiO-rad(90), RowO, ColO, HomMat2DR)
  16. affine_trans_region (RegionO, RegionO, HomMat2DR, 'nearest_neighbor')
  17. region_features (RegionO, 'height', H)
  18. closing_rectangle1 (RegionO, RegionO, 1, H)

  19. *//第二次校正
  20. *//左侧
  21. get_region_ud_edge (RegionO, 'Left', RowsL, ColsL)
  22. gen_contour_polygon_xld (ContL, RowsL, ColsL)
  23. fit_line_contour_xld (ContL, 'tukey', -1, 0, 5, 2, RowBL, ColBL, RowEL, ColEL, Nr, Nc, Dist)
  24. gen_arrow_contour_xld (ArrowL, RowBL, ColBL, RowEL, ColEL, 10, 10)
  25. *//右侧
  26. get_region_ud_edge (RegionO, 'Right', RowsR, ColsR)
  27. gen_contour_polygon_xld (ContR, RowsR, ColsR)
  28. fit_line_contour_xld (ContR, 'tukey', -1, 0, 5, 2, RowBR, ColBR, RowER, ColER, Nr, Nc, Dist)
  29. gen_arrow_contour_xld (ArrowR, RowBR, ColBR, RowER, ColER, 10, 10)

  30. *//计算中线并校正
  31. RowBM:=(RowBL+RowBR)/2
  32. ColBM:=(ColBL+ColBR)/2
  33. RowEM:=(RowEL+RowER)/2
  34. ColEM:=(ColEL+ColER)/2
  35. gen_arrow_contour_xld (ArrowM, RowBM, ColBM, RowEM, ColEM, 10, 10)
  36. angle_lx (RowBM, ColBM, RowEM, ColEM, AngleO)
  37. hom_mat2d_identity (HomMat2DI2)
  38. hom_mat2d_rotate (HomMat2DI2, AngleO-rad(90), (RowBM+RowEM)/2, (ColBM+ColEM)/2, HomMat2DR2)
  39. affine_trans_region (RegionO, RegionO, HomMat2DR2, 'nearest_neighbor')

  40. affine_trans_image (Image, ImageAF, HomMat2DR, 'constant', 'false')
  41. affine_trans_image (ImageAF, ImageAF, HomMat2DR2, 'constant', 'false')
  42. *//可视化
  43. dev_clear_window ()
  44. dev_display (ImageAF)
  45. dev_set_draw ('margin')
  46. dev_set_color ('red')
  47. dev_display (RegionO)
  48. dev_set_color ('green')
  49. dev_display (ArrowL)
  50. dev_display (ArrowR)
  51. dev_display (ArrowM)
复制代码
奖励计划已经开启,本站鼓励作者发布最擅长的技术内容和资源,流量变现就在现在,[点我]加入吧~~~Go
UKimiF 发表于 2025-9-9 09:11:02 | 显示全部楼层
另外如果你不需要那么高的角度精度直接到第一次校正就可以了,如果要求的话再做第二次校正,所有操作都是基于形态学的所以算法在性能上不用担心,效果图如下:
效果21.png
效果22.png
奖励计划已经开启,本站鼓励作者发布最擅长的技术内容和资源,流量变现就在现在,[点我]加入吧~~~Go
 楼主| zczc123 发表于 2025-9-9 15:19:52 | 显示全部楼层
UKimiF 发表于 2025-9-9 09:09
也很简单,首先把基准区域从两边换成中间空心的菱形网格,针对空心区域且边缘较细的情况,我们只需要用基 ...

谢谢大佬,看了您的代码学到了很多,感觉我想法没有放开,我已经想到了最小外接矩阵,但没想到求整体的外接矩阵,也没想到用开运算后的图像来作为基准区域。我要学的还有很多,再次谢谢大佬!
奖励计划已经开启,本站鼓励作者发布最擅长的技术内容和资源,流量变现就在现在,[点我]加入吧~~~Go
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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