C#Halcon从零开发_Day10_直线拟合

一、引言

直线拟合应用场景:

  • 产品边缘检测:检测产品的直线边缘(如金属板、塑料件的边缘),判断是否符合设计规格。
  • 缺陷检测:通过拟合直线检测边缘的直线度,识别是否存在弯曲、断裂或毛刺等缺陷。
  • 长度、宽度测量:通过拟合直线计算物体的长度、宽度等几何尺寸。

二、具体实施:

dev_get_window (WindowHandle)
read_image (Image2, 'C:/Users/10314/Desktop/rpic1.jpg')
rgb1_to_gray (Image2, Image)


*1、绘制卡尺形态


Elements:=10
Rowc:=0
Colc:=0
DetecHeight:=100
DetecWidth:=20
disp_message (WindowHandle, '画一条直线,右键是确认', 'window', 12, 12, 'red', 'false')
*生成空显示对象,用于显示
gen_empty_obj (EmptyObject)
*画线
draw_line (WindowHandle, Row1, Column1, Row2, Column2)
*产生直线xld 多边形的两点表示直线轮廓
gen_contour_polygon_xld (RegionLines, [Row1,Row2], [Column1,Column2])
*存储到显示对象
concat_obj (EmptyObject, RegionLines, EmptyObject)
*计算直线与X轴的夹角,逆时针为正
angle_lx (Row1, Column1, Row2, Column2, Angle)
*边缘检测方向垂直于检测直线:加90°
Angle:=Angle+rad(90)
*根据检测直线按顺序产生测量区域矩形,并存储到显示对象
for Index:=1 to Elements by 1
    *只有一个测量矩形,作为卡尺工具,宽度为检测直线的长度
    if(Elements==1)
        Rowc:=(Row1+Row2)/2
        Colc:=(Column1+Column2)/2
        distance_pp (Row1, Column1, Row2, Column2, Distance)
        gen_rectangle2_contour_xld (Rectangle, Rowc, Colc, Angle, DetecHeight/2, Distance/2)
    else
        *多个测量矩形,产生该测量矩形xld
        Rowc:=Row1 + ((Row2-Row1)/(Elements-1))*(Index-1)
        Colc:=Column1 +((Column2-Column1)/(Elements-1))*(Index-1)
        gen_rectangle2_contour_xld (Rectangle, Rowc, Colc, Angle, DetecHeight/2, DetecWidth/2)
    endif
       if(Index==1)
           ArrBStartRow:= Rowc-cos(-Angle+rad(90))*DetecHeight/2
           ArrStartCol:= Colc +sin(-Angle+rad(90))*DetecHeight/2
           ArrEndRow:=Rowc+cos(-Angle+rad(90))*DetecHeight/2
           ArrEndCol:=Colc -sin(-Angle+rad(90))*DetecHeight/2
           HeadLength:=10
           HeadWidth:=10
           *在第一个测量矩形绘制一个箭头xld。显示边缘检测方向
           gen_arrow_contour_xld (Arrow, ArrBStartRow, ArrStartCol, ArrEndRow, ArrEndCol, HeadLength, HeadWidth)
       endif
        
endfor

*2、卡尺测量


get_image_size (Image, Width, Height)
RowEdgeList:=[]
for i := 0 to Elements-1 by 1
    RowEdgeList := [RowEdgeList, i]
endfor
ColumnEdgeList:=[]
for i := 0 to Elements-1 by 1
    ColumnEdgeList := [ColumnEdgeList, i]
endfor
sigma:=1
Threshold:=20
*由明到暗为负极性
trans:='negative'
sel:='first'
dev_set_color ('green')
for Index:=1 to Elements by 1
    *只有一个测量矩形2,作为卡尺工具,宽度为检测直线的长度
    if(Elements==1)
        *省略
    else
        *生成多个矩形2卡尺并测量
        Rowc:=Row1 + ((Row2-Row1)/(Elements-1))*(Index-1)
        Colc:=Column1 +((Column2-Column1)/(Elements-1))*(Index-1)
        **由于检测为negative: 亮--暗,所以测量矩阵需要角度往下,也就是加上180°
        gen_measure_rectangle2 (Rowc, Colc, Angle+rad(180), DetecHeight/2, DetecWidth/2, Width, Height, 'nearest_neighbor', MeasureHandle)
        
        measure_pos (Image, MeasureHandle,sigma, Threshold, trans, sel, RowEdge, ColumnEdge, Amplitude, Distance1)
        RowEdgeList[Index-1]:= RowEdge
        ColumnEdgeList[Index-1]:=ColumnEdge
        gen_cross_contour_xld (Cross, RowEdge, ColumnEdge, 12, 0.785398)
        clear_handle (MeasureHandle)
    endif 
endfor

*3.拟合直线


*生成xld轮廓
gen_contour_polygon_xld (Contour, RowEdgeList, ColumnEdgeList)
*Contour :输入轮廓
*‘tukey’ 使用Tukey权重函数进行鲁棒拟合
*-1: 最大点数(此处使用-1表示使用所有点)
* 0: 裁剪端点(0表示不裁剪)
*5: 迭代次数(对于鲁棒拟合)
*2: 拟合直线的阶数(1表示直线)拟合直线的阶数为2表示你正在使用二次多项式(即抛物线)来拟合数据点,而不是简单的直线(一阶多项式)。
*一阶(Degree=1):直线方程 y=a⋅x+b。 二阶(Degree=2):抛物线方程 y=a⋅x 2+b⋅x+c。
* 输出 RowBegin, ColBegin: 拟合直线起点的行和列坐标
* 输出 RowEnd, ColEnd: 拟合直线终点的行和列坐标
* Nr, Nc: 输出直线的方向向量(可选)
* 输出 点到直线的平均距离(可选)
fit_line_contour_xld(Contour, 'tukey', -1, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist)

 gen_contour_polygon_xld(FittedLine, [RowBegin, RowEnd], [ColBegin, ColEnd])
dev_display(Image)  
dev_set_color('red')
dev_set_line_width(2)
dev_display(FittedLine)

最终效果为:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值