Halcon 曲线追踪

Halcon 曲线追踪(边缘检测、xld分割、xld筛选、线段合并)

图片数据与程序

链接:https://pan.baidu.com/s/1feGOa0A7dvCeBjQivr6TvA
提取码:f2ws

原图

请添加图片描述

起点终点方向

请添加图片描述


* 1.加载图片 ***************************************************
dev_update_off ()
dev_close_window ()
read_image (Image, './die/die_01')
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_set_draw ('margin')
dev_set_colored (12)
dev_set_line_width (2)* 2.设置参数 **************************************************
* 线宽
WireWidths := [1.8, 0, 0, 8, 6, 1.7, 7.5]* 最短分割曲线长度
MinSegmentLength := 5
* 曲线搜索角度
AngleTolerance := rad(35)* 最小搜索半径
MinSearchRadius := 10
MinWireDeviation := 5* 判定曲线是否成功 -- 距离终点距离
AcceptanceRadius := 5
* 最短线长 
MinWireLength := 80* 3.循环处理图片 **************************************************
for Img := 1 to 7 by 1* 4.读取曲线参数 *************************************************** 读取文件(曲线起点坐标,搜索方向,终点坐标,搜索方向)try* 文件路径DataFilePath := './para/die_' + Img$'02' + '_params.tup'read_tuple (DataFilePath, Parameters)catch (Exception)continueendtry* 读取数据个数NPads := Parameters[0]* 曲线起点坐标StartPadRows := Parameters[1:NPads]StartPadCols := Parameters[NPads + 1:2 * NPads]* 搜索方向StartInitOrientation := Parameters[2 * NPads + 1:3 * NPads]* 读取曲线终点坐标EndPadRows := Parameters[3 * NPads + 1:4 * NPads]EndPadCols := Parameters[4 * NPads + 1:5 * NPads]* 读取搜索方向EndInitOrientation := Parameters[5 * NPads + 1:6 * NPads]* 曲线起点与搜索方向gen_cross_contour_xld (CrossStart, StartPadRows, StartPadCols, 6, 0.785398)start_row := StartPadRows - 30 * sin(StartInitOrientation)start_column := StartPadCols + 30 * cos(StartInitOrientation)gen_arrow_contour_xld (ArrowStart, StartPadRows, StartPadCols, start_row, start_column, 5, 5)* 曲线终点与搜索方向gen_cross_contour_xld (CrossEnd, EndPadRows, EndPadCols, 6, 0.785398)   end_row := EndPadRows - 30 * sin(EndInitOrientation)end_column := EndPadCols + 30 * cos(EndInitOrientation)gen_arrow_contour_xld (ArrowEnd, EndPadRows, EndPadCols, end_row, end_column, 5, 5)* 显示读取曲线参数read_image (Image, 'die/die_' + Img$'02')dev_display (Image)    dev_set_color ('red')dev_display (CrossEnd)dev_display (ArrowEnd)dev_set_color ('blue')dev_display (CrossStart)dev_display (ArrowStart)stop()* 初始化线gen_empty_obj (Wires)* 5.循环搜索曲线 **************************************************for Pad := 0 to |StartPadRows| - 1 by 1* 最大线段距离MaxDistSegment := 17 * WireWidths[Img - 1]* 6.正向搜索 *************************************************** 曲线追踪--正向搜索track_wire (Image, FwdWireSegments, StartPadRows[Pad], StartPadCols[Pad],\StartInitOrientation[Pad], EndPadRows[Pad], EndPadCols[Pad], \WireWidths[Img - 1], AngleTolerance, MinSegmentLength, MaxDistSegment)* 合并线段fuse_wire_segments (FwdWireSegments, Wire, \StartPadRows[Pad], StartPadCols[Pad], \EndPadRows[Pad], EndPadCols[Pad], \MinWireLength, MaxDistSegment, MinWireDeviation)* 计算与终点的距离distance_pc (Wire, EndPadRows[Pad], EndPadCols[Pad], DistanceMin, DistanceMax)if (DistanceMin > AcceptanceRadius)* 选择正向搜索 最后一段count_obj (FwdWireSegments, NXLDs)select_obj (FwdWireSegments, ObjectSelected, NXLDs)get_contour_xld (ObjectSelected, Row, Column)* 7.反向搜索 *************************************************** 曲线追踪-- 反向搜索track_wire (Image, BckWireSegments, EndPadRows[Pad], EndPadCols[Pad], \EndInitOrientation[Pad], StartPadRows[Pad], StartPadCols[Pad], \WireWidths[Img - 1], AngleTolerance, MinSegmentLength, MaxDistSegment)* 合并线段fuse_wire_segments (BckWireSegments, WireBck, \StartPadRows[Pad], StartPadCols[Pad],\EndPadRows[Pad], EndPadCols[Pad], \DistanceMin, MaxDistSegment, MinWireDeviation)count_obj (WireBck, WiresFound)if (WiresFound > 0)* 获取正向线段* 8.正反向距离判定-截取正向有效部分*************************************************** 计算正向与反向接续处distance_contours_xld (Wire, WireBck, ContourOut, 'point_to_segment')query_contour_attribs_xld (ContourOut, Attribs)get_contour_attrib_xld (ContourOut, 'distance', Distance)MinDistIdx := sort_index(Distance)[0]get_contour_xld (Wire, WireRow, WireCol)* 截取正向有效部分gen_contour_polygon_xld (WireFwdPart, WireRow[0:MinDistIdx], WireCol[0:MinDistIdx])* 9.正反向距离判定-截取反向有效部分 *************************************************** 获取反向线段坐标get_contour_xld (WireBck, WireBckRow, WireBckCol)* 计算距离distance_pp (WireBckRow, WireBckCol, \gen_tuple_const(|WireBckRow|,WireRow[MinDistIdx]), \gen_tuple_const(|WireBckCol|,WireCol[MinDistIdx]), DistancePP)MinDistBckIdx := sort_index(DistancePP)[0]* 截取反向有效部分gen_contour_polygon_xld (WireBckPart,\WireBckRow[MinDistBckIdx + 1:|WireBckRow| - 1],\WireBckCol[MinDistBckIdx + 1:|WireBckRow| - 1])* 合并正向与反向线段concat_obj (WireFwdPart, WireBckPart, WireSegments)else* 未找到逆向直线* 使用正向线段count_obj (FwdWireSegments, NSegments)Sequence := [1:NSegments]select_obj (FwdWireSegments, WireSegments, Sequence)endif* 10.合并正反线段 **************************************************length_xld (WireSegments, Length)* 合并正反线段union_adjacent_contours_xld (WireSegments, FusedSegments, max(Length), max(Length) / max([min(Length),1]), 'attr_keep')* 合并到曲线数组中smooth_contours_xld (FusedSegments, Wire, 11)concat_obj (Wires, Wire, Wires)else* 距离终点合格 合并到曲线数组中smooth_contours_xld (Wire, SmoothedContours1, 11)concat_obj (Wires, SmoothedContours1, Wires)endifendfor* 11.显示结果 **************************************************dev_display (Image)dev_set_color ('red')dev_display (Wires)if (Img < 7)disp_continue_message (WindowHandle, 'black', 'true')stop ()endif
endfor

搜索子函数

gen_empty_obj (Wire)
get_image_size (Image, Width, Height)
* Coordinates of the point at which to resume the tracking of the wire
StartPointRow := StartPadRows
StartPointCol := StartPadColsRefOrientation := StartInitOrientationSearchRadius := 30 * WireWidths
MinSearchRadius := 5 * WireWidths
* 距离退出
DistSegmentThreshold := min([SearchRadius / 3.0, MaxDistSegment])
while (1)* 起点与终点距离distance_pp (StartPointRow, StartPointCol, EndPadRows, EndPadCols, Distance)* 生成搜索区域gen_search_region (SearchRegion, StartPointRow, StartPointCol,\RefOrientation, min([SearchRadius, Distance]), AngleTolerance)reduce_domain (Image, SearchRegion, ImageReduced)NXLDs := 0HighThreshold := 1* 循环修改 HighThreshold 搜索线边缘while (NXLDs == 0 and HighThreshold >= 0.1)* 高斯搜索线边缘lines_gauss (ImageReduced, Lines, WireWidths / sqrt(3), 0.05, HighThreshold, 'dark', 'true', 'true', 'true')* 生成边缘线gen_polygons_xld (Lines, Polygons, 'ramer', 1)* 拆分边缘split_contours_xld (Polygons, Contours, 'polygon', 1, 5)* 长度筛选select_contours_xld (Contours, SelectedContours, 'contour_length', MinSegmentLength, max([Width,Height]) / 2.0, -0.5, 0.5)count_obj (SelectedContours, NXLDs)HighThreshold := 0.5 * HighThresholdendwhileif (NXLDs == 0)breakendif* 计算角度筛选范围 LowerLimit := [RefOrientation - AngleTolerance,\RefOrientation - AngleTolerance + rad(180),\RefOrientation - AngleTolerance - rad(180)]UpperLimit := [RefOrientation + AngleTolerance,\RefOrientation + AngleTolerance + rad(180),\RefOrientation + AngleTolerance - rad(180)]* 角度筛选select_shape_xld (SelectedContours, ObjectSelected,\['phi_points', 'phi_points', 'phi_points'], \'or', LowerLimit, UpperLimit)count_obj (ObjectSelected, NContours)if (NContours > 1)* 尝试链接线段union_collinear_wire_segments (ObjectSelected, UnionContours, 5, 0.5)count_obj (UnionContours, NUCont)* 计算与起点的距离DistMin := []for C := 1 to NUCont by 1select_obj (UnionContours, ObjectSelected1, C)distance_pc (ObjectSelected1, StartPointRow, StartPointCol, DistanceMin, DistanceMax)DistMin := [DistMin,DistanceMin]endfortuple_find (DistMin, min(DistMin), IndMin)* 线段距离超出设置范围if (DistMin[IndMin[0]] > DistSegmentThreshold)breakendifselect_obj (UnionContours, WireSegment, IndMin[0] + 1)elseif (NContours == 0)breakelse* 只有一个线段copy_obj (ObjectSelected, WireSegment, 1, 1)endifconcat_obj (Wire, WireSegment, Wire)* 更新起点与终点update_search_parameters (WireSegment, StartPointRow, StartPointCol, RefOrientation, MinSearchRadius, MaxDistSegment, \StartPointRow, StartPointCol, RefOrientation, SearchRadius, DistSegmentThreshold)* 确认起点与终点 是否退出V1 := [EndPadRows - StartPointRow, EndPadCols - StartPointCol]V1 := V1 / sqrt(sum(V1 * V1))V2 := [-sin(RefOrientation), cos(RefOrientation)]if (V1[0] * V2[0] + V1[1] * V2[1] < 0)breakendif
endwhile
return ()

结果图片

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/865393.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python处理异常用操作介绍

Python中的异常处理主要用于捕获和处理程序运行过程中出现的错误。 在编写Python程序时&#xff0c;我们经常会遇到各种错误&#xff0c;如语法错误、运行时错误等。为了确保程序的稳定性和健壮性&#xff0c;我们需要对可能出现的错误进行捕获和处理。本文将介绍Python中常用的…

[笔记] 卷积 - 02 滤波器在时域的等效形式

1.讨论 这里主要对时域和频域的卷积运算的特征做了讨论&#xff0c;特别是狄拉克函数的物理意义。 关于狄拉克函数&#xff0c;参考这个帖子&#xff1a;https://zhuanlan.zhihu.com/p/345809392 1.狄拉克函数提到的好函数的基本特征是能够快速衰减&#xff0c;对吧&#xf…

软件功能测试基础知识大揭秘,功能测试报告就找专业软件测评机构

软件功能测试是以软件产品的需求规格为基础&#xff0c;通过对软件功能的逐个测试&#xff0c;验证软件是否符合需求规格&#xff0c;是否能够正常执行各项功能操作。对于软件产品而言&#xff0c;功能测试是一项至关重要的工作&#xff0c;它能够发现软件中存在的功能缺陷、错…

多微信运营管理方案

微信作为一款社交通讯软件&#xff0c;已经成为人们日常生活中不可缺少的工具。不仅个人&#xff0c;很多企业都用微信来联系客户、维护客户和营销&#xff0c;这自然而然就会有很多微信账号、手机也多&#xff0c;那管理起来就会带来很多的不便&#xff0c;而多微信私域管理系…

softmax从零开始实现

softmax从零开始实现 代码结果 代码 import numpy as np import torch import torchvision import torchvision.transforms as transforms from torch.utils import data# H,W,C -> C,H,W mnist_train torchvision.datasets.FashionMNIST(root"./data", trainTr…

java静态代理-被代理对象,代理对象的概念(图+代码解释)

案例是老师类&#xff0c;这个老师生病请假了&#xff0c;需要请另外一个老师临时帮忙&#xff0c;这个过来帮忙的老师就是代理对象&#xff0c;生病的老师就是被代理对象&#xff0c;其中我们需要代理对象和被代理对象都implement这个ITeacherDao接口&#xff0c;实现里面的te…

8款你不一定知道的良心软件!

AI视频生成&#xff1a;小说文案智能分镜智能识别角色和场景批量Ai绘图自动配音添加音乐一键合成视频https://aitools.jurilu.com/我们使用一些流行的软件的时候&#xff0c;往往会忽略一些功能非常强大的软件&#xff0c;因为这些软件的众 多&#xff0c;都因为看不见而丢失&a…

udp发送数据如果超过1个mtu时,抓包所遇到的问题记录说明

最近在测试Syslog udp发送相关功能&#xff0c;测试环境是centos udp头部的数据长度是2个字节&#xff0c;最大传输长度理论上是65535&#xff0c;除去头部这些字节&#xff0c;可以大概的说是64k。 写了一个超过64k的数据(随便用了一个7w字节的buffer)发送demo&#xff0c;打…

从百数教学看产品设计:掌握显隐规则,打造极致用户体验

字段显隐规则允许通过一个控件&#xff08;如复选框、单选按钮或下拉菜单&#xff09;来控制其他控件&#xff08;如文本框、日期选择器等&#xff09;和标签页&#xff08;如表单的不同部分&#xff09;的显示或隐藏。 这种规则通常基于用户的选择或满足特定条件来触发&#…

龙迅 国产原装 低成本高性能转换器 Type-C with 2lane@8.1Gbps/lane 4K60

2.一般说明 LT8711UXE1是一款高性能的Type-C/DP1.2至HDMI2.0转换器&#xff0c;设计用于将USBType-C源或DP1.2源连接至HDMI2.0收发器。该LT8711UXE1集成了一个DP1.2兼容接收器&#xff0c;和一个HDMI2.0兼容发射器。此外&#xff0c;还包括用于CC通信的两个CC控制器&#xff0c…

红酒与建筑:品味历史与艺术的交汇

在时间的长河中&#xff0c;红酒与建筑都是人类智慧的结晶&#xff0c;它们各自承载着历史的厚重与艺术的韵味。当这两者交汇时&#xff0c;仿佛是一场穿越时空的对话&#xff0c;将我们带入一个既古老又现代、既深沉又温柔的世界。今天&#xff0c;就让我们一起走进这个奇妙的…

PMP报考条件是什么?很多人都没读懂...

最近正值8月份考试报名期&#xff0c;想计划考8月份考试的宝子可以准备起来了&#xff0c;下面是报名时间和考试安排 8月考试时间安排&#xff1a; &#x1f449;报名时间在7.9日—12日 &#x1f449;考试时间在8.31日&#xff08;周六&#xff09; 一、PMP报名条件是什么&am…

炎黄数智人:万科集团——智能催收专员‘崔筱盼’,引领财务管理数字化转型

在数字化时代的浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;技术的飞速发展正深刻改变着商业世界的面貌。万科集团&#xff0c;作为中国房地产行业的翘楚&#xff0c;一直致力于探索和实践最前沿的科技创新。此次&#xff0c;万科集团推出的数字员工“崔筱盼”&#…

十 .pfc,bus纹波分析与抑制方法

以apfc为例 在分析时用 uin 和 iin 表示输入电压和输入电流&#xff0c;uo 和 io&#xff0c;表示输出电压和输出电流&#xff0c;Uin 和 Iin 表示输入电压和输入电流的幅值&#xff0c;则输入电压和输入电流可以分别表示为&#xff1a; 从式&#xff08;3-3&#xff09;可以…

c->c++(二):class

本文主要探讨C类的相关知识。 构造和析构函数 构造函数(可多个)&#xff1a;对象产生时调用初始化class属性、分配class内部需要的动态内存 析构函数&#xff08;一个&#xff09;&#xff1a;对对象消亡时调用回收分配动态内存 C提供默认构造和析构,…

AI是在帮助开发者还是取代他们

目录 1.概述 1.1.AI助力开发者 1.2.AI对开发者的挑战 2.AI工具现状 2.1. GitHub Copilot 2.2. TabNine 2.3.小结 3.AI对开发者的影响 3.1.对开发者的影响 3.2.开发者需要掌握的新技能 3.3.在AI辅助的环境中保持竞争力的策略 4.AI开发的未来 5.总结 1.概述 生成式…

OA系统多少钱一套 用低代码开发OA系统需要多少钱

在数字化时代&#xff0c;企业对办公自动化(OA)系统的需求日益增长&#xff0c;以提高工作效率和优化管理流程。低代码开发平台以其快速开发和部署的能力&#xff0c;成为构建OA系统的热门选择。本文将介绍低代码开发OA系统的成本效益&#xff0c;并以白码低代码平台为例&#…

C# 类型转换之显式和隐式

文章目录 1、显式类型转换2. 隐式类型转换3. 示例4. 类型转换的注意事项5. 类型转换的应用示例总结 在C#编程中&#xff0c;类型转换是一个核心概念&#xff0c;它允许我们在程序中处理不同类型的数据。类型转换可以分为两大类&#xff1a;显式类型转换&#xff08;Explicit Ca…

如何对GD32 MCU进行加密?

GD32 MCU有哪些加密方法呢&#xff1f;大家在平时项目开发的过程中&#xff0c;最后都可能会面临如何对出厂产品的MCU代码进行加密&#xff0c;避免产品流向市场被别人读取复制。 下面为大家介绍GD32 MCU所支持的几种常用的加密方法&#xff1a; 首先GD32 MCU本身支持防硬开盖…

Q-Vision新功能发布 | CANReplay-enable发送

Q-Vision是一款网络分析与ECU测试工具软件&#xff0c;支持CAN&#xff08;FD&#xff09;、LIN、以太网、LVDS等车载网络标准&#xff0c;以及CCP/XCP/UDS/OBD等协议&#xff0c;并能导入DBC/LDF/ARXML/A2L/ODX等格式的数据库。 使用Q-Vision可实现对多种总线网络的在线记录、…