halcon视觉缺陷检测系列(2)频域和空间域转换的方法详解

简介: halcon视觉缺陷检测系列(2)频域和空间域转换的方法详解

理论基础


一、频率特征是图像的灰度变化特征,低频特征是灰度变化不明显,例如图像整体轮廓,高频特征是图像灰度变化剧烈,如图像边缘和噪声。一个重要的经验结论:低频代表图像整体轮廓,高频代表了图像噪声,中频代表图像边缘、纹理等细节。什么时候使用傅里叶变换进行频域分析?


具有一定纹理特征的图像,纹理可以理解为条纹,如布匹、木板、纸张等材质容易出现。

需要提取对比度低或者信噪比低的特征。

图像尺寸较大或者需要与大尺寸滤波器进行计算,此时转换至频域计算,具有速度优势。因为空间域滤波为卷积过程(加权求和),频域计算直接相乘。

二、在halcon中,使用频域进行检测,有两个步骤是比较关键的:


一个是生成合适的滤波器;

一个是空间域和频域之间的转换。

生成滤波器主要有如下算子:


gen_std_bandpass,

gen_sin_bandpass,

gen_gauss_filter,

gen_mean_filter,

gen_derivative_filter,

gen_bandpass,

gen_bandfilter,

gen_highpass,

gen_lowpass


空间域和频域之间的转换,主要有如下两个关键算子:


rft_generic


fft_generic


这两个算子的共同点:


这两个算子都是进行快速傅里叶变换的算子


这两个算子都可以进行空间域-》频域和频域-》空间域的变换,只需要针对参数Direction分别进行选择,'to_freq'是进行的是空间域-》频域的变换,'from_freq'是频域-》空间域的变换。


针对参数ResultType,如果是'to_freq',那么ResultType一般选择'complex';如果是'from_freq',ResultType一般选择'byte'(灰度图像)。


这两个算子的不同点:


rft_generic算子的输入图像是实值函数,fft_generic的输入图像是复数函数;从输出的结果来看,rft_generic只需要计算和存储了左半边的复数图像信息就可以了,因为右半边是共轭对称的。因此从最终的输出我们可以看到,只有左上和左下有DC成分。而fft_generic如果设定的是原点在左上角,那么就会在四个角上有DC成分。


fft_generic算子可以通过参数Mode设置原点的位置:如果设置的是'dc_edge',那么原点在左上角;如果设置的是'dc_center',那么就会将原点平移到中心位置。fft_generic算子一般会设置为'dc_center'。对于rft_generic算子,因为没有设置项,所以默认原点位置为左上角。


针对同一个图像,进行空间域-》频域、频域-》空间域的转换的时候,如果使用的是rft_generic算子,那么两个转换就都使用该算子;如果使用的是fft_generic算子,那么两个转换也都使用该算子,在对同一个图像进行空间域和频域的相互转换时,不要交叉使用这两个算子。


当然,从空间域到频域的转换,也可以使用算子fft_image,这个算子也是快速傅里叶变换,其实际效果相当于:


fft_generic(Image,ImageFFT,'to_freq',-1,'sqrt','dc_center','complex')



举例说明


1、检测布料表面划痕


image.png

*《Halcon机器视觉算法原理与编程实战》16-1
*清空当前窗口
dev_close_window ()
*读取测试图像
read_image (Image, 'data/cloth1')
*获取图像的宽
get_image_size (Image, Width, Height)
*创建显示窗口,并设置窗口及绘制参数
dev_open_window_fit_size (0, 0, Width, Height, -1, -1, WindowHandle)
dev_display (Image)
dev_set_draw ('margin')
dev_set_line_width (3)
dev_set_color ('red')
*创建一个高斯滤波器,用于将傅里叶转换后的图像进行滤波
gen_gauss_filter (GaussFilter, 3.0, 3.0, 0.0, 'none', 'rft', Width, Height)
*开始检测
*将测试图像转化为单通道的灰度图像
rgb1_to_gray (Image, ImageGray)
*对灰度图像进行颜色反转
invert_image (ImageGray, ImageInvert)
*对反转后的图像进行傅里叶变换
rft_generic (ImageInvert, ImageFFT, 'to_freq', 'none', 'complex', Width)
*对傅里叶图像做卷积,使用之前创建的高斯滤波器作为卷积核
convol_fft (ImageFFT, GaussFilter, ImageConvol)
*将卷积后的傅里叶图像还原为空间域图像。可见图像的突变部分得到了增强
rft_generic (ImageConvol, ImageFiltered, 'from_freq', 'n', 'real', Width)
*设置提取线条的参数
calculate_lines_gauss_parameters (17, [25,3], Sigma, Low, High)
*将图像中的有灰度差异的线条提取出来
lines_gauss (ImageFiltered, Lines, Sigma, Low, High, 'dark', 'true', 'gaussian', 'true')
*将提取出的结果显示出来
dev_display (Image)
dev_display (Lines)


2、傅里叶变换之划痕检测

image.png



*微信公众号--机器视觉那些事儿
*检测-FFT傅里叶变换之划痕检测
*对于检测表面是具有一定纹理的比如:布匹、皮革、塑料等,针对这一类表面的检测就不能单纯依靠帧差或者背景差来完成,
*这种情况下,通过将图像变换到频域进行处理,提取缺陷分量后反变换到时域,然后通过Blob分析获得缺陷的具体位置。
*重点说明:
*频域处理部分的过程为:
*1)先生成一个滤波器,此处生成的是正弦形状的带通滤波,使用的算子为gen_sin_bandpass。
*2)然后再进行图像的傅里叶变换,使用的算子为rft_generic,此处需要注意参数的使用。
*3)使用之前的滤波器,对图像在频域进行卷积计算,从而增强高频信息。
*4)最后对图像进行傅里叶反变换,使用的算子依然是rft_generic,注意和第二步中的参数进行区分。在这一步,即得到了我们平时进行Blob分析的图像。
*之后的处理分为三部分:
*1)第一部分,先进行Blob分析后,筛选掉一些杂点。然后提取出保留区域所对应的图像。
*2)第二部分进行亚像素处理,先提取出亚像素轮廓,使用的是lines_gauss算子;然后按照轮廓总长度进行轮廓筛选,从而得到划痕的亚像素轮廓。至此,已经得到划痕了。
*3)第三部分进行划痕区域的处理,先将亚像素轮廓转为区域,使用的算子是gen_region_contour_xld;得到划痕轮廓之后就可以将划痕标记出来了。
* 首先,创建合适的带通滤波
* 然后,输入图像在频域中进行傅里叶变换和滤波,以便增强高频信息
* 最后,再被转换回空间域,增强的缺陷通过形态学进行之后的处理
dev_update_off ()
dev_close_window ()
* 读图像
read_image (Image, '检测-FFT傅里叶变换之划痕检测.png')
*彩色转灰度图
count_channels (Image, Channels)
if (Channels == 3 or Channels == 4)
    rgb1_to_gray (Image, Image)
endif
* 翻转图像,亮变暗  暗变量
invert_image (Image, ImageInverted)
* 获取图像宽高
get_image_size (Image, Width, Height)
* dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_display (Image)
* 
* Optimize the speed of the fast fourier transform
* 优化快速傅里叶变换的速度
* Message := 'Optimize the speed of the fast fourier transform.'
* Message[1] := 'Please wait...'
* disp_message (WindowHandle, Message, 'window', 12, 12, 'black', 'true')
* optimize_rft_speed (Width, Height, 'standard')
* disp_continue_message (WindowHandle, 'black', 'true')
* stop ()
* 
* Enhance the scratches by filtering in the frequency domain
* 通过在频域中滤波来增强划痕
* 生成具有正弦形状的带通滤波器
gen_sin_bandpass (ImageBandpass, 0.4, 'none', 'rft', Width, Height)
* 对一幅图片的实部进行快速傅里叶变换的计算,将图像转为傅里叶图像
* 参数为'to_freq',输出图像为复数形式
* ImageInverted:输入的图片(输入图像需要为背景为暗,前景为亮的图像,一般需要先要将原始图像反转)
* ImageFFT:傅里叶变换后输出的图片
* 'to_freq':变换方向,傅里叶变换
* 'none':变换因子的规范
* 'complex':输出图片的数据类型,输出图像为复数形式
* Width: 图像的宽
rft_generic (ImageInverted, ImageFFT, 'to_freq', 'none', 'complex', Width)
* 对图片用滤波器在频域进行卷积运算
* ImageFFT: 输入的图片
* ImageBandpass:频域滤波器
* ImageConvol:计算后的输出图像
convol_fft (ImageFFT, ImageBandpass, ImageConvol)
* 对滤波后的图片进行傅里叶反变换
* 参数为'from_freq',输入图像为复数形式
rft_generic (ImageConvol, Lines, 'from_freq', 'n', 'byte', Width)
* 
* Segment the scratches by using morphology
* 使用形态分割划痕
* 二值化
threshold (Lines, Region, 5, 255)
* 获得连通域
connection (Region, ConnectedRegions)
* 特征直方图,按照面积特征选择区域
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 5, 5000)
* 膨胀
dilation_circle (SelectedRegions, RegionDilation, 5.5)
* 区域联合成一个区域
union1 (RegionDilation, RegionUnion)
* 抠图
reduce_domain (Image, RegionUnion, ImageReduced)
* 检测线条及其宽度
* 输出亚像素直线轮廓
lines_gauss (ImageReduced, LinesXLD, 0.8, 3, 5, 'dark', 'false', 'bar-shaped', 'false')
* 联合直线亚像素轮廓
union_collinear_contours_xld (LinesXLD, UnionContours, 40, 3, 3, 0.2, 'attr_keep')
* 按照轮廓的总长度来选择亚像素轮廓
select_shape_xld (UnionContours, SelectedXLD, 'contlength', 'and', 15, 1000)
* 由亚像素轮廓生成区域
gen_region_contour_xld (SelectedXLD, RegionXLD, 'filled')
* 区域联合
union1 (RegionXLD, RegionUnion)
* 膨胀
dilation_circle (RegionUnion, RegionScratches, 10.5)
* 
* Display the results
* 显示标记出来的的直线划痕
dev_set_draw ('margin')
dev_set_line_width (3)
dev_set_colored (12)
dev_display (Image)
dev_display (RegionScratches)


相关文章
|
4天前
|
编解码 自动驾驶 测试技术
【论文速递】PETR: 用于多视图 3D 对象检测的位置嵌入变换
【论文速递】PETR: 用于多视图 3D 对象检测的位置嵌入变换
|
8月前
|
机器学习/深度学习 传感器 算法
【交互式阈值二进制图像】采用彩色或单色图像通过交互/手动方式阈值单色图像或彩色图像的单个色带研究(Matlab代码实现)
【交互式阈值二进制图像】采用彩色或单色图像通过交互/手动方式阈值单色图像或彩色图像的单个色带研究(Matlab代码实现)
|
机器学习/深度学习
深度学习数据增强方法-内含(亮度增强,对比度增强,旋转图图像,翻转图像,仿射变化扩充图像,错切变化扩充图像,HSV数据增强)七种方式进行增强-每种扩充一张实现7倍扩)+ 图像缩放代码-批量
深度学习数据增强方法-内含(亮度增强,对比度增强,旋转图图像,翻转图像,仿射变化扩充图像,错切变化扩充图像,HSV数据增强)七种方式进行增强-每种扩充一张实现7倍扩)+ 图像缩放代码-批量
|
4天前
|
机器学习/深度学习 文字识别 算法
[Halcon&图像] 缺陷检测的一些思路、常规检测算法
[Halcon&图像] 缺陷检测的一些思路、常规检测算法
440 1
|
4天前
|
存储 算法 算法框架/工具
基于HSV色度空间的图像深度信息提取算法FPGA实现,包含testbench和MATLAB辅助验证程序
该文档介绍了在一个FPGA项目中使用HSV色彩模型提取图像深度信息的过程。通过将RGB图像转换为HSV,然后利用明度与深度的非线性映射估计深度。软件版本为Vivado 2019.2和MATLAB 2022a。算法在MATLAB中进行了对比测试,并在FPGA上实现了优化,包括流水线并行处理和查找表技术。提供的Verilog代码段展示了RGB到灰度的转换。实验结果和核心程序的图片未显示。
|
9月前
|
编解码 算法 数据可视化
【多重信号分类】超分辨率测向方法——依赖于将观测空间分解为噪声子空间和源/信号子空间的方法具有高分辨率(HR)并产生准确的估计(Matlab代码实现)
【多重信号分类】超分辨率测向方法——依赖于将观测空间分解为噪声子空间和源/信号子空间的方法具有高分辨率(HR)并产生准确的估计(Matlab代码实现)
|
8月前
|
机器学习/深度学习 传感器 算法
使用应用于环境振动数据的 SSI-COV 算法自动识别线状结构的模态参数附matlab代码
使用应用于环境振动数据的 SSI-COV 算法自动识别线状结构的模态参数附matlab代码
|
9月前
|
JSON 算法 数据格式
优化cv2.findContours()函数提取的目标边界点,使语义分割进行远监督辅助标注
可以看到cv2.findContours()函数可以将目标的所有边界点都进行导出来,但是他的点存在一个问题,太过密集,如果我们想将语义分割的结果重新导出成labelme格式的json文件进行修正时,这就会存在点太密集没有办法进行修改,这里展示一个示例:没有对导出的结果进行修正,在labelme中的效果图。
95 0
|
机器学习/深度学习 算法 测试技术
图像大面积缺失,也能逼真修复,新模型CM-GAN兼顾全局结构和纹理细节(1)
图像大面积缺失,也能逼真修复,新模型CM-GAN兼顾全局结构和纹理细节
149 0
|
编解码 数据可视化 UED
图像大面积缺失,也能逼真修复,新模型CM-GAN兼顾全局结构和纹理细节(2)
图像大面积缺失,也能逼真修复,新模型CM-GAN兼顾全局结构和纹理细节
231 0