HALCON测量学习:measure_diamond.hdev

Halcon 钻石检测 案例程序2020.7.21.

*此程序显示了如何以亚像素精度检测钻石的边缘以及如何确定钻石顶点的位置。

*首先,我们使用阈值图像对钻石进行分割,并提取钻石边缘周围的较薄区域 通过使用形态学运算。

*然后,以亚像素精度提取边缘并将其拟合为直线。 随后,通过拟合直线相交来确定钻石底尖的位置。

dev_update_off ()
dev_close_window ()
read_image (Image, 'diamond/diamond_01')
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_set_line_width (2)

NumImages := 5
for Index := 1 to NumImages by 1
    read_image (Image, 'diamond/diamond_' + Index$'.2')
    * 
    * Segment diamond region//分割钻石区域
    threshold (Image, Region, 128, 255) //灰度128~255
    clip_region_rel (Region, RegionClipped, 0, 290, 0, 0) //将输入Region的最小外接矩形区域进行剪切,按照上下左右剪裁,此处向下剪裁290
    shape_trans (RegionClipped, RegionTrans, 'convex') //变换区域的形状,'convex'为凸包,围绕点或形状的紧密拟合的凸边界
    dilation_rectangle1 (RegionTrans, RegionDilation, 5, 1) //使用矩形结构元素对区域进行膨胀,width=5,heigh=1
    erosion_rectangle1 (RegionTrans, RegionErosion, 5, 1) //使用矩形结构元素对区域进行腐蚀
    difference (RegionDilation, RegionErosion, RegionDifference) //膨胀区域-腐蚀区域,注意:大区域减去小区域
    reduce_domain (Image, RegionDifference, ImageReduced) //Image中RegionDifference的那部分图像
    * 
    * Subpixel accurate fitting of the edges //亚像素边缘的精确拟合
    edges_sub_pix (ImageReduced, Edges, 'canny', 3, 5, 5) //亚像素边缘提取
    union_collinear_contours_xld (Edges, UnionContours, 100, 10, 4, rad(10), 'attr_keep') //将近似共线轮廓合并
    select_contours_xld (UnionContours, SelectedContours, 'contour_length', 50, 2000, 0, 0) //选择轮廓长度为50~2000的边界
    fit_line_contour_xld (SelectedContours, 'tukey', -1, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist) //对一些线段的XLD做近似计算直线计算,最小二乘法

    * 
    * Sort the edge contours and determine their intersection
    tuple_sort_index (RowBegin, Indices) //将一组数组进行升序排列,然后将其在原数组的index按升序放入indexs中
    RowBegin := subset(RowBegin,Indices) //选取数组RowBegin中的第Indices个元素
    RowEnd := subset(RowEnd,Indices)
    ColBegin := subset(ColBegin,Indices)
    ColEnd := subset(ColEnd,Indices)
    Nr := subset(Nr,Indices) //法向量的行坐标
    Nc := subset(Nc,Indices) //法向量的列坐标
    Dist := subset(Dist,Indices) //原点到该线的距离
    gen_contour_polygon_xld (LineEdge1, [Dist[0] / Nr[0],0], [0,Dist[0] / Nc[0]]) //不带圆角的多边形轮廓,产生直线
    gen_contour_polygon_xld (LineEdge2, [Dist[1] / Nr[1],Width - 1], [0,(Dist[1] - (Width - 1) * Nr[1]) / Nc[1]]) //产生直线
    intersection_lines (RowBegin[0], ColBegin[0], RowEnd[0], ColEnd[0], RowBegin[1], ColBegin[1], RowEnd[1], ColEnd[1], RowTip, ColTip, IsOverlapping) //计算两线的交点
    gen_cross_contour_xld (Cross, RowTip, ColTip, 20, rad(45)) //生成XLD轮廓,在两线交点画一个十字叉
    * 
    * Display the results //显示结果
    dev_display (Image)
    dev_set_color ('yellow')
    dev_display (LineEdge1)
    dev_display (LineEdge2)
    dev_set_color ('blue')
    dev_display (Cross)
    if (Index != NumImages)
        disp_continue_message (WindowHandle, 'black', 'true')
        stop ()
    endif
endfor


案例算子

fit_line_contour_xld( Contours : : Algorithm, MaxNumPoints, ClippingEndPoints, Iterations, ClippingFactor : RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist ) //对一些线段的XLD做近似计算直线计算

  • 参数Algorithm中的一些类型解释如下:

regression:回归,标准的最小二乘法拟合

huber:加权的最小二乘法拟合,异常值的影响被减小基于Huber方法

tukey:加权的最小二乘法拟合,异常值的影响被减小基于Tukey方法

drop:加权的最小二乘法拟合,异常值的影响被消除

gauss:加权的最小二乘法拟合,异常值的影响被减小基于最逼近线上的所有其轮廓点的平均值和距离标准方差

  • 参数列表:

Contours(in):输入轮廓

Algorithm(in):形成线的算法

MaxNumPoints(in):用于计算的最大轮廓点个数

ClippingEndPoints(in):在逼近过程中被忽略的开始及末尾点个数

Iterations(in):迭代的最大次数

ClippingFactor(in):消除异常值的裁剪因子

RowBegin(out):线段开始点的行坐标

ColBegin(out):线段开始的列坐标

RowEnd(out):线段结尾的行坐标

ColEnd(out):线段结尾的列坐标

Nr(out):线参数:法向量的行坐标

Nc(out):法向量的列坐标

Dist(out):原点到该线的距离


gen_contour_polygon_xld (Line, [RowBegin,RowEnd], [ColBegin,ColEnd])  //不带圆角的多边形轮廓

    源代码的操作,我很迷呀!

    gen_contour_polygon_xld (LineEdge1, [Dist[0] / Nr[0],0], [0,Dist[0] / Nc[0]]) //不带圆角的多边形轮廓,产生直线
    gen_contour_polygon_xld (LineEdge2, [Dist[1] / Nr[1],Width - 1], [0,(Dist[1] - (Width - 1) * Nr[1]) / Nc[1]]) //产生直线

    //画线
    //也可以这样画出直线段 ,但是显示的不太明显,例程中做了一定的调整
    //gen_contour_polygon_xld (LineEdge1, [RowBegin[0],RowEnd[0]], [ColBegin[0],ColEnd[0]])
    //gen_contour_polygon_xld (LineEdge2, [RowBegin[1],RowEnd[1]], [ColBegin[1],ColEnd[1]])
参考博问说的:https://blog.csdn.net/xd940940/article/details/104711747


案例学习总结:

1.提取轮廓:腐蚀区域  减去  膨胀区域  =  边缘区域

2.求物体的尖端:尖端两侧  两个线段  交点

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一些思路,帮助您用 OpenCV 实现类似于 Halcon 中的 gen_measure_rectangle2 和 measure_pos 函数的功能。 gen_measure_rectangle2 函数 gen_measure_rectangle2 函数用于生成测量矩形,其参数为中心点坐标、角度、宽度和高度。在 OpenCV 中,我们可以通过旋转矩形来实现类似的功能。 具体步骤如下: 1. 使用 cv::RotatedRect 构造函数创建一个旋转矩形。传入中心点坐标、宽度和高度参数。 2. 使用 cv::RotatedRect::angle 成员函数设置旋转角度。 3. 使用 cv::boxPoints 成员函数,将旋转矩形转换为矩形的四个顶点。将这些点四舍五入并转换为整数。 4. 使用 cv::fillConvexPoly 函数,将矩形顶点填充到测量矩阵中。 5. 返回测量矩阵。 measure_pos 函数 measure_pos 函数用于计算测量矩形的位置,其参数为测量矩形和偏移量。在 OpenCV 中,我们可以通过图像的平移来实现类似的功能。 具体步骤如下: 1. 创建一个空的位置矩阵,使用 cv::Mat::zeros 函数,传入图像高度和宽度参数。 2. 计算测量矩形的中心点坐标。 3. 计算位置矩阵的左上角坐标,使用中心点坐标和偏移量计算。 4. 创建一个平移矩阵,使用 cv::Mat::eye 函数。设置第三列为偏移量的 x 和 y 值。 5. 使用 cv::warpAffine 函数,将测量矩形从原始图像中复制到位置矩阵中。传入平移矩阵作为变换参数。 6. 返回位置矩阵。 希望这些步骤可以帮助您实现类似于 Halcon 中 gen_measure_rectangle2 和 measure_pos 函数的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值