dev_close_window ()
dev_update_off ()
Path := 'lcd/mura_defects_texture_'
read_image (Image, Path + '01')
get_image_size (Image, Width, Height)
dev_open_window (0, 0, 640, 480, 'black', WindowHandle)
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
dev_set_draw ('margin')
dev_set_line_width (3)
dev_set_color ('red')
for f := 1 to 2 by 1
* 读图像
read_image (Image, Path + f$'.2i')
* 将RGB图像的R G B三个通道分别分出来为三个分量的图像
decompose3 (Image, R, G, B)
* defects are characterized by dark patches. Hence, by substracting the
* estimated background illumination from the original image the
* defects become more apparent
* 缺陷的特征是暗斑。 因此,通过从原始图像中减去估计的背景照明,缺陷变得更加明显
* 这个是自己定义的一个函数,使用F7快捷键,可以跳转到函数内部
estimate_background_illumination (B, ImageFFT1)
* 两个图像相减,
* 计算公式:g' := (g1 - g2) * Mult + Add
* 原图减去低通滤波后的图像,得到边缘明显的图像
sub_image (B, ImageFFT1, ImageSub, 2, 100)
* median filter smooths out the fine texture, simplifying the following
* segmentation and final detection of defects
* 中值滤波器可以平滑精细纹理,简化了以下分割和最终缺陷检测
* 中值滤波
median_image (ImageSub, ImageMedian, 'circle', 9, 'mirrored')
* 分水岭阈值分割
* 首先使用分水岭分割方法分离出多个区域,然后假设相邻区域内的最小值分别为B1、B2,分水岭的最小值为W。
* 当满足max{W-B1,W-B2} < Threshold时,合并为同个区域。
watersheds_threshold (ImageMedian, Basins, 20)
* dark patches corresponding to defects have a very low energy
* Energy:灰度值能量 (能量:是灰度共生矩阵各元素值的平方和,是对图像纹理的灰度变化稳定程度的度量,反应了图像灰度分布均匀程度和纹理粗细度。能量值大表明当前纹理是一种规则变化较为稳定的纹理)
* Correlation:灰度值的相关性 (能量:是灰度共生矩阵各元素值的平方和,是对图像纹理的灰度变化稳定程度的度量,反应了图像灰度分布均匀程度和纹理粗细度。能量值大表明当前纹理是一种规则变化较为稳定的纹理)
* Homogeneity:灰度值的局部同质性 (是图像包含信息量的随机性度量。当共生矩阵中所有值均相等或者像素值表现出最大的随机性时,熵最大;因此熵值表明了图像灰度分布的复杂程度,熵值越大,图像越复杂)
* Contrast:灰度值对比 (反差:又称为对比度,度量矩阵的值是如何分布和图像中局部变化的多少,反应了图像的清晰度和纹理的沟纹深浅。纹理的沟纹越深,反差越大,效果清晰;反之,对比值小,则沟纹浅,效果模糊)
cooc_feature_image (Basins, ImageMedian, 6, 0, Energy, Correlation, Homogeneity, Contrast)
* sgn:确认是1还是-1
* 分析能量,能量值越大,灰度分布越平稳,能量值越小,灰度变换大。然后得到能量数组中符合条件的索引
tuple_find (sgn(Energy - 0.05), -1, Indices)
* 通过索引值,选择对应的区域
select_obj (Basins, Defects, Indices + 1)
* 在原图上标记出mura缺陷
dev_display (Image)
dev_display (Defects)
* 计算缺陷的个数
count_obj (Defects, NDefects)
disp_message (WindowHandle, NDefects + ' \'mura\' defects detected', 'window', -1, -1, 'red', 'true')
if (f < 2)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
endif
endfor
estimate_background_illumination自定义函数内容:
* 获取图像宽高
get_image_size (Image, Width, Height)
* 对一幅图片的实部进行快速傅里叶变换的计算,将图像转为傅里叶图像
rft_generic (Image, ImageFFT, 'to_freq', 'none', 'complex', Width)
* 在频域中生成高斯低通滤波器
* Sigma1和Sigma2越大,建立的滤波器能通过更多的信息
* Sigma1和Sigma2越小,建立的滤波器将滤去更多的尖锐信息
gen_gauss_filter (ImageGauss, 50, 50, 0, 'n', 'rft', Width, Height)
* 对图片用滤波器在频域进行卷积运算,也就是使用高斯滤波器在频域内进行滤波处理
convol_fft (ImageFFT, ImageGauss, ImageConvol)
* 对滤波后的图片进行傅里叶反变换,得到空间域图像
rft_generic (ImageConvol, IlluminationImage, 'from_freq', 'none', 'byte', Width)
return ()
重点分析:
频域分析时,空间域到频域的转换,使用是rft_generic算子,因此,在生成高斯频域滤波器的时候,参数Mode选择的是’rft’。
生成高斯频域滤波器的算子gen_gauss_filter中,两个sigma的值,值越大,通过滤波器的信息将更多,值越小,滤波器将过滤掉更多的尖锐信息。
频域到空间域的转换之后,得到的是低通滤波之后的图像,通过sub_image算子,对原图的B分量图像和低通滤波之后的图像做减法,从而得到包括更多轮廓信息的图像。
为了最终得到mura缺陷,还需要对空间域图像进行如下三个步骤的处理:
median_image:中值滤波
watersheds_threshold:分水岭算法之后阈值分割
cooc_feature_image:通过灰度特征矩阵,得到纹理特征
最后通过分析纹理特征中的能量特征,得到mura缺陷。
执行流程: