1. 线拟合
1.1 直线卡尺
本小结以计算两条边缘的夹角为例,介绍直线卡尺功能。
1. 图像读取+获取图像尺寸
dev_update_off ()
dev_close_window ()
read_image (Image, 'C:/Users/Admin/Desktop/图像/测量测试图.jpg')
dev_open_window_fit_image (Image, 500, 500, -1, -1, WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_display (Image)
get_image_size (Image, Width, Height)
AI写代码
bash
2. 创建模型
* 创建测量模型的数据结构
create_metrology_model (MetrologyHandle)
* 提前设置图像大小,以加快 图像大小,以加快首次调用 apply_metrology_model 的速度。
set_metrology_model_image_size (MetrologyHandle, Width, Height)
AI写代码
bash
3.定义线测量对象的参数
* 定义计量线对象的参数
LineRow1 := [307,294]
LineColumn1 := [20,56]
LineRow2 := [297,293]
LineColumn2 := [40,508]
Tolerance := 20
AI写代码
bash
4.创建直线测量模型,并设置参数
* 创建2个直线测量模型,并设置参数
add_metrology_object_line_measure (MetrologyHandle, LineRow1, LineColumn1, LineRow2, LineColumn2, 30, 3, 1, 50, [], [], Index1)
* 设置检测框的个数(20个)
set_metrology_object_param (MetrologyHandle, 'all', 'num_measures', 20)
AI写代码
bash
5.将测量模型应用到图像+输出结果
* 将模型应用到图像中
apply_metrology_model (Image, MetrologyHandle)
* 获取结果
get_metrology_object_result (MetrologyHandle, 'all', 'all', 'result_type', 'all_param', LineParameter)
AI写代码
bash
6.测量2条直线之间的角度
* 测量两条直线的角度
angle_ll (LineParameter[0], LineParameter[1], LineParameter[2], LineParameter[3], LineParameter[4], LineParameter[5], LineParameter[6], LineParameter[7], Angle)
Angle := deg(Angle)
AI写代码
bash
7.创建直线图形
* 创建直线图形
get_metrology_object_result_contour (ResultContour, MetrologyHandle, 'all', 'all', 1.5)
intersection_lines (LineParameter[0], LineParameter[1], LineParameter[2], LineParameter[3], LineParameter[4], LineParameter[5], LineParameter[6], LineParameter[7], Row, Column, IsOverlapping1)
AI写代码
bash
8. 计算两条直线的走向
* 计算两条直线的走向
line_orientation (LineParameter[0], LineParameter[1], LineParameter[2], LineParameter[3], Orientation1)
if (Orientation1 > 0)
Orientation1 := Orientation1 - rad(180)
endif
line_orientation (LineParameter[4], LineParameter[5], LineParameter[6], LineParameter[7], Orientation2)
AI写代码
bash
9.可视化
*
* 可视化直线夹角
gen_circle_contour_xld (ContCircle, Row, Column, 10, Orientation1, Orientation2, 'positive', 1)
* 获取用于可视化的测量区域和测量点
get_metrology_object_measures (Contour, MetrologyHandle, 'all', 'all', MRow, MColumn)
gen_cross_contour_xld (Cross, MRow, MColumn, 6, rad(45))
* Display everything
dev_display (Image)
dev_set_line_width (1)
dev_set_color ('yellow')
dev_display (Contour)
dev_display (Cross)
dev_set_line_width (2)
dev_set_color ('green')
dev_display (ResultContour)
dev_set_color ('blue')
dev_display (ContCircle)
AI写代码
bash
结果图:
总结:
通过调节直线卡尺的各项参数(检测框区域起点终点,检测框宽高及数量,检测阈值灯)功能实现,两条边缘的角度测量。
完整代码:
* 直线卡尺实例
dev_update_off ()
dev_close_window ()
read_image (Image, 'C:/Users/Admin/Desktop/图像/测量测试图.jpg')
dev_open_window_fit_image (Image, 500, 500, -1, -1, WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_display (Image)
get_image_size (Image, Width, Height)
*
* 创建测量模型的数据结构
create_metrology_model (MetrologyHandle)
* 提前设置图像大小,以加快 图像大小,以加快首次调用 apply_metrology_model 的速度。
set_metrology_model_image_size (MetrologyHandle, Width, Height)
* 定义计量线对象的参数
LineRow1 := [307,294]
LineColumn1 := [20,56]
LineRow2 := [297,293]
LineColumn2 := [40,508]
Tolerance := 20
*
* 创建2个直线测量模型,并设置参数
add_metrology_object_line_measure (MetrologyHandle, LineRow1, LineColumn1, LineRow2, LineColumn2, 10, 3, 1, 10, [], [], Index1)
* 设置检测框的个数(20个)
* set_metrology_object_param (MetrologyHandle, 'all', 'num_measures', 20)
* 将模型应用到图像中
apply_metrology_model (Image, MetrologyHandle)
* 获取结果
get_metrology_object_result (MetrologyHandle, 'all', 'all', 'result_type', 'all_param', LineParameter)
* 测量两条直线的角度
angle_ll (LineParameter[0], LineParameter[1], LineParameter[2], LineParameter[3], LineParameter[4], LineParameter[5], LineParameter[6], LineParameter[7], Angle)
Angle := deg(Angle)
* 创建直线图形
get_metrology_object_result_contour (ResultContour, MetrologyHandle, 'all', 'all', 1.5)
intersection_lines (LineParameter[0], LineParameter[1], LineParameter[2], LineParameter[3], LineParameter[4], LineParameter[5], LineParameter[6], LineParameter[7], Row, Column, IsOverlapping1)
* 计算两条直线的走向
line_orientation (LineParameter[0], LineParameter[1], LineParameter[2], LineParameter[3], Orientation1)
if (Orientation1 > 0)
Orientation1 := Orientation1 - rad(180)
endif
line_orientation (LineParameter[4], LineParameter[5], LineParameter[6], LineParameter[7], Orientation2)
*
* 可视化直线夹角
gen_circle_contour_xld (ContCircle, Row, Column, 10, Orientation1, Orientation2, 'positive', 1)
* 获取用于可视化的测量区域和测量点
get_metrology_object_measures (Contour, MetrologyHandle, 'all', 'all', MRow, MColumn)
gen_cross_contour_xld (Cross, MRow, MColumn, 6, rad(45))
* Display everything
dev_display (Image)
dev_set_line_width (1)
dev_set_color ('yellow')
dev_display (Contour)
dev_display (Cross)
dev_set_line_width (2)
dev_set_color ('green')
dev_display (ResultContour)
dev_set_color ('blue')
dev_display (ContCircle)
disp_message (WindowHandle, 'Angle = ' + Angle$'.5' + '°', 'window', 12, 12, 'black', 'true')
AI写代码
bash
2. 圆拟合
2.1 图像读取,创建显示窗体
清空窗体后,根据图像大小重新打开窗体,将其显示在屏幕的(500,500)位置上,并显示图像。
* 圆拟合实例
dev_update_off ()
dev_close_window ()
read_image (Image, 'C:/Users/Admin/Desktop/图像/测试图7.bmp')
dev_open_window_fit_image (Image, 500, 500, -1, -1, WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_display (Image)
AI写代码
bash
2.2 圆拟合参数设置
在创建圆拟合卡尺工具前,需要对参数进行设置。这里需要重点强调的几个参数包括:
小圆卡尺和大圆卡尺:大家看到这里会比较疑惑,为什么要设置两个圆。其实这里的目的是为了通过大圆和小圆的半径差来设置矩形检测区域的高度。我这样做是为了对接C#程序的UI交互页面。其实直接设置它的高度,也能达到同样的效果。
最小匹配分数:值越小,模型的容差越大,反之相反。简单的说,值小的时候,模型会尽可能匹配出圆,而舍弃一部分准确性。当值大的时候,模型的准确性就会较高,对应的图像必须得是相对较为规整的圆形。
极性:极性方向从圆心出发,沿着半径发散。
拟合点选择:拟合点选择方向从圆心出发,沿半径发散。
拟合算法:默认选择“邻近算法”。其中“双三插值算法”精度最高,对应耗时也最久。
** 参数设置
* 圆卡尺Row坐标
CircleMetrologyRow := 420
* 圆卡尺Col坐标
CircleMetrologyColumn := 1077
* 小圆卡尺半径
SmallCircleMetrologyRadius := 80
* 大圆卡尺半径
BigCircleMetrologyRadius := 120
* 检测框宽度
CircleMetrologyWidth := 5
* 检测框数量
CircleMetrologyAmount := 20
* Sigma
MeasureSigma := 1
* Threshold(阈值)
MeasureThreshold := 30
* 最小匹配值
MeasureMinScore:= 0.1
* 极性(positive:由黑到白; negative: 由白到黑; all:任意)
MeasureTransition :='all'
* 拟合点选择(first:第一个; last:最后一个; all:所有)
MeasureSelect := 'all'
* 拟合算法选择(nearest_neighbor:邻近算法; bilinear:双线插值算法; bicubic:双三次插值算法)
FittingMethod :='nearest_neighbor'
AI写代码
bash
2.3 圆拟合算法实现
2.3.1 图像格式转换
对于三通道或对通道的图像,需要对图像进行转换。统一转换为灰度图。(这一步也可以放在代码的开头,作为数据预处理)
* 转换彩图至灰度图
count_channels (ImageOut, imgChannels)
if(imgChannels != 1)
rgb1_to_gray (ImageOut, ImageOut)
endif
* 转换real图至byte图
get_image_type (ImageOut, imgType)
if(imgType == 'real')
ChangeDepthImageToByteImage (ImageOut, ImageOut, 1, result)
if(result != '')
return()
endif
endif
AI写代码
bash
2.3.2 构建圆检测模型
构建圆检测模型。需要注意的是,在构建圆检测模型前可以先获取一下图像尺寸,并将图像尺寸传给模型,从而提升模型的速度。
* 获取图像尺寸
get_image_size (ImageOut, Width, Height)
* 准备测量模型数据结构
create_metrology_model (MetrologyHandle)
* 设置图像大小从而提升第一次的运行速度
set_metrology_model_image_size (MetrologyHandle, Width, Height)
* 添加圆形检测模型
add_metrology_object_circle_measure (MetrologyHandle, CircleMetrologyRow, CircleMetrologyColumn, CircleMetrologyRadius, CircleMetrologyHight, CircleMetrologyWidth, MeasureSigma, MeasureThreshold, [], [], MetrologyCircleIndices)
AI写代码
bash
2.3.3 设置模型参数
在构建完检测模型后,需要将模型参数传入。下方的参数对应着2.2章节的参数。
* 设置圆形检测模型的参数
set_metrology_object_param (MetrologyHandle, MetrologyCircleIndices, 'num_measures', CircleMetrologyAmount)
set_metrology_object_param (MetrologyHandle, MetrologyCircleIndices, 'min_score', MeasureMinScore)
set_metrology_object_param (MetrologyHandle, MetrologyCircleIndices, 'measure_transition', MeasureTransition)
set_metrology_object_param (MetrologyHandle, MetrologyCircleIndices, 'measure_select', MeasureSelect)
set_metrology_object_param (MetrologyHandle, MetrologyCircleIndices, 'measure_interpolation', FittingMethod)
AI写代码
bash
2.3.4 进行测量,获取结果
进行测量,测量结果会储存在“CircleParameter”中。按照顺序,第一位存了圆的Row坐标,第二位存了圆的Column坐标,第三位存了圆的半径。如果这个变量为空,说明检测失败。
* 进行测量
apply_metrology_model (ImageOut, MetrologyHandle)
* 获取结果
get_metrology_object_result (MetrologyHandle, MetrologyCircleIndices, 'all', 'result_type', 'all_param', CircleParameter)
if(|CircleParameter| != 0)
CircleRow := CircleParameter[0]
CircleColumn := CircleParameter[1]
CircleRadius := CircleParameter[2]
endif
AI写代码
bash
2.3.5 创建可视化的图形
创建一些可视化的图像,从而便于观察检测结果。
* 获取测量对象的轮廓线
get_metrology_object_result_contour (CircleContour, MetrologyHandle, 'all', 'all', 1.5)
* 获取测量轮廓线,以及拟合点坐标
get_metrology_object_measures (MetrologyContour, MetrologyHandle, 'all', 'all', PointRows, PointColumns)
gen_cross_contour_xld (CrossContour, PointRows, PointColumns, 6, 0.785398)
AI写代码
bash
2.3.6 可视化显示
dev_display (CircleContour)
dev_display (MetrologyContour)
dev_display (CrossContour)
AI写代码
bash
2.4 效果展示
这边尝试拟合了一个扇形,将“最小分数”改小后的拟合效果。图中的小矩形就是检测框,检测框中的叉叉就是拟合出来的点。
2.5 完整代码展示
* 圆拟合实例
dev_update_off ()
dev_close_window ()
read_image (Image, 'C:/Users/Admin/Desktop/图像/测试图7.bmp')
dev_open_window_fit_image (Image, 500, 500, -1, -1, WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_display (Image)
** 参数设置
* 圆卡尺Row坐标
CircleMetrologyRow := 420
* 圆卡尺Col坐标
CircleMetrologyColumn := 1077
* 小圆卡尺半径
SmallCircleMetrologyRadius := 80
* 大圆卡尺半径
BigCircleMetrologyRadius := 120
* 检测框宽度
CircleMetrologyWidth := 5
* 检测框数量
CircleMetrologyAmount := 20
* Sigma
MeasureSigma := 1
* Threshold(阈值)
MeasureThreshold := 30
* 最小匹配值
MeasureMinScore:= 0.1
* 极性(positive:由黑到白; negative: 由白到黑; all:任意)
MeasureTransition :='all'
* 拟合点选择(first:第一个; last:最后一个; all:所有)
MeasureSelect := 'all'
* 拟合算法选择(nearest_neighbor:邻近算法; bilinear:双线插值算法; bicubic:双三次插值算法)
FittingMethod :='nearest_neighbor'
** 圆拟合函数
FittingCircle (Image, CircleContour, MetrologyContour, CrossContour, CircleMetrologyRow, CircleMetrologyColumn, SmallCircleMetrologyRadius, BigCircleMetrologyRadius, CircleMetrologyWidth, CircleMetrologyAmount, MeasureSigma, MeasureThreshold, MeasureMinScore, MeasureTransition, MeasureSelect, FittingMethod, CircleRow, CircleColumn, CircleRadius)
** 可视化
dev_display (CircleContour)
dev_display (MetrologyContour)
dev_display (CrossContour)
AI写代码
bash
其中“圆拟合函数”代码如下:
ImageOut := Image
CircleMetrologyRadius := (BigCircleMetrologyRadius+SmallCircleMetrologyRadius)/2
CircleMetrologyHight :=(BigCircleMetrologyRadius-SmallCircleMetrologyRadius)/2
* 转换彩图至灰度图
count_channels (ImageOut, imgChannels)
if(imgChannels != 1)
rgb1_to_gray (ImageOut, ImageOut)
endif
* 转换real图至byte图
get_image_type (ImageOut, imgType)
if(imgType == 'real')
ChangeDepthImageToByteImage (ImageOut, ImageOut, 1, result)
if(result != '')
return()
endif
endif
* 获取图像尺寸
get_image_size (ImageOut, Width, Height)
* 准备测量模型数据结构
create_metrology_model (MetrologyHandle)
* 设置图像大小从而提升第一次的运行速度
set_metrology_model_image_size (MetrologyHandle, Width, Height)
* 添加圆形检测模型
add_metrology_object_circle_measure (MetrologyHandle, CircleMetrologyRow, CircleMetrologyColumn, CircleMetrologyRadius, CircleMetrologyHight, CircleMetrologyWidth, MeasureSigma, MeasureThreshold, [], [], MetrologyCircleIndices)
* 设置圆形检测模型的参数
set_metrology_object_param (MetrologyHandle, MetrologyCircleIndices, 'num_measures', CircleMetrologyAmount)
set_metrology_object_param (MetrologyHandle, MetrologyCircleIndices, 'min_score', MeasureMinScore)
set_metrology_object_param (MetrologyHandle, MetrologyCircleIndices, 'measure_transition', MeasureTransition)
set_metrology_object_param (MetrologyHandle, MetrologyCircleIndices, 'measure_select', MeasureSelect)
set_metrology_object_param (MetrologyHandle, MetrologyCircleIndices, 'measure_interpolation', FittingMethod)
* 进行测量
apply_metrology_model (ImageOut, MetrologyHandle)
* 获取结果
get_metrology_object_result (MetrologyHandle, MetrologyCircleIndices, 'all', 'result_type', 'all_param', CircleParameter)
if(|CircleParameter| != 0)
CircleRow := CircleParameter[0]
CircleColumn := CircleParameter[1]
CircleRadius := CircleParameter[2]
endif
* 获取测量对象的轮廓线
get_metrology_object_result_contour (CircleContour, MetrologyHandle, 'all', 'all', 1.5)
* 获取测量轮廓线,以及拟合点坐标
get_metrology_object_measures (MetrologyContour, MetrologyHandle, 'all', 'all', PointRows, PointColumns)
gen_cross_contour_xld (CrossContour, PointRows, PointColumns, 6, 0.785398)
return ()
AI写代码
bash
参考此文章进行直线和圆的拟合