halcon使用measure_pos检测直线(使用检测规则)

        函数使用measure_pos检测边缘点,里面加了计算距离的筛选规则,用规则去挑出更符合需要的点位。

函数原理:

        1、使用灰度投影求出可能是边缘的几根线,再使用参数自己选择需要哪条边。这条边作为边缘的参考边。

        2、使用measure_pos求出边缘的所有点位,计算点位于参考边的距离,判断这个距离是否满足参数要求,不满足的直接剔除。将剩下的点位生成我们需要的直线。

函数封装: 

 

Rows := []
Columns := []
LineParam := []
gen_empty_obj (OutContour)
try
    *RecRow, RecColumn, RecPhi, RecLength1, RecLength2:直线ROI区域rectagnle2参数
    *Transition 卡尺朝向;SmoothSigma 平滑系数;Threshold 边缘梯度;
    *LineIndex 边缘索引,0-第一条边,-1-最后一条边;RecHeight-测量矩形高度;RecWidth-测量矩形宽度
    
    ******第一步,用两个一维测量算子,求出直线两点,并得到直线方位角
    smallest_rectangle2 (FindRectangle, RecRow, RecColumn, RecPhi, RecLength1, RecLength2)
    smallest_rectangle1(FindRectangle, Row11, Column11, Row22, Column22)
    reduce_domain (ImageEnhanced, FindRectangle, ImageReduced)
    crop_domain (ImageReduced, ImagePart)
    ********
    if(RecPhi>-rad(45))
        Angle:=RecPhi-rad(90)
    else
        Angle:=RecPhi+rad(90)
    endif
    ***************第二步,根据直线角度,生成测量矩形,灰度投影,得到边缘位置集合
    get_image_size(ImagePart, Width, Height)
    gen_rectangle2(Rectangle3,Height/2, Width/2,Angle, RecLength2-5, RecLength1-5)
    gen_contour_polygon_xld(Contour, [Height/2-RecLength1*sin(RecPhi),Height/2+RecLength1*sin(RecPhi)], [Width/2+RecLength1*cos(RecPhi),Width/2-RecLength1*cos(RecPhi)])
    *
    gen_measure_rectangle2( Height/2, Width/2,Angle, RecLength2-5, RecLength1-5, Width, Height, 'nearest_neighbor', MeasureHandle2)
    measure_projection(ImagePart, MeasureHandle2, GrayValues)
    create_funct_1d_array(GrayValues, Function)
    smooth_funct_1d_gauss (Function, SmoothSigma, SmoothedFunction)
    derivate_funct_1d(SmoothedFunction, 'first', Derivative)
    local_min_max_funct_1d(Derivative, 'strict_min_max', 'false', Min, Max)
    funct_1d_to_pairs(Derivative, XValues, YValues)
    *
    minIndex:=[]
    for Index := 0 to |Min|-1 by 1
        if (YValues[Min[Index]]<-Threshold)
            minIndex:=[minIndex,Min[Index]]
        endif
    endfor
    *
    maxIndex:=[]
    for Index := 0 to |Max|-1 by 1
        if (YValues[Max[Index]]>Threshold)
            maxIndex:=[maxIndex,Max[Index]]
        endif
    endfor
    ****
    *
    if (|maxIndex|=0 and Transition == 'positive')
        return()
    endif
    *
    if (|minIndex|=0 and Transition == 'negative')
        return()
    endif
    ***************第三步,根据参数配置筛选出参考边缘轮廓
    lineIndex:=-9999
    if (Transition == 'positive')
        if (LineIndex>=0 and |maxIndex|> LineIndex)
            lineIndex := maxIndex[LineIndex]
        elseif(|maxIndex|>= abs(LineIndex))
            lineIndex := maxIndex[|maxIndex|+LineIndex]
        endif
    else
        if (LineIndex>=0 and |minIndex|> LineIndex)
            lineIndex := minIndex[LineIndex]
        elseif(|minIndex|>= abs(LineIndex))
            lineIndex := minIndex[|minIndex|+LineIndex]
        endif
    endif
    if(lineIndex=-9999)
        return()
    endif
    *得到参考边缘,将矩形中线平移至参考边缘位置
    if(RecPhi>=-rad(45))
        gen_parallel_contour_xld(Contour, LineContour1, 'regression_normal', -lineIndex+(RecLength2-5))
    else
        gen_parallel_contour_xld(Contour, LineContour1, 'regression_normal', lineIndex-(RecLength2-5))
    endif
    
    get_contour_xld(LineContour1, Row1, Col1)
    Row1:=Row1+Row11
    Col1:=Col1+Column11
    ****************第四步,根据参考边缘,筛选实际边缘点
    gen_contour_polygon_xld(LineContour, Row1, Col1)
    *
    tuple_mean(Row1,RCenter)
    tuple_mean(Col1,CCenter)
    *
    gen_empty_obj(Crosses)
    rows:=[]
    cols:=[]
    *一维卡尺测量点位
    get_image_size(Image, Width, Height)
    RecHeight := RecLength2
    RecWidth := NumDistance
    
    for i := -RecLength1+RecWidth to RecLength1-RecWidth by RecWidth
        row:=RCenter-i*sin(RecPhi)
        col:=CCenter+i*cos(RecPhi)
        gen_rectangle2 (Rectangle1, row, col, Angle, RecHeight, RecWidth)
        gen_measure_rectangle2 (row, col, Angle, RecHeight, RecWidth, Width, Height, 'nearest_neighbor', MeasureHandle)
        if (Transition == 'positive')
            measure_pos(Image, MeasureHandle, 1, 5, 'positive', 'all', RowEdge, ColumnEdge, Amplitude, Distance)
        else
            measure_pos(Image, MeasureHandle, 1, 5, 'negative', 'all', RowEdge, ColumnEdge, Amplitude, Distance) 
        endif
        gen_cross_contour_xld (Cross, RowEdge, ColumnEdge, 30, 0.785398)
        ***
        if (|RowEdge|=0)
            continue
        else
            d := 9999           
            for k := 0 to |RowEdge|-1 by 1
                distance_pc (LineContour, RowEdge[k], ColumnEdge[k], DistanceMin, DistanceMax)
                if (DistanceMin<d)         //循环将每次的最小距离作为判断,逐渐提高判断要求
                    d := DistanceMin         
                    if (d<MinDistance)
                        row := RowEdge[k]
                        col := ColumnEdge[k]
                    endif
                endif
                
            endfor
            if (row!=0)
                gen_cross_contour_xld (Cross, row, col, 10, 0.785398)
                Rows := [Rows,row]
                Columns := [Columns,col]
                concat_obj (Crosses, Cross, Crosses)
            endif
        endif
    endfor
    if(|Rows|<2)
        throw ([201005,''])
    endif
    *得到点位,拟合直线
    gen_contour_polygon_xld (Contour, Rows, Columns)   
    fit_line_contour_xld (Contour,  'tukey', -1, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist)
    LineParam:=[RowBegin, ColBegin, RowEnd, ColEnd]
    gen_contour_polygon_xld(Line, [RowBegin,RowEnd], [ColBegin,ColEnd])
    
    *测量轮廓
    concat_obj (OutContour, Rectangle1, OutContour)
    concat_obj (OutContour, Crosses, OutContour)
catch (Exception)
endtry

return ()

        这个函数稍微有一点绕,还是需要看代码跑一下,这个能加深理解。 

 

### Halcon 卡尺工具直线检测使用方法及参数设置 #### 设置环境与加载图像 为了确保能够准确地执行卡尺测量,在开始之前需准备好工作环境。这通常涉及读取待分析的图像文件,此过程可通过`read_image`函数完成[^1]。 ```cpp read_image (Image, 'path_to_your_image') ``` #### 图像预处理 对于精确的边缘定位而言,良好的图像预处理至关重要。这里包含了诸如二值化(阈值分割)、形态学操作以及亚像素精度下的边缘提取等一系列步骤,这些都有助于提高后续测量准确性。 ```cpp threshold (Image, Region, MinGray, MaxGray) edges_sub_pix (Region, Edges, 'canny', Parameters) ``` #### 定义测量区域 利用`gen_measure_rectangle2`来创建一个用于指导测量活动的矩形框。该命令允许指定矩形中心点、宽度、高度及其相对于水平轴的角度偏移量,以此界定出具体的搜索区间和方向。 ```cpp gen_measure_rectangle2 (Row, Column, Phi, Length1, Length2, Width, Height, MeasureHandle) ``` - `Row`, `Column`: 矩形中心坐标。 - `Phi`: 矩形旋转角度。 - `Length1`, `Length2`: 平行边长度。 - `Width`, `Height`: 垂直边尺寸。 #### 执行测量 一旦完成了上述准备工作,则可以调用`measure_pos`来进行实际的数据采集。它会基于先前配置好的条件寻找目标特征,并返回有关位置的信息连同两平行边界间的间距数据一同给出。 ```cpp measure_pos (Edges, MeasureHandle, Transition, Sigma, AmpThresh, FuzzyThresh, Interpolation, RowEdgeFirst, ColumnEdgeFirst, RowEdgeLast, ColumnEdgeLast, EdgeAmplitudeFirst, EdgeAmplitudeLast, Distance) ``` #### 获取更详细的测量结果 如果希望进一步了解所选区域内各要素的具体情况,还可以借助其他功能强大的API接口如`get_metrology_object_measures`或`apply_metrology_model`等,它们能提供更加全面详尽的结果描述[^2][^4]。 ```cpp // 适用于复杂场景下多对象的同时评估 apply_metrology_model(Image, MetrologyHandle) // 或者单独查询某个特定部分的情况 get_metrology_object_measures(MeasureContours, MetrologyHandle, 'all', 'all', Row, Column) ``` #### 结果展示与清理 最后一步便是呈现最终成果——即显示测得的关键点位图样并打印相应的数值;与此同时记得适时回收不再使用的资源以维持系统的高效运作状态。 ```cpp dev_display(Edges) disp_message(WindowHandle, "Distance between edges: "+ Distance, 'window', Row, Column, Color, []) close_measure(MeasureHandle) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值