失败笔记本--HALCON--002--202406

失败笔记本-HALCON篇-002

项目场景:

现在有一张图片如下:待检测图片
要用HALCON检测出图片左侧尺子的边(直线),中间工件的方孔(矩形),右侧两个工件的轮廓和位置(圆形和圆心)。这是在水下拍摄的一张图片,图片中背景很杂乱,干扰很多,光照也不足。这是一个比较复杂的工程,让我们先来问问ChatGPT有什么样的建议:

假设你是一个资深的HALCON工程师,现在你遇到了这样一个任务,需要你检测出一张水下图片中的尺子边缘(直线),工件方孔(矩形),空心圆工件边缘和位置(圆形大小和圆心位置)。但是这张图片的质量较差(相对于图像处理来说),背景很杂乱,干扰很多,光照也不足,工件上还有反光和光晕,你会怎么做呢?

要在质量较差、背景杂乱、干扰多、光照不足且有反光和光晕的水下图片中检测尺子边缘、方孔、空心圆工件的边缘和位置,需要综合运用HALCON的图像处理功能。以下是一个详细的步骤:
图像预处理:
去噪:使用高斯滤波、中值滤波等方法对图像进行平滑处理,减少噪声。
增强对比度:使用直方图均衡化或自适应对比度增强技术(如CLAHE)来改善图像对比度。
光照补偿:通过局部对比度增强或者使用背景减除的方法来均衡光照。
反光和光晕处理:
反射去除:可以通过多尺度Retinex算法或基于反射模型的算法来减少图像中的反光和光晕影响。
边缘检测:
边缘增强:使用Sobel、Canny等边缘检测算子来突出图像中的边缘。
阈值分割:自适应阈值或Otsu方法可以帮助分割出可能的目标边缘区域。
形状检测:
直线检测:使用Hough变换检测尺子的边缘直线。
矩形检测:通过区域增长或形态学操作(如闭运算)先提取潜在的方孔区域,然后使用最小外接矩形法检测矩形。
圆形检测:使用Hough圆变换检测空心圆工件的边缘和位置。
验证和细化:
形状匹配:基于几何模型匹配或者模板匹配方法来验证和细化检测结果。
排除错误检测:通过形状和尺寸约束来排除误检测。
步骤实现细节:
使用gauss_image或median_image函数进行平滑处理。
使用equalize_histogram或clahe函数进行对比度增强。
使用dyn_threshold或local_deviation函数进行光照补偿。
使用edges_sub_pix函数进行亚像素级别的边缘检测。
使用hough_lines和hough_circle函数进行直线和圆的检测。
使用select_shape函数基于形状特征(如面积、长宽比)筛选目标区域。
使用find_shape_model或find_shape_model_3d进行形状匹配和细化。

还给出了参考的代码:

read_image (Image, 'underwater_image.jpg')
* 图像预处理
gauss_image(Image, SmoothedImage, 3)
equalize_histogram(SmoothedImage, EnhancedImage)

* 反光和光晕处理
* 使用Retinex算法或其他方法处理反光问题(假设实现为 Retinex)

* 边缘检测
edges_sub_pix(EnhancedImage, Edges, 'canny', 1, 20, 40)

* 直线检测
lines_gauss (Edges, Lines, 1, 20, 40, 'light', 'false', 'true', 'false')

* 矩形检测
* 区域检测并形态学处理
threshold(EnhancedImage, Regions, 128, 255)
connection(Regions, ConnectedRegions)
select_shape(ConnectedRegions, Rectangles, 'rectangularity', 'and', 0.9, 1.0)

* 圆形检测
hough_circle(Edges, Circles, 10, 100)

* 结果显示和验证
dev_display(EnhancedImage)
dev_set_color('green')
dev_display(Lines)
dev_set_color('blue')
dev_display(Rectangles)
dev_set_color('red')
dev_display(Circles)

ok,ChatGPT给出了一个大致的思路,打开图片–过滤噪声–对比度增强–去除反射–边缘检测–形状识别。
让我们参考给出的示例程序来试一试:(我只能说这波GPT是错的)


1.图像预处理

分析:

在这一部分,我们要先打开图片,然后转换灰度,高斯滤波一番,进行图像的直方图均衡化处理。
使用以下代码:

rgb1_to_gray (Image, GrayImage)
gauss_image (GrayImage, ImageGauss, 3)
equalize_histogram(SmoothedImage, EnhancedImage)

出现问题:

  • 首先是gauss_image()算子报警告:
  • 其次居然出现了equalize_histogram()是未知算子的错误!

问题分析:

解决方案:

当然是把程序中使用错误的算子进行改正:

rgb1_to_gray (Image, GrayImage)
gauss_image (GrayImage, ImageGauss, 3)
equ_histo_image(ImageGauss, EnhancedImage)

进行了这三步操作后,图片效果如下:
预处理效果对比
观察效果:较暗的地方突出了,希望特征能够顺利提取出来。预处理这里还有可以尝试的手段:如使用 emphasize() 或者illuminate() 增强图像的高频区域(边缘和拐角),使图像看起来更清晰。


2.边缘检测

分析:

使用代码:

edges_sub_pix (EnhancedImage, Edges, 'canny', 1, 20, 40)

效果如下:
边缘检测canny效果
哎呀,感觉有戏啊。参数的调整后面再说,让我们先把流程做完。

3.直线检测

分析:

使用代码:

lines_gauss (Edges, Lines, 1, 20, 40, 'light', 'false', 'true', 'false')

出现问题:

ok,直接报错了啊,Image data management: wrong object-ID (HALCON错误代码: 4052)。

问题分析:

寻求大佬帮助,啊原来是因为算子的第一个参数是xld格式的,参考大佬回答:HALCON错误代码: 4052
查看lines_gauss()算子的介绍:halcon lines_gauss算子详解

Image (input_object) :输入图像
Lines (output_object) :检测线条(XLD)
Sigma (input_control) :高斯滤波值
Low (input_control) :滞后阈值分割的低阈值
High (input_control) :滞后阈值分割的高阈值
LightDark (input_control) :提取线条类型( ‘dark’,‘light’)
ExtractWidth (input_control) :是否提取线宽(‘false’,‘true’)
LineModel (input_control) :用来调整线条位置和宽度的线模型(‘bar-shaped’, ‘gaussian’, ‘none’, ‘parabolic’)
CompleteJunctions (input_control) :在断连的部分是否添加节点使线条连续(‘false’, ‘true’)

这样看来在上一步canny检测之后的输出结果是XLD轮廓,在Halcon中,使用XLD表示亚像素的轮廓和多边形。常用edges_sub_pix算子来提取亚像素轮廓(halcon中XLD的概念及算子应用)。

解决方案:

可以试着对XLD轮廓直接进行操作:

3.再次直线检测

分析:

矩形检测中没有使用xld轮廓,我们先进行矩形的检测试试看,使用代码:

threshold(EnhancedImage, Regions, 0, 143)
connection(Regions, ConnectedRegions)
select_shape(ConnectedRegions, Rectangles, 'rectangularity', 'and', 0.9, 1.0)

效果如下:
请添加图片描述
矩形检测及效果
好好好,突然把左侧尺子边缘测出来了,那么思路来了,如果能把上图右侧蓝色区域补起来,那么尺子两个边就都能检测到。

  • 我们先fill_up()一步,填充效果较差
  • 那就使用shape_trans(),强行将其补成矩形
  • 再用图片高度条件筛选
    代码如下:
connection(Regions, ConnectedRegions)
shape_trans (ConnectedRegions, RegionTrans, 'rectangle1')
select_shape(RegionTrans, Rectangles, 'height', 'and', Height, Height)

效果如下:
检测效果
但是这样的弊端很大,尺子的一部分被遮盖了起来,测出来的其实不是真实边缘:
请添加图片描述

4.圆形检测

这个直线检测是真难啊,暂时没有什么好的办法,我们先对俩圆进行检测:

  • 先提取ROI,参考Halcon图像预处理-感兴趣区域(ROI)
    我们使用 gen_rectangle1()算子和reduce_domain()算子对图片进行裁剪,只提取有圆形的区域。
  • 然后我们进行二值化;
  • 按照面积筛选;
  • 取最小外接圆。
    效果如下:
    圆形检测效果
    ok,看着非常不错。

5.矩形检测

ok,最后是矩形的检测,让我们复制检测圆形的思路:

  • 先提取ROI
  • 二值化
  • 填充后分离形状
  • 形状修正为内接矩形

出现问题:

咋就是说,其实问题很大,转化出来的内接矩形其实是不准的,识别的形状它很不规则,如下图所示:
识别到的矩形外框
救命啊,这个怎么能修正为正好合适的规则矩形呢,用外接矩形转换太大,内接矩形又太小。

6.输出结果显示在图片上

okk,最后我们把这俩圆的圆点坐标和半径求出来,标在图片上:

欧克,结果如下:
在图片中添加文字
注意:
很曲折好不好,添加点和线是在图片上添加的,先画了一个region然后添加在图片上,而添加文字是添加在窗口,用了外部算子,代码如下:(真心觉得这些操作没有OpenCV方便呢?)


gen_circle (Circle, Row, Column, 2)
paint_region (Circle, Image, ImageResult, [0, 255, 0], 'fill')
gen_region_line (RegionLines, Row-Radius, Column-Radius, Row+Radius, Column-Radius)
gen_region_line (RegionLines1, Row-Radius, Column+Radius, Row+Radius, Column+Radius)
paint_region (RegionLines, ImageResult, ImageResult1, [0, 255, 0], 'fill')
paint_region (RegionLines1, ImageResult1, ImageResult2, [0, 255, 0], 'fill')

font_name :='Courier'
font_size := 20

dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
dev_display (ImageResult2)

disp_message (WindowHandle, '半径:' + Radius +'\n圆心坐标:(' + Row +',' + Column +')' , 'image', Row+Radius, Column+Radius, 'green', 'false')

总结:

好好好,在002中,首先复习了001中的颜色反转操作,学到了HALCON中有region和XLD的区别,小东西花样还挺多。这个项目做的很差,练习时长两周半的我要再想想其他办法搞一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值