理论基础
具有一定纹理特征的图像,纹理可以理解为条纹,如布匹、木板、纸张等材质容易出现。
需要提取对比度低或者信噪比低的特征。
图像尺寸较大或者需要与大尺寸滤波器进行计算,此时转换至频域计算,具有速度优势。因为空间域滤波为卷积过程(加权求和),频域计算直接相乘。
一个是生成合适的滤波器;
一个是空间域和频域之间的转换。
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
举例说明

*《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、傅里叶变换之划痕检测

*微信公众号--机器视觉那些事儿
*检测-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)3、木板划痕检测

*http://www.ihalcon.com/read-13031-1.html
*缺陷检测,将木板的划痕提取出来
dev_update_off ()
dev_close_window ()
read_image (Image, '缺陷检测木板划痕提取.jpg')
*彩色转灰度图
count_channels (Image, Channels)
if (Channels == 3 or Channels == 4)
rgb1_to_gray (Image, Image)
endif
get_image_size (Image, Width, Height)
dev_open_window_fit_size (0, 0, Width, Height, -1, -1, WindowHandle)
dev_display (Image)
*傅里叶变换去背景
fft_generic (Image, ImageFFT, 'to_freq', -1, 'sqrt', 'dc_center', 'complex')
gen_rectangle2 (Rectangle1, 308.5, 176.56, rad(-0), 179.4, 7.725)
gen_rectangle2 (Rectangle2, 306.955, 175, rad(-90), 180.765, 4.68)
union2 (Rectangle1, Rectangle2, UnionRectangle)
paint_region (UnionRectangle, ImageFFT, ImageResult, 0, 'fill')
fft_generic (ImageResult, ImageFFT1, 'from_freq', 1, 'sqrt', 'dc_center', 'byte')
*提取划痕
threshold (ImageFFT1, Regions, 5, 240)
connection (Regions, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 20, 99999)
union1 (SelectedRegions, RegionUnion)
dilation_rectangle1 (RegionUnion, RegionDilation, 5, 5)
connection (RegionDilation, ConnectedRegions1)
select_shape (ConnectedRegions1, SelectedRegions1, ['width','height'], 'and', [30,15], [150,100])
dilation_rectangle1 (SelectedRegions1, RegionDilation1, 11, 11)
union1 (RegionDilation1, RegionUnion1)
skeleton (RegionUnion1, Skeleton)
*显示
dev_set_color ('red')
dev_display (Image)
dev_display (Skeleton)halcon官方自带的例子
detect_indent_fft.hdev * Optimize the fft speed for the specific image size optimize_rft_speed (Width, Height, 'standard') * * Construct a suitable filter by combining two gaussian * filters Sigma1 := 10.0 Sigma2 := 3.0 gen_gauss_filter (GaussFilter1, Sigma1, Sigma1, 0.0, 'none', 'rft', Width, Height) gen_gauss_filter (GaussFilter2, Sigma2, Sigma2, 0.0, 'none', 'rft', Width, Height) sub_image (GaussFilter1, GaussFilter2, Filter, 1, 0) * * Process the images iteratively NumImages := 11 for Index := 1 to NumImages by 1 * * Read an image and convert it to gray values read_image (Image, 'plastics/plastics_' + Index$'02') rgb1_to_gray (Image, Image) * Perform the convolution in the frequency domain rft_generic (Image, ImageFFT, 'to_freq', 'none', 'complex', Width) convol_fft (ImageFFT, Filter, ImageConvol) rft_generic (ImageConvol, ImageFiltered, 'from_freq', 'n', 'real', Width)
参考文献
微信公众号:机器视觉那些事儿
《Halcon机器视觉算法原理与编程实战》杨青
本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:



少有人走的路



















