一、Halcon 15种常用缺陷检测实例分享
缺陷检测是一种通过计算机视觉技术来检测产品制造过程中的缺陷的方法。该技术可以检测出产品表面的缺陷,如裂纹、凹陷、划痕、气泡等,并且可以实时监测和诊断制造过程中的问题。在制造业中,机器视觉缺陷检测技术已经被广泛应用于各种产品的质量控制和检测工作中,如电子产品、汽车零部件、医疗器械等。
1.背景网格产品刮伤缺陷检测
* 关闭窗口
dev_close_window ()
*关闭程序计数器,图形变量更新,窗口图形更新
dev_update_off ()
*设置图像路径
Path := 'lcd/mura_defects_blur_'
*读取一张图像
read_image (Image, Path + '01')
*获取图像大小
get_image_size (Image, Width, Height)
*创建一个新窗体
dev_open_window_fit_size (0, 0, Width, Height, 640, 480, WindowHandle)
*设置字体信息:字体大小为16,字体为mono,粗体,斜体
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
*设置区域的填充方式
dev_set_draw ('margin')
*设置线宽度
dev_set_line_width (3)
*设置输出对象的显示颜色
dev_set_color ('red')
ScaleFactor := 0.4
*获取lines_gauss算子Sigma, Low, High三个参数值
calculate_lines_gauss_parameters (17, [25,3], Sigma, Low, High)
for f := 1 to 3 by 1
*读取一张图像 1=>'01'
read_image (Image, Path + f$'.2i')
*获取彩色图像的R,G,B三分量
decompose3 (Image, R, G, B)
* *将图像转化为频域图像
rft_generic (B, ImageFFT, 'to_freq', 'none', 'complex', Width)
*生成一个高斯滤波核
gen_gauss_filter (ImageGauss, 100, 100, 0, 'n', 'rft', Width, Height)
*将频域图像核高斯滤波核进行卷积运算
convol_fft (ImageFFT, ImageGauss, ImageConvol)
*将卷积后的图像转换为空间域图像
rft_generic (ImageConvol, ImageFFT1, 'from_freq', 'none', 'byte', Width)
*用缺陷图像减去背景图像(时域图像)
sub_image (B, ImageFFT1, ImageSub, 2, 100)
* 对上述图像进行抽点,变焦
zoom_image_factor (ImageSub, ImageZoomed, ScaleFactor, ScaleFactor, 'constant')
*获取变焦后的图像的ROI
get_domain (ImageZoomed, Domain)
*图像ROI进行腐蚀操作
erosion_rectangle1 (Domain, RegionErosion, 7, 7)
*获取变焦图像中ROI区域内的图像
reduce_domain (ImageZoomed, RegionErosion, ImageReduced)
*探测线和获取线宽度
lines_gauss (ImageReduced, Lines, Sigma, Low, High, 'dark', 'true', 'gaussian', 'true')
*生成一个2D的齐次变换矩阵
hom_mat2d_identity (HomMat2DIdentity)
*添加一个缩放因子到齐次变换矩阵
hom_mat2d_scale_local (HomMat2DIdentity, 1 / ScaleFactor, 1 / ScaleFactor, HomMat2DScale)
*仿射变换
affine_trans_contour_xld (Lines, Defects, HomMat2DScale)
* 显示图像
dev_display (Image)
* 显示线缺陷
dev_display (Defects)
stop ()
endfor
2.不均匀表面刮伤检测
*关闭程序计数器,图形变量更新,窗口图形更新
dev_update_off ()
*关闭已打开的窗口
dev_close_window ()
************************************************第一步: 获取图像**************************************************
*读取图像
read_image (Image, 'image.png')
*获取图像大小
get_image_size (Image, Width, Height)
*打开一个新窗口
dev_open_window_fit_image (Image, 0, 0, Width, Width, WindowID)
*设置字体信息:字体大小为16,字体为mono,粗体,斜体
set_display_font (WindowID, 16, 'mono', 'true', 'false')
*设置区域的填充方式
dev_set_draw ('margin')
*设置线宽度
dev_set_line_width (4)
*显示图像
dev_display (Image)
************************************************第二步: 分割图像**************************************************
* 均值滤波,滤波核大小为7*7
mean_image (Image, ImageMean, 7, 7)
* 用局部阈值进行分割
dyn_threshold (Image, ImageMean, DarkPixels, 5, 'dark')
* 联通处理
connection (DarkPixels, ConnectedRegions)
* 输出对象的显示颜色的数目
dev_set_colored (12)
dev_display (Image)
dev_display (ConnectedRegions)
************************************************第三步: 处理区域**************************************************
* 过滤出缺陷区域
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 10, 1000)
dev_display (Image)
dev_display (SelectedRegions)
* 将SelectedRegions中的所有区域合并
union1 (SelectedRegions, RegionUnion)
* 对合并区域进行膨胀处理,其结构元素为圆形,半径为3.5
dilation_circle (RegionUnion, RegionDilation, 3.5)
dev_display (Image)
dev_display (RegionDilation)
Message := 'Region of the scratches after dilation'
* 对膨胀后的区域进行求骨架
skeleton (RegionDilation, Skeleton)
* 对获取的骨架区域进行连通处理
connection (Skeleton, Errors)
dev_set_colored (12)
dev_display (Image)
dev_display (Errors)
************************************************第三步: 获取大缺陷和小缺陷**************************************************
*过滤出大的缺陷
select_shape (Errors, Scratches, 'area', 'and', 50, 10000)
*过滤出小的缺陷
select_shape (Errors, Dots, 'area', 'and', 1, 50)
dev_display (Image)
dev_set_color ('red')
dev_display (Scratches)
dev_set_color ('blue')
dev_display (Dots)
3.产品表面三角缺陷检测
*读取一张图像
read_image (Image, '1.jpg')
*将RGB图像转化为灰度图
rgb1_to_gray (Image, GrayImage)
*使用自动阈值分割图像前景区域
binary_threshold (GrayImage, Region, 'max_separability', 'dark', UsedThreshold)
*将前景区域中图像剪切出来
reduce_domain (GrayImage, Region, ClipImage)
*均值滤波
mean_image (ClipImage, ImageMean, 200, 3)
*局部阈值,分割出前景
dyn_threshold (ClipImage, ImageMean, RegionDynThresh, 7, 'light')
*对分割的区域闭运算,填充间隙,平滑边界
closing_circle (RegionDynThresh, RegionClosing, 3.5)
*连通处理
connection (RegionClosing, ConnectedRegions)
*过滤出三角形区域
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 500, 2000)
*填充三角形内部区域
fill_up (SelectedRegions, RegionFillUp)
*将三角形区域转换为凸度
shape_trans (RegionFillUp, RegionTrans, 'convex')
*将区域转换为轮廓
gen_contour_region_xld (RegionTrans, Contours, 'border')
*显示图像
dev_display(GrayImage)
*显示三角形区域
dev_display(Contours)
* 检测毛刺
ImageFiles := []
ImageFiles[0] := './fin1.png'
ImageFiles[1] := './fin2.png'
ImageFiles[2] := './fin3.png'
for Index := 0 to |ImageFiles| - 1 by 1
read_image (Image, ImageFiles[Index])
binary_threshold (Image, Region, 'max_separability', 'light', UsedThreshold)
closing_circle (Region, RegionClosing, 203.5)
reduce_domain (Image, RegionClosing, ImageReduced)
reduce_domain (Image, Region, ImageReduced1)
*差分
difference (ImageReduced, ImageReduced1, RegionDifference)
opening_circle (RegionDifference, RegionOpening, 3)
dev_set_draw ('margin')
dev_set_line_width (5)
dev_display (Image)
dev_display (RegionOpening)
stop()
endfor
*关闭程序计数器,图形变量,窗口图形更新
dev_update_off()
* Image Acquisition 01: Code generated by Image Acquisition 01
ImageFiles := []
ImageFiles[0] := '1.bmp'
ImageFiles[1] := '2.bmp'
for Index := 0 to |ImageFiles| - 1 by 1
*读取一张图像
read_image (Image, ImageFiles[Index])
*分割出环形区域
threshold (Image, Region, 100, 255)
*对区域进行连通处理
connection (Region, ConnectedRegions)
*过滤出圆环区域
select_shape (ConnectedRegions, SelectedConnectedRegions, ['area','circularity'], 'and', [40000,0.6], [99999,1])
*将圆环区域中的图像剪切出来
reduce_domain (Image, SelectedConnectedRegions, ImageReduced)
*将图像和高斯导数进行卷积运算
derivate_gauss (ImageReduced, DerivGaussImage, 1.5, 'gradient')
*分割出图像中的轮廓
threshold (DerivGaussImage, DerivGaussRegion, 9, 50)
*对轮廓区域进行连通处理
connection (DerivGaussRegion, DerivGaussConnectedRegions)
*获取的轮廓区域
select_shape_std (DerivGaussConnectedRegions, SelectedDerivGaussConnectedRegions, 'max_area', 70)
*填充该轮廓区域
fill_up (SelectedDerivGaussConnectedRegions, RegionFillUp)
*求轮廓区域和填充的轮廓区域之间的补集区域
difference (RegionFillUp, SelectedDerivGaussConnectedRegions, RegionDifference)
*对补集区域进行连通处理
connection (RegionDifference, ResultConnectedRegions)
*获取缺陷区域
select_shape (ResultConnectedRegions, DefectResult, 'area', 'and', 50, 999)
*显示图像
dev_display (Image)
*显示缺陷区域
dev_display (DefectResult)
stop()
endfor
*读取一张图像
read_image (Image, '1.jpg')
*获取图像大小
get_image_size(Image, Width, Height)
*关闭已经打开的窗口
dev_close_window ()
*打开新窗口
dev_open_window(0, 0, Width, Height, 'black', WindowHandle) //打开指定大小的窗口
*对图像进行阈值操作
threshold (Image, Region, 0, 50)
*对区域进行连通处理
connection (Region, ConnectedRegions)
*过滤出产品的外轮廓区域
select_shape (ConnectedRegions, SelectedRegions, 'ra', 'and', 10, 200)
*对轮廓区域进行填充
fill_up (SelectedRegions, RegionFillUp)
*将区域转化为最小外接圆
shape_trans (SelectedRegions, RegionTrans, 'outer_circle')
*通过补集运算获取产品缺口区域
difference (RegionTrans, RegionFillUp, RegionDifference)
*对缺口区域进行腐蚀操作
erosion_circle (RegionDifference, RegionErosion, 1)
*把一个区域转变为一个二进制字节图像。
region_to_bin (RegionErosion, BinImage, 255, 0, 656, 492)
*对图像进行阈值操作
threshold (BinImage, Region1, 255, 255)
*对阈值区域连通处理
connection (Region1, ConnectedRegions1)
*设置输出对象显示颜色
dev_set_color('blue')
*过滤出想要的缺口区域
select_shape (ConnectedRegions1, SelectedRegions1, ['ra','rb'], 'and', [5,1], [10,5])
*统计出缺口的数目
count_obj (SelectedRegions1, Number)
*显示图像
dev_display (Image)
*显示缺陷区域
dev_display (SelectedRegions1)
7.电路板短路,断路检测
*读取图像
read_image (Image, 'pcb')
*关闭已经打开的窗口
dev_close_window ()
*获取图像大小
get_image_size (Image, Width, Height)
*打开新的窗口
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
*显示图像
dev_display (Image)
*执行灰度开运算
gray_opening_shape (Image, ImageOpening, 7, 7, 'octagon')
*执行灰度闭运算
gray_closing_shape (Image, ImageClosing, 7, 7, 'octagon')
*局部阈值操作,分割出电路断线
dyn_threshold (ImageOpening, ImageClosing, RegionDynThresh, 75, 'not_equal')
*显示图像
dev_display (Image)
*设置输出对象的显示颜色
dev_set_color ('red')
*设置区域的填充方式
dev_set_draw ('margin')
*显示电路断线区域
dev_display (RegionDynThresh)
8.找出所有网格顶点的位置
*读取一张图像
read_image (Image, '1.png')
*获取图像大小
get_image_size (Image, Width, Height)
*关闭已经打开的窗口
dev_close_window ()
*打开新窗口
dev_open_window (0, 0, Width/2, Height/2, 'black', WindowHandle)
*对图像均值滤波,滤波核大小3*3
mean_image(Image, ImageMean, 3, 3)
*对图像均值滤波,滤波核大小12*12
mean_image(Image, ImageMean2, 12, 12)
*通过局部阈值分割出网格区域
dyn_threshold(ImageMean, ImageMean2, RegionDynThresh, 5, 'dark')
*对网格区域进行连通处理
connection(RegionDynThresh, ConnectedRegions)
*过滤出网格区域
select_shape(ConnectedRegions, SelectedRegions, 'area', 'and', 150, 50000)
*开运算,获取网格竖线
opening_rectangle1(SelectedRegions, RegionOpening1, 1, 10)
*开运算,获取网格横线
opening_rectangle1(SelectedRegions, RegionOpening2, 10, 1)
*交集运算,获取横线和竖线的交点
intersection(RegionOpening1, RegionOpening2, RegionIntersection)
*对交点区域进行连通处理
connection(RegionIntersection, ConnectedRegions1)
*获取交点的坐标位置:行,列坐标
area_center (ConnectedRegions1, Area, Row, Column)
*显示图像
dev_display (Image)
*显示网格交点
dev_display (ConnectedRegions1)
9.化妆品标签褶皱检测
************************************************第一步: 程序初始化**************************************************
*关闭当前有打开的窗口
dev_close_window ()
*关闭程序计数器,图形变量,窗口图形更新
dev_update_off ()
*打开一个新窗口
dev_open_window (0, 0, 640, 512, 'black', WindowHandle)
*设置字体信息:字体大小为16,字体为mono,粗体,斜体
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
stop ()
************************************************第二步: 批量读取图像**************************************************
*批量读取4张图像到Images图形变量里
read_image (Images, './shampoo_label_0' + [1:4])
for I := 1 to 4 by 1
*从对象数组里选择对象元素
select_obj (Images, ObjectSelected, I)
*显示选择的图像
dev_display (ObjectSelected)
*延时0.5秒
wait_seconds (0.5)
endfor
************************************************第三步: 获取反照率和表面梯度**************************************************
* 物像里的光照方向
Tilts := [6.1,95.0,-176.1,-86.8]
* 光源和物体之间的角度
Slants := [41.4,42.6,41.7,40.9]
ResultType := ['gradient','albedo']
photometric_stereo (Images, HeightField, Gradient, Albedo, Slants, Tilts, ResultType, 'poisson', [], [])
* 显示反射图
dev_display (Albedo)
stop ()
* 使用梯度字段计算表面的高斯曲率,缺陷在曲率图像中通常易于检测
derivate_vector_field (Gradient, MeanCurvature, 1.0, 'mean_curvature')
************************************************第四步: 获取检测到的缺陷**************************************************
* 对曲率图像进行阈值
threshold (MeanCurvature, Region, -10, -0.07)
* 对区域进行开运算
opening_circle (Region, RegionOpening, 1)
* 对区域进行连通处理
connection (RegionOpening, ConnectedRegions)
* 将缺陷过滤出来
select_shape (ConnectedRegions, Defects, 'area', 'and', 50, 99999)
* 将区域转换为圆
shape_trans (Defects, Circle, 'outer_circle')
* 设置区域填充方式
dev_set_draw ('margin')
* 设置输出对象的显示颜色
dev_set_color ('red')
* 显示反射图
dev_display (Albedo)
* 显示缺陷
dev_display (Defects)
* 显示缺陷外圆
dev_display (Circle)
10.皮革纹理表面缺陷检测
* 关闭窗口
dev_close_window ()
*关闭程序计数器,图形变量,窗口图形更新
dev_update_off ()
*图像路径
Path := 'mura_defects_texture_'
*读取一张图像
read_image (Image, Path + '01')
*获取图像大小
get_image_size (Image, Width, Height)
*打开一个新窗口
dev_open_window (0, 0, 640, 480, 'black', WindowHandle)
*设置字体信息:字体大小为16,字体为mono,粗体,斜体
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')
*获取彩色图像的三个通道,R,G,B
decompose3 (Image, R, G, B)
*缺陷是暗斑。 因此,通过原始图像减去背景照明,从而使缺陷变得更加明显。
estimate_background_illumination (B, ImageFFT1)
*用缺陷图减去背景图
sub_image (B, ImageFFT1, ImageSub, 2, 100)
*中值滤波
median_image (ImageSub, ImageMedian, 'circle', 9, 'mirrored')
*提取分水岭盆地
watersheds_threshold (ImageMedian, Basins, 20)
*计算灰度共生矩阵的灰度值特性,暗斑的能量非常低
cooc_feature_image (Basins, ImageMedian, 6, 0, Energy, Correlation, Homogeneity, Contrast)
*Energy小于0.05,Mask为1,否则为0
Mask := Energy [<=] 0.05
select_mask_obj (Basins, Defects, Mask)
* 显示图像
dev_display (Image)
* 显示缺陷
dev_display (Defects)
stop()
endfor
11.手机摄像头图像表面的轻微缺陷检测
************************************************第一 窗口初始化****************************************************
*关闭已经打开的窗口
dev_close_window ()
*关闭程序计数器,图形变量更新,窗口图形更新
dev_update_off ()
*读取一张图像
read_image (Image,'2.bmp')
*获取图像大小
get_image_size (Image, Width, Height)
*打开新的窗口
dev_open_window (0, 0, 640, 480, 'black', WindowHandle)
*设置区域填充方式
dev_set_draw ('margin')
*设置线宽度
dev_set_line_width (2)
*设置输出对象显示颜色数目
dev_set_colored(12)
************************************************第二 图像预处理****************************************************
*优化FFT的速度
optimize_rft_speed (Width, Height, 'standard')
Sigma1 := 10.0
Sigma2 := 2.0
*构建高斯滤波器
gen_gauss_filter (GsFilter1, Sigma1, Sigma1, 0.0, 'none', 'rft', Width, Height)
*构建高斯滤波器
gen_gauss_filter (GsFilter2, Sigma2, Sigma2, 0.0, 'none', 'rft', Width, Height)
*两个滤波器相减
sub_image (GsFilter1, GsFilter2, Filter, 1, 0)
************************************************第三 开始处理图像****************************************************
* Image Acquisition 01: Code generated by Image Acquisition 01
ImageFiles := []
ImageFiles[0] := '1.bmp'
ImageFiles[1] := '2.bmp'
for Index := 0 to |ImageFiles| - 1 by 1
*读取一张图像
read_image (Image, ImageFiles[Index])
*将RGB彩色图转化为灰度图
rgb1_to_gray (Image, Image)
*对灰度图进行反选
invert_image(Image, ImageInvert)
*将图像转化为频域图像
rft_generic (ImageInvert, ImageFFT, 'to_freq', 'sqrt', 'complex', Width)
*将频域图像和滤波核进行卷积运算
convol_fft (ImageFFT, Filter, ImageConvol)
*将频域图像转化为空间域图像
rft_generic (ImageConvol, ImageFiltered, 'from_freq', 'n', 'real', Width)
*创建一个ROI
gen_rectangle1(Rectangle,30,25,450,610)
*将ROI区域的图像剪切
reduce_domain(ImageFiltered, Rectangle, ROI)
*中值滤波
median_image(ROI, ImageMedian, 'circle', 20, 'mirrored')
*使用高斯核进行图像平滑
smooth_image (ROI, ImageSmooth, 'gauss', 8)
*通过阈值分割出缺陷区域
threshold (ImageSmooth, Regions, -0.0016783, -0.0006434)
*对缺陷区域进行连通处理
connection(Regions, ConnectedRegions)
*对区域进行膨胀操作
dilation_circle (ConnectedRegions, RegionDilation, 5)
*过滤出指定面积大小的缺陷
select_shape (RegionDilation, SelectedRegions, 'area', 'and', 800, 99999)
*根据区域生成XLD轮廓
gen_contour_region_xld (SelectedRegions, Contours, 'border')
*将XLD拟合成圆
fit_circle_contour_xld (Contours, 'atukey', -1, 2, 0, 5, 2, Row, Column, Radius, StartPhi, EndPhi, PointOrder)
*生成一个圆对象
gen_circle_contour_xld (ContCircle, Row, Column, Radius+20, 0, 6.28318, 'positive', 1)
*显示图像
dev_display (Image)
*显示圆标记
dev_display(ContCircle)
stop()
endfor
12.网状产品表面破损检测
*关闭程序计数器,图形变量更新,窗口图形更新
dev_update_window ('off')
*读取一张图像
read_image (Image, 'plastic_mesh/plastic_mesh_01')
*关闭打开的窗口
dev_close_window ()
*获取图像大小
get_image_size (Image, Width, Height)
*创建一个新窗口
dev_open_window_fit_image (Image, 0, 0, Width, Height, WindowHandle)
*设置字体信息:字体大小为16,字体为mono,粗体,斜体
set_display_font (WindowHandle, 18, 'mono', 'true', 'false')
*设置区域的填充方式
dev_set_draw ('margin')
*设置线宽度
dev_set_line_width (3)
for J := 1 to 14 by 1
*读取一张图像
read_image (Image, 'plastic_mesh/plastic_mesh_' + J$'02')
*均值滤波
mean_image (Image, ImageMean, 49, 49)
*局部阈值分割图像
dyn_threshold (Image, ImageMean, RegionDynThresh, 5, 'dark')
*对分割后的区域进行连通处理
connection (RegionDynThresh, ConnectedRegions)
*过滤出缺陷网孔区域
select_shape (ConnectedRegions, ErrorRegions, 'area', 'and', 500, 99999)
*统计出缺陷网孔的数目
count_obj (ErrorRegions, NumErrors)
*显示图像
dev_display (Image)
*设置对象的显示颜色
dev_set_color ('red')
*显示缺陷网孔
dev_display (ErrorRegions)
if (NumErrors > 0)
*显示产品NG
disp_message (WindowHandle, 'Mesh not OK', 'window', 24, 12, 'black', 'true')
else
*显示产品OK
disp_message (WindowHandle, 'Mesh OK', 'window', 24, 12, 'black', 'true')
endif
stop()
endfor
13.铣刀刀口破损缺陷检测
*****************************************************************************第一 图像预处理********************************************************
*读取一张图像
read_image(Image,'1.bmp')
*对图像的灰度值在0到255范围内拉伸
scale_image_max (Image, ImageScaleMax)
*反选像素的位
bit_not (ImageScaleMax, ImageNot)
*生成一个椭圆元素
gen_disc_se (SE, 'byte', 45,45, 0)
*黑帽运算,分割比临近暗的区域
gray_bothat (ImageNot, SE, ImageBotHat)
*生成ROI1
gen_rectangle1 (ROI_0, 574.119, 268.867, 644.104, 337.728)
*生成ROI2
gen_rectangle1 (TMP_Region, 87.9029, 783.297, 179.989, 809.627)
*合并两个ROI
union2 (ROI_0, TMP_Region, ROI_0)
*生成ROI3
gen_rectangle1 (TMP_Region, 743.558, 937.222, 839.327, 997.981)
*合并ROI
union2 (ROI_0, TMP_Region, ROI_0)
*将合并ROI区域的图像剪切
reduce_domain (ImageBotHat, ROI_0, TemplateImage)
*设置区域填充方式
dev_set_draw ('margin')
*获取图像的数据,类型,高度,宽度
get_image_pointer1 (TemplateImage, Pointer, Type, Width, Height)
*显示图像
dev_display (TemplateImage)
*****************************************************************************第二 自动寻找最佳阈值********************************************************
* 最大方差初始化为0
MaxVariance := 0.0
* 最佳分割灰度阈值从1遍历到255,初始阈值的选取可以取图像平均灰度值
for ImgThreshold := 1 to 255 by 1
dev_display (TemplateImage)
* 前景区域分割
threshold (TemplateImage, Region, ImgThreshold, 255)
* 获得前景区域像素个数
area_center (Region, Area, Row, Column)
* 获得前景区域均值和方差
intensity (Region,TemplateImage, Mean, Deviation)
*对前景区域进行反选
complement (Region, RegionComplement)
*获取背景区域的面积和坐标
area_center (RegionComplement, Area1, Row1, Column1)
*获得背景区域像素个数、均值和方差
intensity (RegionComplement,TemplateImage, Mean1, Deviation1)
* 计算类间方差
Otsu := Area*1.0/[Width*Height]*Area1*1.0/[Width*Height]*pow(Mean-Mean1,2)
* 获取最大类间方差最佳阈值
if (Otsu>MaxVariance)
MaxVariance := Otsu
BestThreshold := ImgThreshold
endif
endfor
dev_display (TemplateImage)
dev_set_color ('green')
dev_set_draw ('fill')
stop ()
*****************************************************************************第三 分割缺陷目标********************************************************
* 阈值操作,选取高亮目标,即为缺陷
threshold (TemplateImage, Region1, BestThreshold, 255)
* 对缺陷区域进行连通处理
connection(Region1, ConnectedRegions)
* 根据面积过滤出大的缺陷
select_shape (ConnectedRegions, SelectedRegions1, 'area', 'and', 261.07, 1971)
* 填充缺陷内部间隙
fill_up(SelectedRegions1, RegionFillUp)
* 显示图像
dev_display(Image)
* 显示缺陷区域
dev_display(RegionFillUp)
stop()
******************************************第一步 初始化**************************************************
*读取一张图像
read_image (Hull, '1')
*获取图像大小
get_image_size (Hull, Width, Height)
*关闭已经打开的窗口
dev_close_window ()
*打开一个新的窗口
dev_open_window (0, 0, Width, Height, 'black', WindowID)
*显示图像
dev_display (Hull)
******************************************第二步 图像处理**************************************************
*阈值操作,分割出吸嘴
threshold (Hull, Dark, 0, 80)
*补集运算,获取背景区域
difference (Hull, Dark, Light)
*对背景区域进行连通处理
connection (Light, ConnectedRegions)
*过滤出背景区域
select_shape (ConnectedRegions, NoHullCand, 'area', 'and', 50000, 9999999)
*对过滤的背景区域进行闭运算,填充背景间隙和平滑背景边界
closing_circle (NoHullCand, NoHull, 13.5)
*补集运算,获取吸嘴区域
difference (Hull, NoHull, Region)
*对吸嘴区域开运算
opening_circle (Region, RegionOpening, 2.5)
*对吸嘴区域进行连通处理
connection (RegionOpening, ConnectedRegions)
*过滤出吸嘴区域
select_shape (ConnectedRegions, RegionHull, 'area', 'and', 5000, 9999999)
*将吸嘴区域转换为凸包区域
shape_trans (RegionHull, ConvexHull, 'convex')
*补集运算,获取吸嘴的缺口
difference (ConvexHull, RegionHull, Region)
*对吸嘴缺口区域进行连通处理
connection (Region, ConnectedRegions)
*过滤出吸嘴缺口
select_shape (ConnectedRegions, LargeHoles, 'area', 'and', 2000, 99999)
select_shape (LargeHoles, Holes, 'convexity', 'and', 0, 0.85)
*显示图像
dev_display (Hull)
*设置输出对象的线宽度
dev_set_line_width (5)
*设置区域的填充方式
dev_set_draw ('margin')
*设置输出对象显示颜色为红色
dev_set_color ('red')
*显示吸嘴缺口
dev_display (Holes)
*读入标准模板图片(图片名字为standard.bmp)
read_image (Image, './standard.bmp')
*设置图像窗口
get_image_size (Image, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
dev_display (Image)
*选中模板区域(ROI)
gen_rectangle1 (ROI_0, 201, 244, 385, 526)
reduce_domain (Image, ROI_0, ImageReduced)
*选中模板区域数字
threshold (ImageReduced, Regions, 106, 255)
connection (Regions, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 163.12, 10000)
union1 (SelectedRegions, RegionUnion)
*求模板区域坐标
area_center (RegionUnion, Areastandard, Rowstandard, Columnstandard)
*扣取模板区域图像,创建模板需要的是图像,不是区域
reduce_domain (ImageReduced, RegionUnion, ImageReduced1)
*创建模板
create_shape_model (ImageReduced1, 'auto', rad(0), rad(360), 'auto', 'auto', 'use_polarity', 'auto', 'auto', ModelID)
*读入图像路径,循环遍历每个图像
list_files ('./', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
for Index := 0 to |ImageFiles| - 1 by 1
read_image (Image, ImageFiles[Index])
*模板匹配
find_shape_model (Image, ModelID, 0, rad(360), 0.5, 1, 0.5, 'least_squares', 0, 0.9, Row, Column, Angle, Score)
*判断匹配是否成功
if (|Score| > 0)
*搜寻当前图像匹配成功的区域并求它的坐标和角度
dev_display_shape_matching_results (ModelID, 'red', Row, Column, Angle, 1, 1, 0)
*将模板区域仿射变换到匹配成功的区域
vector_angle_to_rigid (Rowstandard, Columnstandard, 0, Row, Column, Angle, HomMat2D)
affine_trans_region (RegionUnion, RegionAffineTrans, HomMat2D, 'nearest_neighbor')
dev_display (Image)
*blob方法提取当前图像的数字,并变成一个联通域
threshold (Image, Regions1, 106, 255)
connection (Regions1, ConnectedRegions1)
select_shape (ConnectedRegions1, SelectedRegions1, 'area', 'and', 163.12, 10000)
union1 (SelectedRegions1, RegionUnion1)
*仿射变换后的模板区域与当前区域求差集,即缺陷部分
difference (RegionAffineTrans, RegionUnion1, RegionDifference)
*开运算去除很小点的噪声
opening_circle (RegionDifference, RegionOpening, 3)
*求缺陷的面积
area_center (RegionOpening, Area, Row1, Column1)
*缺陷面积大于阈值,说明有缺陷
if(Area>100)
*设置缺陷区域的颜色
dev_set_color ('blue')
*显示缺陷区域
dev_display (RegionOpening)
*显示NG
set_display_font (WindowHandle, 50, 'mono', 'true', 'false')
disp_message (WindowHandle,'NG', 'window', 15, 40, 'yellow', 'false')
*缺陷面积小于阈值,说明没缺陷
else
*显示OK
set_display_font (WindowHandle, 50, 'mono', 'true', 'false')
disp_message (WindowHandle,'OK', 'window', 15, 40, 'green', 'false')
endif
*没有匹配到模板,直接NG
else
set_display_font (WindowHandle, 50, 'mono', 'true', 'false')
disp_message (WindowHandle,'NG', 'window', 15, 40, 'yellow', 'false')
endif
endfor
参考链接:机器视觉-缺陷检测