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 ()

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

 

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值