Halcon测量专栏-圆弧测量

2024-03-12 04:04
文章标签 测量 halcon 专栏 圆弧

本文主要是介绍Halcon测量专栏-圆弧测量,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.前言

1.1什么是圆弧

圆上任意两点间的部分叫做圆弧。由于圆弧有正反的特性,即为有顺时针方向和逆时针方向,在确定圆弧时,也需要确定圆弧的方向。

1.2halcon实现方式

针对圆弧的问题。1:它与圆是相似的,都具备中心坐标和半径,还有起始和终点角度;2:定义一个圆弧方向,以顺时针为测量方向。

2.halcon程序

2.1halcon程序


read_image (Image, 'D:/1NewWork/work/2.26/.png')get_image_size (Image, Width, Height)
*获得圆上初始采样点
row:=[296,949,2046]
column:=[2555,3063,1192]
********************************拟合弧形采样ROI*****************
gen_contour_polygon_xld (Contour, row, column)
fit_circle_contour_xld (Contour, 'algebraic', -1, 0, 0, 3, 2, Row, Column, Radius, StartPhi, EndPhi, PointOrder)
gen_circle_contour_xld (ContCircle, Row, Column, Radius, EndPhi,StartPhi,  'positive', 1)
*gen_circle_contour_xld (ContCircle, Row, Column, Radius, 1,EndPhi,  'positive', 1)
dev_display (Image)
dev_display (ContCircle)
row1:=[]
column1:=[]
gen_empty_obj (EmptyObject)
gen_empty_obj (EmptyObject2)phi:=3.14*2-StartPhituple_abs (StartPhi-EndPhi+3.14*2, Abs)
tuple_ceil (Abs/3.1415926*90, Ceil)
**********************************弧形采样*********************
for Index := 0to Ceil-1 by 1tuple_sin(phi+rad(Index*2),Sin)tuple_cos(phi+rad(Index*2),Cos)*创建测量矩形gen_measure_rectangle2 (Row+Radius*Sin, Column+Radius*Cos, -Index*3.1415926/180*2-phi, 50, 5, Width, Height, 'nearest_neighbor', MeasureHandle)*绘制测量矩形轮廓用于显示gen_rectangle2_contour_xld (Rectangle,Row+Radius*Sin, Column+Radius*Cos, -Index*3.1415926/180*2-phi, 50, 5)*开启测量measure_pos (Image, MeasureHandle, 2, 20, 'all', 'last', RowEdge, ColumnEdge, Amplitude, Distance)*绘制测量结果gen_cross_contour_xld (Cross, RowEdge, ColumnEdge, 20, 1)concat_obj (Cross, EmptyObject, EmptyObject)concat_obj (EmptyObject2, Rectangle, EmptyObject2)row1:=[row1,RowEdge]column1:=[column1,ColumnEdge]
endforgen_contour_polygon_xld (Contour1, row1, column1)
*********************输出结果横纵坐标与半径,起始与结束的角度*****************
fit_circle_contour_xld (Contour1, 'algebraic', -1, 0, 0, 3, 2, Row2, Column2, Radius2, StartPhi2, EndPhi2, PointOrder2)
gen_circle_contour_xld (ContCircle2, Row2, Column2, Radius2,EndPhi2, StartPhi2,  'positive', 1)
dev_display (Image)
dev_display (ContCircle)
dev_display (EmptyObject2)
dev_display (EmptyObject)
dev_display (ContCircle2)

2.2halcon程序讲解

2.2.1读取图像和绘制ROI

read_image (Image, 'D:/1NewWork/work/2.26/.png')
get_image_size (Image, Width, Height)
*获得圆上初始采样点
row:=[296,949,2046]
column:=[2555,3063,1192]
********************************拟合弧形采样ROI*****************
gen_contour_polygon_xld (Contour, row, column)
fit_circle_contour_xld (Contour, 'algebraic', -1, 0, 0, 3, 2, Row, Column, Radius, StartPhi, EndPhi, PointOrder)

找圆弧与找圆是类似的,都需要一个基准的ROI区域,但是圆弧在于,它需要起始点和终点,中间点为圆心位置。根据3点绘制圆的方式,所以ROI选取,3个采样点即可

2.2.2拟合采样点,并绘制弧线ROI

gen_contour_polygon_xld (Contour, row, column)
fit_circle_contour_xld (Contour, 'algebraic', -1, 0, 0, 3, 2, Row, Column, Radius, StartPhi, EndPhi, PointOrder)
gen_circle_contour_xld (ContCircle, Row, Column, Radius, EndPhi,StartPhi,  'positive', 1)
*gen_circle_contour_xld (ContCircle, Row, Column, Radius, 1,EndPhi,  'positive', 1)
dev_display (Image)
dev_display (ContCircle)

通过选取的3点ROI拟合一个圆,获取到圆心坐标,半径,圆弧的起始和终点

2.2.3圆弧检测

row1:=[]
column1:=[]
gen_empty_obj (EmptyObject)
gen_empty_obj (EmptyObject2)phi:=3.14*2-StartPhituple_abs (StartPhi-EndPhi+3.14*2, Abs)
tuple_ceil (Abs/3.1415926*90, Ceil)
**********************************弧形采样*********************
for Index := 0to Ceil-1 by 1tuple_sin(phi+rad(Index*2),Sin)tuple_cos(phi+rad(Index*2),Cos)*创建测量矩形gen_measure_rectangle2 (Row+Radius*Sin, Column+Radius*Cos, -Index*3.1415926/180*2-phi, 50, 5, Width, Height, 'nearest_neighbor', MeasureHandle)*绘制测量矩形轮廓用于显示gen_rectangle2_contour_xld (Rectangle,Row+Radius*Sin, Column+Radius*Cos, -Index*3.1415926/180*2-phi, 50, 5)*开启测量measure_pos (Image, MeasureHandle, 2, 20, 'all', 'last', RowEdge, ColumnEdge, Amplitude, Distance)*绘制测量结果gen_cross_contour_xld (Cross, RowEdge, ColumnEdge, 20, 1)concat_obj (Cross, EmptyObject, EmptyObject)concat_obj (EmptyObject2, Rectangle, EmptyObject2)row1:=[row1,RowEdge]column1:=[column1,ColumnEdge]
endforgen_contour_polygon_xld (Contour1, row1, column1)
*********************输出结果横纵坐标与半径,起始与结束的角度*****************
fit_circle_contour_xld (Contour1, 'algebraic', -1, 0, 0, 3, 2, Row2, Column2, Radius2, StartPhi2, EndPhi2, PointOrder2)
gen_circle_contour_xld (ContCircle2, Row2, Column2, Radius2,EndPhi2, StartPhi2,  'positive', 1)
dev_display (Image)
dev_display (ContCircle)
dev_display (EmptyObject2)
dev_display (EmptyObject)
dev_display (ContCircle2)

根据定义的圆弧,以初始点为起始点,顺时针旋转,旋转指定角度,并使用测量矩形对每个采样区域进行采样,将所有采样点重新拟合为圆即可得到最终结果
在这里插入图片描述

2.2.4注意事项

尤为要注意圆弧是有方向的,文中预先定义圆弧方向为顺时针方向

3.C#程序工具实现

#region // 圆弧测量
public static bool ArcMeasure(HObject image,HTuple Row1,HTuple Column1,HTuple Row2,HTuple Column2,HTuple Row3,HTuple Column3, HTuple Sigma, HTuple Threshold,out HObject ConCircle,out HTuple CenterRow,out HTuple CenterColumn,out HTuple ResultR,out HTuple StartPhi,out HTuple EndPhi)
{HOperatorSet.GenEmptyObj(out ConCircle);CenterRow = -1;CenterColumn = -1;ResultR = -1;StartPhi = -1;EndPhi = -1;try{HOperatorSet.GetImageSize(image, out HTuple width, out HTuple height);HTuple Row = new HTuple(),Column=new HTuple();Row[0] = Row1; Row[1] = Row2; Row[2] = Row3;Column[0]= Column1; Column[1]= Column2; Column[2] = Column3;HOperatorSet.GenContourPolygonXld(out HObject  Contour, Row, Column);HOperatorSet.FitCircleContourXld(Contour, "algebraic", -1, 0, 0, 3, 2, out HTuple row,out HTuple column, out HTuple radius, out HTuple startPhi, out HTuple endPhi, out HTuple pointOrder);HTuple row1=new HTuple(),column1=new HTuple(),phi=0;HOperatorSet.GenEmptyObj(out HObject emptyObject);HOperatorSet.GenEmptyObj(out HObject emptyObject2);phi = Math.PI*2 - startPhi;HOperatorSet.TupleAbs(startPhi - endPhi+Math.PI*2, out HTuple abs);HOperatorSet.TupleCeil(abs / Math.PI * 90, out HTuple ceil);for (int i = 0; i < ceil-1; i++){HOperatorSet.TupleSin(phi + i * 2 * Math.PI / 180 , out HTuple sin);HOperatorSet.TupleCos(phi + i * 2 * Math.PI / 180 , out HTuple cos);HOperatorSet.GenMeasureRectangle2(row + radius * sin, column + radius * cos, ((((-i) * 3.1415926) / 180) * 2) - phi ,50, 5, width, height, new HTuple("nearest_neighbor"), out HTuple measureHandle);HOperatorSet.MeasurePos(image, measureHandle, 2, 20, new HTuple("all"), new HTuple("last"), out HTuple rowEdge,out HTuple columnEdge, out HTuple amplitude, out HTuple distance);row1 = row1.TupleConcat(rowEdge);column1 = column1.TupleConcat(columnEdge);}HOperatorSet.GenContourPolygonXld(out HObject contour, row1, column1);HOperatorSet.FitCircleContourXld(contour, new HTuple("algebraic"), -1, 0, 0, 3, 2, out CenterRow, out CenterColumn,out ResultR, out StartPhi, out EndPhi , out HTuple pointOrder2);HOperatorSet.TupleLength(CenterRow, out HTuple length);if (length == 0){return false;}HOperatorSet.GenCircleContourXld(out ConCircle, CenterRow, CenterColumn, ResultR, EndPhi, StartPhi, new HTuple("positive"), 1);return true;}catch (Exception){return false;}
}
#endregion
#region // 单点查找
/// <summary>
/// 单个点查找
/// </summary>
/// <param name="Image">输入图像</param>
/// <param name="Row1">输入直线起始横坐标</param>
/// <param name="Column1">输入直线起始列坐标</param>
/// <param name="Row2">输入直线终点横坐标</param>
/// <param name="Column2">输入直线终点列坐标</param>
/// <param name="MeasureWide">输入测量矩形宽度</param>
/// <param name="Sigma">输入测量矩形的高斯滤波值</param>
/// <param name="Thrashold">输入最小边缘对比度</param>
/// <param name="ResultRow">输出结果横坐标</param>
/// <param name="ResultColumn">输出结果列坐标</param>
/// <returns>拟合成功返回true,拟合失败返回false</returns>
static public bool PointMeasure_(HObject Image, HTuple Row1, HTuple Column1,HTuple Row2,HTuple Column2,HTuple MeasureWide, HTuple Sigma, HTuple Thrashold, out HTuple ResultRow, out HTuple ResultColumn)
{ResultRow = -1; ResultColumn = -1;try{HTuple hv_TmpCtrl_Row, hv_TmpCtrl_Column, hv_TmpCtrl_Dr, hv_TmpCtrl_Dc, hv_TmpCtrl_Phi,hv_TmpCtrl_Len1;HOperatorSet.GetImageSize(Image, out HTuple width, out HTuple height);hv_TmpCtrl_Row = 0.5 * (Row1 + Row2);hv_TmpCtrl_Column = 0.5 * (Column1 + Column2);hv_TmpCtrl_Dr = Row1 - Row2;hv_TmpCtrl_Dc = Column2 - Column1;hv_TmpCtrl_Phi = hv_TmpCtrl_Dr.TupleAtan2( hv_TmpCtrl_Dc);hv_TmpCtrl_Len1 = 0.5 * ((((hv_TmpCtrl_Dr * hv_TmpCtrl_Dr) + (hv_TmpCtrl_Dc * hv_TmpCtrl_Dc))).TupleSqrt());HOperatorSet.GenMeasureRectangle2(hv_TmpCtrl_Row, hv_TmpCtrl_Column, hv_TmpCtrl_Phi,hv_TmpCtrl_Len1, MeasureWide, width, height, "nearest_neighbor", out HTuple measureHandle);HOperatorSet.MeasurePos(Image, measureHandle, Sigma, Thrashold, new HTuple("all"), new HTuple("first"), out ResultRow,out ResultColumn, out HTuple amplitude, out HTuple distance);HOperatorSet.TupleLength(ResultRow, out HTuple length);if (length==0){return false;}return true;}catch (Exception){return false;}
}
#endregion

总结

弧形检测,与圆检测依旧类型,都是通过一定量的采样点去拟合出几何图形。

这篇关于Halcon测量专栏-圆弧测量的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/800082

相关文章

R语言统计分析——重复测量方差分析

参考资料:R语言实战【第2版】         所谓重复测量方差分析,即受试者被测量不止一次。本例使用数据集市co2数据集:因变量是二氧化碳吸收量(uptake),自变量是植物类型(Type)和七种水平的二氧化碳浓度(conc)。Type是组间因子,conc是组内因子。Type已经被存储为一个因子变量,还需要将conc转换为因子变量。分析过程如下: # 将conc变量转化为因子变量CO2$c

三维激光扫描点云配准外业棋盘的布设与棋盘坐标测量

文章目录 一、棋盘标定板准备二、棋盘标定板布设三、棋盘标定板坐标测量 一、棋盘标定板准备 三维激光扫描棋盘是用来校准和校正激光扫描仪的重要工具,主要用于提高扫描精度。棋盘标定板通常具有以下特点: 高对比度图案:通常是黑白相间的棋盘格,便于识别。已知尺寸:每个格子的尺寸是已知的,可以用于计算比例和调整。平面标定:帮助校准相机和激光扫描仪之间的位置关系。 使用方法 扫描棋盘:

【无线通信发展史⑧】测量地球质量?重力加速度g的测量?如何推导单摆周期公式?地球半径R是怎么测量出来的?

前言:用这几个问答形式来解读下我这个系列的来龙去脉。如果大家觉得本篇文章不水的话希望帮忙点赞收藏加关注,你们的鼓舞是我继续更新的动力。 我为什么会写这个系列呢? 首先肯定是因为我本身就是一名从业通信者,想着更加了解自己专业的知识,所以更想着从头开始了解通信的来源以及在每一个时代的发展进程。 为什么会从头开始写通信? 我最早是学习了中华上下五千年,应该说朝代史,这个算个人兴趣,从夏

欢迎大家关注我的【白话算法和数据结构】专栏

学习ACM也有一年半了,曾经对什么算法都不懂,现在对很多算法都有一定的了解,我们acm集训队都是学长学姐带学弟学妹,其实我们将的学弟学妹大部分都不能理解,当初我听杨大神讲课也是一样,听和没听一样,但是有学长告诉你有这个算法也是好的,只是你知道哦,原来这道题要用这道算法,我以前傻逼的暴力解决~~~然后他告诉你有这个算法,你自己去学,去网上搜资料学,所有人都是这么走过来的,但是网上能把算法将的跟白话一

Java专栏介绍

专栏导读 在当今这个技术飞速发展的时代,Java作为一门成熟且广泛应用的编程语言,一直是软件开发领域的中坚力量。本“Java技术”专栏旨在帮助读者深入理解Java编程语言的精髓,掌握其核心概念与高级特性,并通过实战案例提升编程技能。 专栏目录 一、Java入门知识与基本使用二、Java变量三、运算符四、控制结构五、数组、排序和查找六、面向对象编程(基础)七、面向对象编程(中级)八、面向对

X 射线测厚仪-高效精准,厚度测量的卓越之选

在现代工业的舞台上,对精准度和效率的追求从未停歇。而 X 射线测厚仪,宛如一颗璀璨的明星,以其高效精准的特质,成为厚度测量的卓越之选。 X 射线测厚仪,是科技与智慧的完美结晶。它凭借先进的 X 射线技术,如同一双透视万物的慧眼,能够轻松穿透各种材料,将厚度信息精准地呈现在人们面前。无论是坚硬的金属板材,还是柔软的塑料制品,亦或是富有弹性的橡胶制品,在它的审视下,厚度无处遁形。 高效,是它的另一

Flink全链路延迟的测量方式和实现原理

点击上方蓝色字体,选择“设为星标” 回复”面试“获取更多惊喜 本文已经加入「大数据成神之路PDF版」中提供下载。你可以关注公众号,后台回复:「PDF」 即可获取。 一、背景 Flink Job端到端延迟是一个重要的指标,用来衡量Flink任务的整体性能和响应延迟(大部分流式应用,要求低延迟特性)。 通过流处理引擎竞品对比,我们发现大部分流计算引擎产品,都在告警监控页面,集成了全链路时延指标

【渗透测试专栏】1.2认证和授权类-越权访问(水平/垂直越权)

该系列专栏旨在让漏洞检测变得更简单,只用于学习用途 靶机环境请看专栏前言专栏前言-WooYun漏洞库环境搭建-CSDN博客 目录 该系列专栏旨在让漏洞检测变得更简单,只用于学习用途 一、漏洞描述 1、水平越权 2、垂直越权 二、漏洞级别 三、漏洞检测方法 漏洞修复 一、漏洞描述 偏业务漏洞 1、水平越权 水平越权指的是在同一权限级别下,用户可以访问其他用户的资源或

将DIB/bitmap读入内存并转为 halcon hobject

问题由来:在mfc halcon混合编程中,发现halcon::readimage() 函数读取图片(8位8M/bmp)至少200ms,当然24位 32位bmp 倍数所消耗的时间倍数上涨。那么有没有什么方法加快读取速度?目前发现一个亲测可行的方式:  1、通过 DIBAPI 读取图片,下载可转到点击打开链接,赚点积分 2、获取所读读片的图像数据的首地址,注意非结构头地址 3、通过halcon

Halcon选择一堆region中面积第N大的region的算法实现

以下图为例: 比如我想把面积第2小的那个“小正方形”选择出来,算法代码如下: 1 read_image (Yuan, 'C:/Users/happy xia/Desktop/yuan.png')2 binary_threshold (Yuan, Region, 'max_separability', 'dark', UsedThreshold)3 connection (Regio