halcon找矩形顶点的一种方法

主程序:

read_image (Image11, '11')

*画仿射矩形
dev_set_color ('green')
draw_rectangle2 (3600, Row, Column, Phi, Length1, Length2)

*生成仿射矩形xld
gen_rectangle2_contour_xld (Rectangle, Row, Column, Phi, Length1, Length2)
*找顶点工具(基于卡尺工具)
peak (Image11, Row, Column, Phi, Length1, Length2, 2, 0.41, 20, 'negative', 'first', EdgesY, EdgesX, ResultRow, ResultColumn)

*显示图像
dev_display (Image11)
*显示仿射矩形
dev_display (Rectangle)
*显示所有边缘点
if(|EdgesY|>0)
    dev_set_color ('yellow')
    gen_cross_contour_xld (Cross, EdgesY, EdgesX, 0.5,  0)
    *显示顶点
    dev_set_color ('green')
    gen_cross_contour_xld (Cross,ResultRow, ResultColumn, 3, 0)
    *显示顶点坐标
    disp_message (3600, 'x:='+ResultColumn+'\r\ny:'+ResultRow, 'image', ResultRow, ResultColumn, 'blue', 'false')
endif

peak函数:
在这里插入图片描述

*初始化
ResultRow:=-9999
ResultCol:=-9999
EdgeColumns := []
EdgeRows := []

*仿射矩形Length2所在直线作为rake工具的ROI
ROILineRow1:=0
ROILineCol1:=0
ROILineRow2:=0
ROILineCol2:=0

*仿射矩形方向所直线的边做基准线
StdLineRow1:=0
StdLineCol1:=0
StdLineRow2:=0
StdLineCol2:=0
*判断仿射矩形是否有效
if(Length1<=0 or Length2<=0)
    return()
endif

*计算仿射矩形角度的正弦值、余弦值
tuple_cos (Phi, Cos)
tuple_sin (Phi, Sin)

*矩形第一个端点坐标
Col1 := 1.0*( Coloumn-Length1*Cos - Length2*Sin)
Row1 := 1.0*(Row-(-Length1*Sin + Length2*Cos))

*矩形第二个端点坐标
Col2 := 1.0*(Coloumn+Length1*Cos - Length2*Sin)
Row2 := 1.0*(Row-(Length1*Sin + Length2*Cos))

*矩形第三个端点坐标
Col3 := 1.0*(Coloumn+Length1*Cos + Length2*Sin)
Row3 := 1.0*(Row-(Length1*Sin - Length2*Cos))

*矩形第四个端点坐标
Col4 := 1.0*(Coloumn-Length1*Cos + Length2*Sin)
Row4 := 1.0*(Row-(-Length1*Sin - Length2*Cos))

*仿射矩形方向所直线的边做基准线
StdLineRow1:=Row2
StdLineCol1:=Col2
StdLineRow2:=Row3
StdLineCol2:=Col3

*仿射矩形Length2所在直线作为rake工具的ROI
ROILineRow1 := (Row1+Row2)*0.5
ROILineCol1:= (Col1+Col2)*0.5
ROILineRow2 := (Row3+Row4)*0.5
ROILineCol2:= (Col3+Col4)*0.5
* gen_rectangle2_contour_xld (Rectangle, Row, Coloumn, Phi, Length1, Length2)
rake (Image, Regions1, 1.0*Length2*2, Length1*2, DetectWidth, Sigma, Threshold, Transition, Select, ROILineRow1, ROILineCol1, ROILineRow2, ROILineCol2, ResultRows, ResultColumns)
 
*求所有边缘点到基准线的距离,保存最大距离及其对应的边缘点坐标,作为顶点
Max:=0
if(|ResultColumns|>0)
    EdgeRows := ResultRows
    EdgeColumns := ResultColumns
    for i := 0 to |ResultColumns|-1 by 1
        distance_pl (ResultRows[i], ResultColumns[i], StdLineRow1, StdLineCol1, StdLineRow2, StdLineCol2, Distance1)
    if(Max<Distance1)
        Max:=Distance1
        ResultRow:=ResultRows[i]
        ResultColumn:=ResultColumns[i]
    endif
    
    endfor
endif


return ( )

rake函数:
在这里插入图片描述

*获取图像尺寸	
get_image_size(Image,Width,Height)
*产生一个空显示对象,用于显示
gen_empty_obj(Regions)
*初始化边缘坐标数组
ResultRow := []
ResultColumn := []
*产生直线xld
gen_contour_polygon_xld (RegionLines, [Row1,Row2], [Column1,Column2])
*存储到显示对象
concat_obj(Regions, RegionLines, Regions)
*计算直线与x轴的夹角,逆时针方向为正向。
angle_lx (Row1, Column1, Row2, Column2, ATan)

*边缘检测方向垂直于检测直线:直线方向正向旋转90°为边缘检测方向
ATan:=ATan+rad(90)

*根据检测直线按顺序产生测量区域矩形,并存储到显示对象
for i:=1 to Elements by 1
*     RowC := Row1+(((Row2-Row1)*i)/(Elements+1))
*     ColC := Column1+(Column2-Column1)*i/(Elements+1)
*     if (RowC>Height-1 or RowC<0 or ColC>Width-1 or ColC<0)
*     continue 
*     endif
    *如果只有一个测量矩形,作为卡尺工具,宽度为检测直线的长度
    if(Elements=1)
        RowC := 1.0*(Row1+Row2)*0.5
        ColC := 1.0*(Column1+Column2)*0.5
        *判断是否超出图像,超出不检测边缘
        if (RowC>Height-1 or RowC<0 or ColC>Width-1 or ColC<0)
            continue 
        endif
        distance_pp(Row1, Column1, Row2, Column2, Distance)
        DetectWidth:=Distance
        gen_rectangle2_contour_xld(Rectangle, RowC, ColC,ATan, 1.0*DetectHeight/2,1.0*Distance/2)
    else
        *如果有多个测量矩形,产生该测量矩形xld
        RowC := 1.0*(Row1+(((Row2-Row1)*(i-1))/(Elements-1)))
        ColC := 1.0*(Column1+(Column2-Column1)*(i-1)/(Elements-1))
        *判断是否超出图像,超出不检测边缘
        if (RowC>Height-1 or RowC<0 or ColC>Width-1 or ColC<0)
            continue 
        endif
        gen_rectangle2_contour_xld(Rectangle, RowC, ColC, ATan, 1.0*DetectHeight/2,1.0*DetectWidth/2)
    endif
    
     *把测量矩形xld存储到显示对象
    concat_obj (Regions, Rectangle, Regions)
    if(i=1)
        *在第一个测量矩形绘制一个箭头xld,用于只是边缘检测方向
        RowL2:=RowC+DetectHeight/2*sin(-ATan)
        RowL1:=RowC-DetectHeight/2*sin(-ATan)
        ColL2:=ColC+DetectHeight/2*cos(-ATan)
        ColL1:=ColC-DetectHeight/2*cos(-ATan)
        gen_arrow_contour_xld (Arrow1, RowL1, ColL1, RowL2, ColL2, 25, 25)
        *把xld存储到显示对象
        concat_obj (Regions, Arrow1, Regions)
    endif
    *产生测量对象句柄
    gen_measure_rectangle2(RowC, ColC,ATan, DetectHeight/2,DetectWidth/2,Width, Height, 'nearest_neighbor', MsrHandle_Measure)
    
    *设置极性
    if (Transition = 'negative')
        Transition := 'negative'
    else 
        if (Transition = 'positive')
            
            Transition := 'positive'
     	  else  
            Transition := 'all'
        endif
    endif
    *设置边缘位置。最强点是从所有边缘中选择幅度绝对值最大点,需要设置为'all'
    if (Select = 'first')
        Select := 'first'
    else 
        if (Select = 'last')
            
            Select := 'last'
     	  else  
            Select := 'all'
        endif
    endif
    *检测边缘
    measure_pos (Image, MsrHandle_Measure, Sigma, Threshold, Transition, Select, RowEdge, ColEdge, Amplitude, Distance)
    *清除测量对象句柄
    close_measure(MsrHandle_Measure)
    
    *临时变量初始化
    *tRow,tCol保存找到指定边缘的坐标
    tRow := 0
    tCol := 0
    *t保存边缘的幅度绝对值
    t:= 0
    *找到的边缘必须至少为1
    tuple_length(RowEdge, Number)
    if(Number<1)
        continue
    endif
    *有多个边缘时,选择幅度绝对值最大的边缘
    for j:=0 to Number-1 by 1
        if(abs(Amplitude[j])>t)
            
            tRow := RowEdge[j]
            tCol := ColEdge[j]
            t := abs(Amplitude[j])
        endif
    endfor
    *把找到的边缘保存在输出数组
    if(t>0)
        ResultRow:=[ResultRow,tRow]
        ResultColumn:=[ResultColumn,tCol]
    endif
endfor

return ()

猜你喜欢

转载自blog.csdn.net/cashmood/article/details/111941651
今日推荐