基于halcon的直线查找之卡尺
我这人比较懒得罗里吧嗦,基本都是直接说两点:why?how?
基于halcon的直线查找之卡尺
直线的检测在halcon中主要有两种方式:直线拟合和卡尺直线。这里分享卡尺方法,拟合请移步:直线拟合
直线卡尺
首先把整体思路列出来:
①CreateMetrologyModel创建一个测量句柄;
②AddMetrologyObjectLineMeasure添加一个线“Line”的模型;
③SetMetrologyObjectParam设置相关测量参数。比如:卡尺垂直于边的长度,卡尺的宽度,卡尺的个数,保留的卡尺个数,边缘最低对比度等;
④ApplyMetrologyModel开始找边;
⑤GetMetrologyObjectMeasures、GetMetrologyObjectResultContour将找到的边界结果显示,同时获得每个卡尺找到的点坐标。
是不是很简单?没错,就这么简单无脑。作为调包侠,是还是觉得用的算子有点多啊…感觉给别人用这么多函数有点low?那就自己再封一层壳吧,瞬间高大上了。
CTRL + CV时刻
直接copy拿去用吧
// 代码量有点冗杂,很多参数判断。起始作为底层供调用的方法,无需写这些判断,推荐判断安全性的问题应该交给上层调用者来保证,底层保证效率就行,避免上层判断,底层又判断,造成重复耗时。可以删掉,从CreateMetrologyModel开始。void FindLineCaliper(HObject ho_Image, HObject* ho_ResultContour, HObject* ho_MeasureContour,HTuple hv_Row1, HTuple hv_Column1, HTuple hv_Row2, HTuple hv_Column2, HTuple hv_MeasureLength,HTuple hv_MeasureWidth, HTuple hv_MeasureSigma, HTuple hv_MeasureThreshold, HTuple hv_NumInstances,HTuple hv_MeasureSelect, HTuple hv_MeasureTransition, HTuple hv_NumMeasures,HTuple* hv_LineFind, HTuple* hv_RowStart, HTuple* hv_ColumnStart, HTuple* hv_RowEnd,HTuple* hv_ColumnEnd, HTuple* hv_RowFrame, HTuple* hv_ColumnFrame)
{HObject ho_MeasuredLines;HTuple hv_num_instances, hv_measure_select, hv_measure_transition;HTuple hv_num_measures, hv_ValueName, hv_Value, hv_Channels;HTuple hv_Width, hv_Height, hv_IsNumber, hv_Index, hv_Index1;HTuple hv_IsString, hv_NumMatches1, hv_NumMatches2, hv_IsString1;HTuple hv_NumMatches3, hv_NumMatches4, hv_MetrologyHandle;HTuple hv_IndexLine, hv_RowMeasure, hv_ColumnMeasure, hv_IndexSearch;HTuple hv_Frame_Parameter, hv_Index2, hv_NumMatches5, hv_NumMatches6;;//*********找直线函数**********//****输入参数:Image:输入图像, 需要单通道图像*****//****输入参数:Row1,Column1,Row2,Column2:找直线的参考基准线, 其位置与需要找的直线位置相同或近似平行*****//****输入参数:MeasureLength,MeasureWidth,MeasureSigma,MeasureThreshold:卡尺的长宽, Sigma值和阈值,支持数组输入*****//****输入参数:ParameterName,ParameterValue:检测控制参数名称和值, 具体请见下表*****//****输入参数: NumInstances: 检测的直线数量,必须为正整数***//****输入参数: NumMeasures: 检测的卡尺数量*****//****输入参数:MeasureTransition:找线的方式, 由暗到明, 由明到暗,只能是'positive'或'negative'*****//****输入参数:MeasureSelect: 每个卡尺内找到的点是最近点还是最远点, 只能是'first'或'last'*****//****输出参数:LineFind: 0:无法找到直线;1:可以找到直线*****//****输出参数:RowStart,ColumnStart,RowEnd,ColumnEnd:找到的直线起点与终点的坐标*****//****输出参数:ResultContour:生成的直线图形*****//****输出参数:MeasureContour:生成的卡尺图形*****//****输出参数:RowFrame,ColumnFrame:每个卡尺找到的点的坐标*****//****函数作者:*****//****更新时间:*****//******************//****默认参数值*****//******************(*hv_LineFind) = 0;(*hv_RowStart) = 0;(*hv_ColumnStart) = 0;(*hv_RowEnd) = 0;(*hv_ColumnEnd) = 0;(*hv_RowFrame) = HTuple();(*hv_ColumnFrame) = HTuple();hv_num_instances = 1;hv_measure_select = "last";hv_measure_transition = "positive";hv_num_measures = 40;hv_ValueName.Clear();hv_ValueName[0] = "num_instances";hv_ValueName[1] = "num_measures";hv_ValueName[2] = "measure_transition";hv_ValueName[3] = "measure_select";//****参数类型和范围确认*****//****int/real 型:['int',min,max], min=<输入值<=max,上下限若是无穷大,则写作'' *****//****string 型:['string','a','b',...,'z'],输入值需是'a','a','b',...,'z'中的任意一个值*****hv_Value.Clear();hv_Value[0] = "int";hv_Value[1] = 1;hv_Value[2] = "";hv_Value[3] = "int";hv_Value[4] = 1;hv_Value[5] = "";hv_Value[6] = "string";hv_Value[7] = "positive";hv_Value[8] = "negative";hv_Value[9] = "string";hv_Value[10] = "first";hv_Value[11] = "last";//*************************************//****1.判断输入参数是否满足计算要求*****//*************************************//****a.判断输入图像是否为单通道图像*****CountChannels(ho_Image, &hv_Channels);if (0 != (hv_Channels != 1)){Rgb1ToGray(ho_Image, &ho_Image);}GetImageSize(ho_Image, &hv_Width, &hv_Height);//****b.判断输入的直线参数是否为number,若出现非数字格式的输入情况,则直接返回*****TupleIsNumber((((((((hv_Row1.TupleConcat(hv_Column1)).TupleConcat(hv_Row2)).TupleConcat(hv_Column2)).TupleConcat(hv_MeasureLength)).TupleConcat(hv_MeasureWidth)).TupleConcat(hv_MeasureThreshold)).TupleConcat(hv_NumInstances)).TupleConcat(hv_NumMeasures),&hv_IsNumber);{HTuple end_val50 = (hv_IsNumber.TupleLength()) - 1;HTuple step_val50 = 1;for (hv_Index = 0; hv_Index.Continue(end_val50, step_val50); hv_Index += step_val50){if (0 != (HTuple(hv_IsNumber[hv_Index]) == 0)){return;}}}//****判断输入参数名称和数值的类型是否正确*****//****MeasureLeght≥1*****{HTuple end_val58 = (hv_MeasureLength.TupleLength()) - 1;HTuple step_val58 = 1;for (hv_Index1 = 0; hv_Index1.Continue(end_val58, step_val58); hv_Index1 += step_val58){if (0 != (HTuple(hv_MeasureLength[hv_Index1]) < 1)){hv_MeasureLength[hv_Index1] = 1;}}}//****MeasureWidth≥1*****{HTuple end_val65 = (hv_MeasureWidth.TupleLength()) - 1;HTuple step_val65 = 1;for (hv_Index1 = 0; hv_Index1.Continue(end_val65, step_val65); hv_Index1 += step_val65){if (0 != (HTuple(hv_MeasureWidth[hv_Index1]) < 1)){hv_MeasureWidth[hv_Index1] = 1;}}}//****MeasureSigma≥0.4*****{HTuple end_val72 = (hv_MeasureSigma.TupleLength()) - 1;HTuple step_val72 = 1;for (hv_Index1 = 0; hv_Index1.Continue(end_val72, step_val72); hv_Index1 += step_val72){if (0 != (HTuple(hv_MeasureSigma[hv_Index1]) < 0.4)){hv_MeasureSigma[hv_Index1] = 0.4;}}}//****MeasureThreshold≥1, MeasureThreshold≤255*****{HTuple end_val79 = (hv_MeasureThreshold.TupleLength()) - 1;HTuple step_val79 = 1;for (hv_Index1 = 0; hv_Index1.Continue(end_val79, step_val79); hv_Index1 += step_val79){if (0 != (HTuple(hv_MeasureThreshold[hv_Index1]) < 1)){hv_MeasureThreshold[hv_Index1] = 1;}if (0 != (HTuple(hv_MeasureThreshold[hv_Index1]) > 255)){hv_MeasureThreshold[hv_Index1] = 255;}}}//****NumInstances ≥1*****TupleInt(hv_NumInstances, &hv_num_instances);if (0 != (hv_num_instances < 1)){hv_num_instances = 1;}//****NumMeasures ≥1******TupleInt(hv_NumMeasures, &hv_num_measures);if (0 != (hv_num_measures < 1)){hv_num_measures = 1;}//****MeasureTransion: 'positive' or 'negative'*****TupleIsString(hv_MeasureTransition, &hv_IsString);if (0 != hv_IsString){TupleRegexpTest(hv_MeasureTransition, (HTuple("positive").Append("ignore_case")), &hv_NumMatches1);if (0 != (hv_NumMatches1 == 1)){hv_measure_transition = "positive";}TupleRegexpTest(hv_MeasureTransition, (HTuple("negative").Append("ignore_case")), &hv_NumMatches2);if (0 != (hv_NumMatches2 == 1)){hv_measure_transition = "negative";}TupleRegexpTest(hv_MeasureTransition, (HTuple("all").Append("ignore_case")), &hv_NumMatches3);if (0 != (hv_NumMatches3 == 1)){hv_measure_transition = "all";}}//****MeasureSelect: 'first' or 'last'*****TupleIsString(hv_MeasureSelect, &hv_IsString1);if (0 != hv_IsString1){TupleRegexpTest(hv_MeasureSelect, (HTuple("first").Append("ignore_case")), &hv_NumMatches4);if (0 != (hv_NumMatches4 == 1)){hv_measure_select = "first";}TupleRegexpTest(hv_MeasureSelect, (HTuple("last").Append("ignore_case")), &hv_NumMatches5);if (0 != (hv_NumMatches5 == 1)){hv_measure_select = "last";}TupleRegexpTest(hv_MeasureSelect, (HTuple("all").Append("ignore_case")), &hv_NumMatches6);if (0 != (hv_NumMatches6 == 1)){hv_measure_select = "all";}}//********************//****2.找直线函数*****//********************CreateMetrologyModel(&hv_MetrologyHandle);//****添加多个直线寻找---3/7*****//for Index3 := 0 to |MeasureLength|-1 by 1//for Index4 := 0 to |MeasureWidth|-1 by 1//for Index5 := 0 to |MeasureSigma|-1 by 1//for Index6 := 0 to |MeasureThreshold|-1 by 1//set_metrology_model_image_size (MetrologyHandle, Width, Height)//add_metrology_object_line_measure (MetrologyHandle, Row1, Column1, Row2, Column2, MeasureLength[Index3], MeasureWidth[Index4], MeasureSigma[Index5], MeasureThreshold[Index6], [], [], IndexLine)//endfor//endfor//endfor//endfor//add_metrology_object_line_measure (MetrologyHandle, Row1, Column1, Row2, Column2, MeasureLength, MeasureWidth, MeasureSigma, MeasureThreshold, [], [], Index)SetMetrologyModelImageSize(hv_MetrologyHandle, hv_Width, hv_Height);AddMetrologyObjectLineMeasure(hv_MetrologyHandle, hv_Row1, hv_Column1, hv_Row2,hv_Column2, hv_MeasureLength, hv_MeasureWidth, hv_MeasureSigma, hv_MeasureThreshold,HTuple(), HTuple(), &hv_IndexLine);SetMetrologyObjectParam(hv_MetrologyHandle, "all", "num_instances", hv_num_instances);SetMetrologyObjectParam(hv_MetrologyHandle, "all", "measure_select", hv_measure_select);SetMetrologyObjectParam(hv_MetrologyHandle, "all", "measure_transition", hv_measure_transition);SetMetrologyObjectParam(hv_MetrologyHandle, "all", "num_measures", hv_num_measures);ApplyMetrologyModel(ho_Image, hv_MetrologyHandle);if (0 != (hv_IndexLine > 0)){GetMetrologyObjectMeasures(&(*ho_MeasureContour), hv_MetrologyHandle, "all", "all", &hv_RowMeasure, &hv_ColumnMeasure);GetMetrologyObjectResultContour(&ho_MeasuredLines, hv_MetrologyHandle, "all", "all", 1.5);(*hv_LineFind) = 1;}else{(*hv_LineFind) = 0;}//**********************//****3.获取直线参数*****//**********************{HTuple end_val163 = hv_IndexLine;HTuple step_val163 = 1;for (hv_IndexSearch = 0; hv_IndexSearch.Continue(end_val163, step_val163); hv_IndexSearch += step_val163){GetMetrologyObjectResult(hv_MetrologyHandle, hv_IndexSearch, "all", "result_type", "all_param", &hv_Frame_Parameter);if (0 != ((hv_Frame_Parameter.TupleLength()) == (hv_num_instances * 4))){(*hv_LineFind) = 1;{HTuple end_val167 = ((hv_Frame_Parameter.TupleLength()) / 4) - 1;HTuple step_val167 = 1;for (hv_Index2 = 0; hv_Index2.Continue(end_val167, step_val167); hv_Index2 += step_val167){(*hv_RowStart)[hv_Index2] = HTuple(hv_Frame_Parameter[hv_Index2 * hv_num_instances]);(*hv_ColumnStart)[hv_Index2] = HTuple(hv_Frame_Parameter[(hv_Index2 * hv_num_instances) + 1]);(*hv_RowEnd)[hv_Index2] = HTuple(hv_Frame_Parameter[(hv_Index2 * hv_num_instances) + 2]);(*hv_ColumnEnd)[hv_Index2] = HTuple(hv_Frame_Parameter[(hv_Index2 * hv_num_instances) + 3]);}}}if (0 != (HTuple((*hv_LineFind) == 1).TupleOr(hv_IndexSearch == hv_IndexLine))){GetMetrologyObjectResultContour(&(*ho_ResultContour), hv_MetrologyHandle, hv_IndexSearch, "all", 1.5);GetMetrologyObjectMeasures(&(*ho_MeasureContour), hv_MetrologyHandle, hv_IndexSearch, "all", &(*hv_RowFrame), &(*hv_ColumnFrame));ClearMetrologyModel(hv_MetrologyHandle);break;}}}return;
}
注意
我还有更简洁的版本
基于halcon的直线查找之卡尺相关推荐
- Halcon自定义直线卡尺rake
拟合直线 rake工具 1. 为什么要开发rake工具 2. rake工具封装的三个函数 2.1 创建ROI的函数:draw_rake 2.2 边缘测量的函数:rake 2.3 拟合直线的函数:pts ...
- 基于halcon与c#联合的视觉处理软件
1.视觉软件 当我们拿到一个视觉项目,如果有一个拖拽式视觉软件去帮我们完成这样一个项目,既省时又省力,学什么halcon.opencv.visionpro,甚至头疼的C++.C#,统统不需要,也能快速 ...
- 【愚公系列】2023年04月 Halcon机器视觉-基于Halcon车牌识别
文章目录 前言 1.Halcon是什么 2.车牌识别 3.车牌识别系统 一.基于Halcon车牌识别 1.车牌识别的流程 二.车牌识别前预处理 三.开始车牌识别 四.识别车牌上面的中文 1.处理需要识 ...
- halcon拟合直线
halcon拟合直线 read_image (hImage, 'E:/vs2012/halcon卡尺例程/白光碗光效果4.bmp') get_image_pointer1(hImage, Pointe ...
- 递归二分法php,PHP基于二分法实现数组查找功能示例【循环与递归算法】
本文实例讲述了PHP基于二分法实现数组查找功能.分享给大家供大家参考,具体如下: 二分法.分别使用while循环的方法和递归调用的方法. // 二分法的使用数组必须是有序的,或升序,或降序 $arr ...
- 基于HALCON的模板匹配方法总结
很早就想总结一下前段时间学习HALCON的心得,但由于其他的事情总是抽不出时间.去年有过一段时间的集中学习,做了许多的练习和实验,并对基于HDevelop的形状匹配算法的参数优化进行了研究,写了一篇& ...
- 带你读AI论文:基于Transformer的直线段检测
摘要:本文提出了一种基于Transformer的端到端的线段检测模型.采用多尺度的Encoder/Decoder算法,可以得到比较准确的线端点坐标.作者直接用预测的线段端点和Ground truth的 ...
- halcon 差异模型 异物_基于HALCON的形状匹配算法的研究和心得总结
很早就想总结一下前段时间学习HALCON的心得,但由于其他的事情总是抽不出时间.去年有过一段时间的集中学习,做了许多的练习和实验,并对基于HDevelop的形状匹配算法的参数优化进行了研究,写了一篇& ...
- 查找(四)-------基于B树的查找和所谓的B树
关于B树,不想写太多了,因为花在基于树的查找上的时间已经特么有点多了,就简单写写算了,如果以后有需要,或者有时间,可以再深入写写 首先说一下,为什么要有B树,以及B树是什么,很多数据结构和算法的书上来 ...
最新文章
- python常用数据结构的常用操作
- qthread destroyed while thread is still running
- SQL Server 2005 在建立与服务器的连接时出错,错误26收藏
- Java 动作事件_java按钮动作事件
- 二、CSS知识总结(上篇)
- 知识蒸馏在推荐系统中的应用
- 抖音云控_抖音云控/快手云控:引领5G电商短视频新潮流
- 学习方向、当前要做的事
- SLF4J:Failed to load class org.slf4j.impl.StaticLoggerBinder
- 数据3分钟丨墨天轮2021年度数据库奖项及中国数据库魔力象限等多项成果发布...
- Ansible Tower - 使用入门 3 - 通过模板运行 Git 上的 Playbook 和 Role
- linux ssh端口是否打开,如何查看linux中的ssh端口开启状态
- form标签的action之前 加密_口令爆破之突破前端JS加密
- 为SSD加速 实战4KB对齐技巧1/3
- SVN客户端使用详细
- 饿了么微信小程序抓取
- Misra c规则简介
- java将小写的日期转换为大写的日期
- Linux操作系统笔记(基本命令+环境安装项目部署+Shell编程)
- 斑马打印机 android驱动,斑马ZC300驱动-斑马Zebra ZC300打印机驱动下载 v01.03.00官方版 - 51驱动网...