halcon 测量拟合 一维测量

一、一维测量的原理

原理:灰度投影+导数(最小幅度值)[Halcon&测量] 一维测量_Loewen丶的小窝-CSDN博客_halcon一维测量

1、Halocn的一维测量首先构建矩形或者扇形的ROI测量对象,然后在ROI内画出等距离的、长度与ROI宽度一致的、垂直于ROI的轮廓线(profile line)的等距线

2、测量ROI的轮廓线尽量与被测边缘垂直,宽度适当宽些

3、然后,沿着垂直轮廓线的方向,计算出每一条等距线的平均灰度值,可以得出轮廓线的灰度直方图,同时可以选择使用高斯滤波器平滑灰度直方图

4、求出平滑灰度直方图的一阶导数,(一阶导数为最大,二阶导数为0)一阶导数的极值点作为边缘的亚像素精度候选点,只有一阶导数极值点的绝对值大于预先设定的阈值(测量算子的参数Threshold)边缘候选点才被选作为边缘中心点(沿着刨分线的放向的一阶导数

二、原理解释

【Halcon】1D测量-工业视觉/halcon-少有人走的路

1、什么是轮廓线?什么是切片?

 2、计算平均灰度值

 

 3、如何提取边缘

 三、流程

1、采集图像(灰度图)

2、测量矩形或者是测量弧形

 测量矩形

gen_measure_rectangle2 (Row, Column, Angle, Length1, Length2, Width, Height, 'bilinear', MeasureHandle)

*生成一个测量的卡尺
*gen_measure_rectangle2:确定测量的矩形的具体位置
*Row (input_control):矩形中心点的行坐标
*Column (input_control):矩形中心点的列坐标
*Phi (input_control):刨分线与水平方向的夹角(弧度制)
*Length1 (input_control):矩形长轴的一半
*Length2 (input_control):矩形短轴的一半
*Width (input_control) :待处理图像的宽度
*Height (input_control) :待处理图像的高度
*Interpolation (input_control) :插值方式(‘bicubic’, ‘bilinear’,‘nearest_neighbor’)
*MeasureHandle (output_control) :测量对象句柄

 

刨分线方向是    

测量弧形

gen_measure_arc( : : CenterRow, CenterCol, Radius, AngleStart, AngleExtent, AnnulusRadius, Width, Height, Interpolation : MeasureHandle)
名字:生成环形区域测量句柄
描述:用于提取垂直环形圆弧的直边缘。
参数:
CenterRow:圆弧中心行坐标
CenterCol:圆弧中心列坐标
Radius:圆弧半径
AngleStart:圆弧起始角度
AngleExtent:圆弧角度范围
AnnulusRadius:环形带的半径(宽度的一半)
Width:图像的宽度
Height:图像的高度
Interpolation :插值类型
MeasureHandle:测量对象句柄

3、测量 边缘对

measure_pairs - 提取垂直于矩形或环形弧的直边对



measure_pairs (Fuse, MeasureHandle, 1, 1, 'negative', 'all', RowEdgeFirst, ColumnEdgeFirst, AmplitudeFirst, RowEdgeSecond, ColumnEdgeSecond, AmplitudeSecond, IntraDistance, InterDistance)

* 提取垂直于矩形或者是弧形的直边对
* 单通道的图像
* 上面定义的测量句柄
* 高斯模糊的Sigma的值,Sigma指定了高斯滤波器的标准差  ,Sigma越大图像越平缓,高斯函数(正太分布)
* 最小边缘幅度值,越大则检测到的边就越少,和canny算子的那个滞后阈值处理一样理解
* 边缘如何成对,'negative'   postive  :沿着 刨分线的方向由暗到亮维为正     all:
* 选择找点的模式(all: 所有的点,first 输出所有的点, last 输出最后一个点)
* 边缘对第一条边的中心行的坐标(2个值)
* 边缘对第一条边列的坐标
* 两条边的边缘幅度值,有符号的
* 边缘对第二条边的中心行的坐标(2个值)
* 边缘对第二条边列的坐标
* 两条边的边缘幅度值,有符号的


***  边缘对内部之间的距离
***  连续边缘对之间的距离


 

 

 

边缘 

measure_pos(Image : : MeasureHandle, Sigma, Threshold, Transition, Select : RowEdge, ColumnEdge, Amplitude, Distance)
Image (input_object) :输入图像
MeasureHandle (input_control) :测量对象句柄
Sigma (input_control) :Sigma指定了高斯滤波器的标准差。 高斯滤波参数,越大越平滑
Threshold (input_control) :边缘强度控制阈值,最小边缘幅度
Transition (input_control) :边界从白到黑还是从黑到白(分别对          应’negative’,‘positive’,也可以选择‘all’)这个是得到矩形的那个方向
Select (input_control) :选择寻点的模式( 'all’输出所有点, 'first’输出第一个点, 'last’输出最后一个点)
下面四个是
RowEdge (output_control) :寻到直边的中心点行坐
ColumnEdge (output_control) :寻到直边的中心点列坐标
Aplitude (output_control) :寻到直边的边缘强度值
Distance (output_control) :连续边之间的距离

 

极性

上面极性写错了, 弃明投暗是negative ,反之就是positive

位置:

dev_update_window ('off')
dev_close_window ()
* ****
* (1)获取图像
* ****
read_image (Fuse, 'fuse')
get_image_size (Fuse, Width, Height)

* Measure 02: Code generated by Measure 02
* Measure 02: Prepare measurement
AmplitudeThreshold := 31
RoiWidthLen2 := 32.5
set_system ('int_zooming', 'false')
* Measure 02: Coordinates for line Measure 02 [0]
LineRowStart_Measure_02_0 := 379.889
LineColumnStart_Measure_02_0 := 554.367
LineRowEnd_Measure_02_0 := 214.226
LineColumnEnd_Measure_02_0 := 559.762
* Measure 02: Convert coordinates to rectangle2 type
TmpCtrl_Row := 0.5*(LineRowStart_Measure_02_0+LineRowEnd_Measure_02_0)
TmpCtrl_Column := 0.5*(LineColumnStart_Measure_02_0+LineColumnEnd_Measure_02_0)
TmpCtrl_Dr := LineRowStart_Measure_02_0-LineRowEnd_Measure_02_0
TmpCtrl_Dc := LineColumnEnd_Measure_02_0-LineColumnStart_Measure_02_0
TmpCtrl_Phi := atan2(TmpCtrl_Dr, TmpCtrl_Dc)
TmpCtrl_Len1 := 0.5*sqrt(TmpCtrl_Dr*TmpCtrl_Dr + TmpCtrl_Dc*TmpCtrl_Dc)
TmpCtrl_Len2 := RoiWidthLen2
* Measure 02: Create measure for line Measure 02 [0]
* Measure 02: Attention: This assumes all images have the same size!
gen_measure_rectangle2 (TmpCtrl_Row, TmpCtrl_Column, TmpCtrl_Phi, TmpCtrl_Len1, TmpCtrl_Len2, 768, 576, 'nearest_neighbor', MsrHandle_Measure_02_0)
* Measure 02: ***************************************************************
* Measure 02: * The code which follows is to be executed once / measurement *
* Measure 02: ***************************************************************
* Measure 02: The image is assumed to be made available in the
* Measure 02: variable last displayed in the graphics window
copy_obj (Fuse, Image, 1, 1)
* Measure 02: Execute measurements
measure_pairs (Image, MsrHandle_Measure_02_0, 6.1, AmplitudeThreshold, 'all', 'all', Row1_Measure_02_0, Column1_Measure_02_0, Amplitude1_Measure_02_0, Row2_Measure_02_0, Column2_Measure_02_0, Amplitude2_Measure_02_0, Width_Measure_02_0, Distance_Measure_02_0)
* Measure 02: Do something with the results
gen_cross_contour_xld (Cross1, Row1_Measure_02_0, Column1_Measure_02_0, 169, 0.785398)
gen_cross_contour_xld (Cross2, Row2_Measure_02_0, Column2_Measure_02_0, 169, 0.785398)



















* Measure 01: Code generated by Measure 01
* Measure 01: Prepare measurement
AmplitudeThreshold := 47
RoiWidthLen2 := 41.5
set_system ('int_zooming', 'true')
* Measure 01: Coordinates for line Measure 01 [0]
LineRowStart_Measure_01_0 := 290.671
LineColumnStart_Measure_01_0 := 473.746
LineRowEnd_Measure_01_0 := 292.784
LineColumnEnd_Measure_01_0 := 717.229
* Measure 01: Convert coordinates to rectangle2 type
TmpCtrl_Row := 0.5*(LineRowStart_Measure_01_0+LineRowEnd_Measure_01_0)
TmpCtrl_Column := 0.5*(LineColumnStart_Measure_01_0+LineColumnEnd_Measure_01_0)
TmpCtrl_Dr := LineRowStart_Measure_01_0-LineRowEnd_Measure_01_0
TmpCtrl_Dc := LineColumnEnd_Measure_01_0-LineColumnStart_Measure_01_0
TmpCtrl_Phi := atan2(TmpCtrl_Dr, TmpCtrl_Dc)
TmpCtrl_Len1 := 0.5*sqrt(TmpCtrl_Dr*TmpCtrl_Dr + TmpCtrl_Dc*TmpCtrl_Dc)
TmpCtrl_Len2 := RoiWidthLen2
* Measure 01: Create measure for line Measure 01 [0]
* Measure 01: Attention: This assumes all images have the same size!
gen_measure_rectangle2 (TmpCtrl_Row, TmpCtrl_Column, TmpCtrl_Phi, TmpCtrl_Len1, TmpCtrl_Len2, 768, 576, 'nearest_neighbor', MsrHandle_Measure_01_0)
* Measure 01: ***************************************************************
* Measure 01: * The code which follows is to be executed once / measurement *
* Measure 01: ***************************************************************
* Measure 01: The image is assumed to be made available in the
* Measure 01: variable last displayed in the graphics window
copy_obj (Fuse, Image, 1, 1)
* Measure 01: Execute measurements
measure_pos (Image, MsrHandle_Measure_01_0, 3.1, AmplitudeThreshold, 'all', 'all', Row_Measure_01_0, Column_Measure_01_0, Amplitude_Measure_01_0, Distance_Measure_01_0)
* Measure 01: Do something with the results

gen_cross_contour_xld (Cross, Row_Measure_01_0, Column_Measure_01_0, 100, 0.785398)



read_image (Image, 'ic_pin')
get_image_size (Image, Width, Height)
* Measure 03: Code generated by Measure 03
* Measure 03: Prepare measurement
AmplitudeThreshold := 38
RoiWidthLen2 := 6.5
set_system ('int_zooming', 'true')
* Measure 03: Coordinates for line Measure 03 [0]
LineRowStart_Measure_03_0 := 56.1067
LineColumnStart_Measure_03_0 := 60.1518
LineRowEnd_Measure_03_0 := 62.4751
LineColumnEnd_Measure_03_0 := 930.307
* Measure 03: Convert coordinates to rectangle2 type
TmpCtrl_Row := 0.5*(LineRowStart_Measure_03_0+LineRowEnd_Measure_03_0)
TmpCtrl_Column := 0.5*(LineColumnStart_Measure_03_0+LineColumnEnd_Measure_03_0)
TmpCtrl_Dr := LineRowStart_Measure_03_0-LineRowEnd_Measure_03_0
TmpCtrl_Dc := LineColumnEnd_Measure_03_0-LineColumnStart_Measure_03_0
TmpCtrl_Phi := atan2(TmpCtrl_Dr, TmpCtrl_Dc)
TmpCtrl_Len1 := 0.5*sqrt(TmpCtrl_Dr*TmpCtrl_Dr + TmpCtrl_Dc*TmpCtrl_Dc)
TmpCtrl_Len2 := RoiWidthLen2
* Measure 03: Create measure for line Measure 03 [0]
* Measure 03: Attention: This assumes all images have the same size!
gen_measure_rectangle2 (TmpCtrl_Row, TmpCtrl_Column, TmpCtrl_Phi, TmpCtrl_Len1, TmpCtrl_Len2, 988, 1018, 'nearest_neighbor', MsrHandle_Measure_03_0)
* Measure 03: ***************************************************************
* Measure 03: * The code which follows is to be executed once / measurement *
* Measure 03: ***************************************************************
* Measure 03: The image is assumed to be made available in the
* Measure 03: variable last displayed in the graphics window
copy_obj (Image, Image, 1, 1)
* Measure 03: Execute measurements
measure_pairs (Image, MsrHandle_Measure_03_0, 1, AmplitudeThreshold, 'all', 'all', Row1_Measure_03_0, Column1_Measure_03_0, Amplitude1_Measure_03_0, Row2_Measure_03_0, Column2_Measure_03_0, Amplitude2_Measure_03_0, Width_Measure_03_0, Distance_Measure_03_0)
* Measure 03: Do something with the results

gen_cross_contour_xld (Cross1, Row1_Measure_03_0, Column1_Measure_03_0, 16, 0.785398)
gen_cross_contour_xld (Cross2, Row2_Measure_03_0, Column2_Measure_03_0, 16, 0.785398)

measure_pairs与measure_pos的区别:一般,measure_pairs可以用于许多组边缘对的情况,measure_pos用于一组边缘对的情况。

translate_measure( : : MeasureHandle, Row, Column )(选用)
名字:转换一个度量对象
描述:一般用于一个程序中有很多测量矩形的情况,当使用第二个测量矩形时,不需要重新   gen_measure_rectangle2生成,将第二个测量矩形的中心坐标放到该算子的第二、三个参数当中即可,其第一个参数得到的句柄就相当于使用gen_measure_rectangle2算子正常生成的测量矩形句柄。然后使用measure_pos对该句柄进行正常计算。
参数:
MeasureHandle:测量句柄
Row:新参考点的行坐标
Column :新参考点的列坐标

4、显示

gen_contour_polygon_rounded_xld创建带圆角的多边形轮廓,坐标和圆角可以通过数组的形式指定。



gen_contour_polygon_xld创建不带圆角的多边形轮廓,坐标同样可以使用数组的形式指定。
Image (input_object)   单通道图像  要获取灰度值的图像。
Contour (input_object)   以位置坐标输入的XLD轮廓。
Interpolation (input_control)  插值方法
Grayval (output_control) 所选图像坐标的灰度值。
* fuse.hdev: measuring the width of a fuse wire
* 
dev_update_window ('off')
dev_close_window ()
* ****
* step: acquire image
* ****
read_image (Fuse, 'fuse')
get_image_size (Fuse, Width, Height)
dev_open_window_fit_image (Fuse, 0, 0, Width, Height, WindowID)
set_display_font (WindowID, 12, 'mono', 'true', 'false')
dev_set_draw ('margin')
dev_set_line_width (3)
dev_display (Fuse)
set_display_font (WindowID, 12, 'mono', 'true', 'false')
disp_continue_message (WindowID, 'black', 'true')
stop ()
* ****
* step: create measure object
* ****
* -> specify ROI
Row := 297
Column := 545
Length1 := 80
Length2 := 10
Angle := rad(90)
*
gen_rectangle2 (ROI, Row, Column, Angle, Length1, Length2)
* -> create measure object
*生成一个测量的卡尺
*gen_measure_rectangle2:确定测量的矩形的具体位置
*Row (input_control):矩形中心点的行坐标
*Column (input_control):矩形中心点的列坐标
*Phi (input_control):刨分线与水平方向的夹角(弧度制)
*Length1 (input_control):矩形长轴的一半
*Length2 (input_control):矩形短轴的一半
*Width (input_control) :待处理图像的宽度
*Height (input_control) :待处理图像的高度
*Interpolation (input_control) :插值方式(‘bicubic’, ‘bilinear’,‘nearest_neighbor’)
*MeasureHandle (output_control) :测量对象句柄
gen_measure_rectangle2 (Row, Column, Angle, Length1, Length2, Width, Height, 'bilinear', MeasureHandle)
dev_display (ROI)
disp_continue_message (WindowID, 'black', 'true')
stop ()
* ****
* step: measure  开始测量
* ****‘




* 提取垂直于矩形或者是弧形的直边对
* 单通道的图像
* 上面定义的测量句柄
* 高斯模糊的Sigma的值,也就是桌标准差  ,Sigma越大图像越平缓,高斯函数(正太分布)
* 最小边缘幅度值,越大则检测到的边就越少,和canny算子的那个滞后阈值处理一样理解
* 边缘如何成对,'negative'   postive  :沿着 刨分线的方向由暗到亮维为正     all:
* 选择找点的模式(all: 所有的点,first 输出所有的点, last 输出最后一个点)
* 边缘对第一条边的中心行的坐标(2个值)
* 边缘对第一条边列的坐标
* 两条边的边缘幅度值,有符号的
* 边缘对第二条边的中心行的坐标(2个值)
* 边缘对第二条边列的坐标
* 两条边的边缘幅度值,有符号的


***  边缘对内部之间的距离
***  连续边缘对之间的距离
measure_pairs (Fuse, MeasureHandle, 1, 1, 'negative', 'all', RowEdgeFirst, ColumnEdgeFirst, AmplitudeFirst, RowEdgeSecond, ColumnEdgeSecond, AmplitudeSecond, IntraDistance, InterDistance)




disp_continue_message (WindowID, 'black', 'true')
stop ()
* ****
* step: visualize results
* ****
num :=|RowEdgeFirst|  // 边缘对的个数

for i := 0 to |RowEdgeFirst| - 1 by 1
    
    * gen_contour_polygon_xld创建不带圆角的多边形轮廓
    gen_contour_polygon_xld (EdgeFirst, [-sin(Angle + rad(90)) * Length2 + RowEdgeFirst[i],-sin(Angle - rad(90)) * Length2 + RowEdgeFirst[i]], [cos(Angle + rad(90)) * Length2 + ColumnEdgeFirst[i],cos(Angle - rad(90)) * Length2 + ColumnEdgeFirst[i]])
    gen_contour_polygon_xld (EdgeSecond, [-sin(Angle + rad(90)) * Length2 + RowEdgeSecond[i],-sin(Angle - rad(90)) * Length2 + RowEdgeSecond[i]], [cos(Angle + rad(90)) * Length2 + ColumnEdgeSecond[i],cos(Angle - rad(90)) * Length2 + ColumnEdgeSecond[i]])
    dev_set_color ('red')
    dev_display (EdgeFirst)
    dev_set_color ('magenta')
    dev_display (EdgeSecond)
    dev_set_color ('blue')
    if (i == 0)
        set_tposition (WindowID, RowEdgeFirst[i] + 5, ColumnEdgeFirst[i] + 20)
    else
        set_tposition (WindowID, RowEdgeFirst[i] - 40, ColumnEdgeFirst[i] + 20)
    endif
    write_string (WindowID, 'width: ' + IntraDistance[i] + ' pix')
endfor
disp_continue_message (WindowID, 'black', 'true')
stop ()
* ****
* step: destroy measure object
* ****
close_measure (MeasureHandle)
dev_update_window ('on')
dev_clear_window ()

measure_pin.dev

  • 3
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值