Halcon学习笔记之缺陷检测(二)
例程:detect_indent_fft.hdev
说明:这个程序展示了如何利用快速傅里叶变换(FFT)对塑料制品的表面进行目标(缺陷)的检测,大致分为三步:
首先,我们用高斯滤波器构造一个合适的滤波器(将原图通过高斯滤波器滤波);
然后,将原图和构造的滤波器进行快速傅里叶变换;
最后,利用形态学算子将缺陷表示在滤波后的图片上(在缺陷上画圈)。
注:代码中绿色部分为个人理解和注释,其余为例程中原有代码
*Initialization(初始化)
dev_updata_off() //这一句包含如下三个算子:
//dev_updata_pc(‘off’) 关闭更新程序计数器
//dev_updata_var(‘off’) 关闭更新变量窗口
//dev_updata_window(‘off’) 关闭更新图像窗口(即通过命令来显示想要在图像窗口显示的图片)
dev_close_window() //关闭活动的图像窗口
read_image(Image,’plastics
/
plastics_01’) //载入图片
//参数说明:为读入图片命名(Image)
// 文件名(’plastics/plastics_01’)
get_image_size(Image,Width,height) //获取图片的长宽;
//参数说明:之前读入或生成的图片(Image)
// 图片的宽(Width)
// 图片的高(Height)
dev_open_window(0,0,Width,Height,’Black’,WindowHandle) //打开一个新的图像窗口
//参数说明:起始坐标(0,0)
// 大小(Width,Height)
// 背景颜色(’Black’)
// 窗口句柄(WindowHandle)
set_display_font (WindowHandle,14,’mono’,’ture’,’false’)//设置不依赖操作系统的字体
//参数说明:窗口句柄(WindowHandle)
// 字体大小(14)
// 字体类型(’mono’)
// 是否黑体(’ture’)
// 是否倾斜(’false’)
dev_set_draw(‘Margin’) //定义区域填充模式
//参数说明:填充模式(’Margin’或者’Fill’) dev_set_line_width(3) //设置输出区域轮廓线的线宽
//可以修改参数来看最后缺陷区域标示的区别
dev_set_color(’red’) //设置一种或者多种输出颜色
*
*Optimize the fft speed for the specific image size(根据指定图像大小进行fft速度最优化)
optimize_rft_speed(Width,Height,’standard’) //对指定大小的图片的fft速度进行优化
//参数说明:图片大小(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) //在频域生成两个高斯滤波器
//参数说明:生成的高斯滤波器(GaussFilter)
// 空域中高斯在主方向上的标准差(Sigma)
// 空域中高斯在正交于主方向的方向上的标准差(Sigma)
// 滤波器主方向的角度(0.0)
// 滤波器的规范(’none’)
// 直流项在频域的位置(’rft’)
// 图片的大小(Width,Height)
sub_image(GaussFilter1,GaussFilter2,Filter,1,0) //两图片相减(灰度)
//sub_image(ImageMinuend, ImageSubtrahend : ImageSub : Mult, Add : )
//g' := (g1 - g2) * Mult + Add
//以上为函数原型以及运算公式
*
*Process the images iteratively(对图像进行迭代运算)
NumImages := 11
For Index := 1 to NumImages by 1 //for循环从1到NumImages,步长为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)//对计算一幅图片实部进行快速傅里叶变换
//参数说明:输入的图片(Image)
// 傅里叶变换后输出的图片(ImageFFT)
// 变换方向(’to_freq’或’from_freq’)
// 变换因子的规范(’none’)
// 输出图片的数据类型(’complex’)
// 图片的宽(Width)
convol_fft(ImageFFT,Filter,ImageConvol) //对图片用一个滤波器在频域进行卷积运算
//参数说明:输入的图片(ImageFFT)
// 频域滤波器(Filter)
// 运算后输出的结果
rft_generic(ImageConcol,ImageFiltered,’from_freq’,’n’,’real’,Width) //对滤波后的图片进行傅里叶反变换
*
*Process the filtered image
gray_range_rect(ImageFiltered,ImageResult,10,10)//用一个矩形掩膜计算像素点的灰度范围
//参数说明:输入的图片(ImageFiltered)
// 输出的灰度范围图(ImageResult)
// 矩形掩膜大小(10,10)
min_max_rect(ImageResult,ImageResult,0,Min,Max,Range)//判断区域内灰度值的最大和最小值
//参数说明:待分析图片区域(ImageResult)
// 图片(ImageResult)
// 被去除的直方图两边像素点所
// 占总像素数的百分比(0)
// 得到的最小值最大值及灰度值范围(Min,Max,Range)
threshold(ImageResult,RegionDynThresh,max([5.55,Max*0.8]),255)//利用全局阈值对图像进行分割
//参数说明:输入的图片(ImageResult)
// 分割后得到的区域(RegionDynThresh)
// 阈值(max([5.55,Max*0.8]),255)
// 公式:MinGray <= g <= MaxGray
connection(RegionDynThresh,ConnectedRegions) //计算区域内的连通部分
//参数说明:输入的图片(RegionDynThresh)
// 得到的连通区域(ConnectedRegions)
select_shape (ConnectedRegions,SelectedRegions,’area’,’and’,4,99999)//根据指定的形态特征选择区域
//参数说明:输入的图片(ConnectedRegions)
// 满足条件的区域(SelectedRegions)
// 将要计算的形态特征(’area’)
// 独立特征间的连接关系(’and’)
// 特征的最小限制(4)
// 特征的最大限制(99999)
union1(SelectedRegions,RegionUnion) //返回包含所有区域的集合
//参数说明:包含所有区域的待计算区域的图片(tedRegions)
// 所有输入区域合(RegionUnion)
closeing_circle(RegionUnion,RegionClosing,10)//用一个圆圈来封闭一个区域
//参数说明:将要被封闭的区域(RegionUnion)
// 被封闭的区域(RegionClosing)
// 圆圈的半径(10)
connection(RegionClosing,ConnectedRegions1)
select_shape(ConnectedRegions1,SelectedRegions1,’area’,’and’,10,99999)
area_center(SelectedRegions1,Area,Row,Column) //计算区域的面积以及中心位置
//参数说明:待计算的区域(SelectedRegions1)
// 区域的面积(Area)
// 区域中心的行(Row)
// 区域中心的列(Column)
*
*Display the results
dev_display(Image) //显示原图
Number := |Area| //将区域面积赋给Number用于后面检查是否存在缺陷
if(Number)
gen_circle_contour_xld(ContCircle,Row,Column,gen_tuple_const(Number,30),gen_tuple_const(Number,0), gen_tuple_const(Number,rad(360)),’positive’,1)//构造一个与设定的圆弧或圆相一致的边界
//参数说明:生成的边界(ContCircle)
// 圆弧或圆的中心坐标(Row,Cloumn)
// 圆弧或圆的半径(gen_tuple_const(Number,30))
// 圆弧或圆的起始角度(gen_tuple_const(Number,0))
// 圆弧或圆的结束角度(gen_tuple_const(Number,rad(360)))
// 不明白是什么意思
// 相邻两点间的距离(1)
ResultMessage := [‘Not OK’,Number + ‘defect(s) found’]
Color := [‘red’,’black’]
dev_display(ContCircle)
else
ResultMessage := ‘OK’
Color := ‘forest green’
endif
disp_message(WindowHandle,ResultMessage,’window’,12,12,Color,’ture’)
if(Index#NumImages)
disp_continue_message(WindowHandle,’black’,’ture’)
stop()
endif
endfor
算法讲解:在实际的表面缺陷检测系统中,针对的检测表面很多是具有一定纹理的比如:布匹、皮革、塑料等,针对这一类表面的检测就不能单纯依靠帧差或者背景差来完成,因为背景的纹理不可能和当前图像的纹理完全相同。因此,本例程的算法通过将图像变换到频域进行处理,提取缺陷分量后反变换到时域,获得缺陷的具体位置。
高斯滤波器:在本算法中,在一开始就构造了两个高斯滤波器,高斯滤波器是一种线性平滑滤波器,适用于消除高斯噪声。滤波器的实质是对信号进行滤波,滤除不需要的部分,得到想要的部分。一个低通的滤波器可以滤除高频信号,对于图像来说,噪声和边缘往往集中在高频分量,因此低通能够降噪,但是也能造成图像的模糊。
本文关键:本文的关键就是使用两个低通滤波器,进行相减后构造了一个带阻滤波器来提取缺陷分量。这就需要保证在实际的待检测表面中缺陷所处的频率范围要和背景以及噪声有明显的差异,并且带阻的频率选择要合适。通过带阻滤波后获得的频率成分对背景中的纹理要有明显的抑制,并且突出缺陷成分,进行傅里叶反变换后重构的图像就是缺陷图像,经过简单的分割就能很容易得到缺陷了。
Halcon学习笔记之缺陷检测(二)的更多相关文章
- Halcon学习笔记之缺陷检测(一)
例程:surface_scratch.hdev 说明:这个程序利用局部阈值和形态学处理提取表面划痕 代码中绿色部分为个人理解和注释,其余为例程中原有代码 *surface_scratch.hdev:e ...
- Halcon学习笔记之支持向量机(二)
例程:classify_halogen_bulbs.hdev 在Halcon中模式匹配最成熟最常用的方式该署支持向量机了,在本例程中展示了使用支持向量机对卤素灯的质量检测方法.通过这个案例,相信大家可 ...
- OpenCV 学习笔记 07 目标检测与识别
目标检测与识别是计算机视觉中最常见的挑战之一.属于高级主题. 本章节将扩展目标检测的概念,首先探讨人脸识别技术,然后将该技术应用到显示生活中的各种目标检测. 1 目标检测与识别技术 为了与OpenCV ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十二章:几何着色器(The Geometry Shader)
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十二章:几何着色器(The Geometry Shader) 代码工 ...
- Java菜鸟学习笔记--数组篇(三):二维数组
定义 //1.二维数组的定义 //2.二维数组的内存空间 //3.不规则数组 package me.array; public class Array2Demo{ public static void ...
- JavaScript学习笔记之数组(二)
JavaScript学习笔记之数组(二) 1.['1','2','3'].map(parseInt) 输出什么,为什么? ['1','2','3'].map(parseInt)//[1,NaN,NaN ...
- vue2.0学习笔记之路由(二)路由嵌套+动画
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- vue2.0学习笔记之路由(二)路由嵌套
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第二十二章:四元数(QUATERNIONS)
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第二十二章:四元数(QUATERNIONS) 学习目标 回顾复数,以及 ...
随机推荐
- Smarty安装配置方法
下载最新的Smarty:http://smarty.php.net/ 解压后将目录中的libs目录重命名为smarty,复制到你的网站目录,同时在网站根目录下建立templates和templates ...
- Bootstrap 基本用法(续)
在bootstrap中有很多的组件,这些组件可以帮组我们更快的写出一些好看的样式,下面就是一些样式: 导航框: <ul class="nav nav-tabs"> &l ...
- 【CSS3】---盒模型margin、padding及border
盒模型--边框 盒子模型的边框就是围绕着内容及补白的线,这条线你可以设置它的粗细.样式和颜色(边框三个属性). 如下面代码为 div 来设置边框粗细为 2px.样式为实心的.颜色为红色的边框: div ...
- .NET DLL 保护措施详解(三)最终效果
针对.NET DLL 保护措施详解所述思路完成最终的实现,以下为程序包下载地址 下载 注意: 运行环境为.net4.0,需要安装VS2015 C++可发行组件包vc_redist.x86.exe.然后 ...
- Ionic Android开发环境搭建 上
首先,需要下载并安装Node.js. 什么是Node.js?百科上说:Node.js是一个基于Chrome JavaScript运行时建立的平台, 用于方便地搭建响应速度快.易于扩展的网络应用.Nod ...
- java 集合(list、set、map)的特点
集合相关的类有一大堆,一般也只用到常用的方法增删改查,而且它它们的方法名也基本一样,所以一直都不知道什么时候用什么集合, 今天趁有空特意从网上整理资料方便日后回忆. 一.List:.有顺序以线性方式存 ...
- 熔断器设计模式<转>
熔断器设计模式 如果大家有印象的话,尤其是夏天,如果家里用电负载过大,比如开了很多家用电器,就会”自动跳闸”,此时电路就会断开.在以前更古老的一种方式是”保险丝”,当负载过大,或者电路发生故障或异常时 ...
- 在window 下安装Memcache详解
有时候我们需要在本地测试的时候就用到memcahce,如果本地没有安装memcache,就会有下面的错误提示: 1234567 系统发生错误 您可以选择 [ 重试 ] [ 返回 ] 或者 [ 回到首页 ...
- C# 谈Dictionary<TKey,TValue>,SortedDictionary<TKey,TValue>排序
使用过Dictionary的人都知道,当每一个Add里面的值都不会改变其顺序,所以需要需要对其排序的时候就用到SortedDictionary, 但SortedDictionary并不是那么理想,其默 ...
- UI1_UIButton
// // AppDelegate.m // UI1_UIButton // // Created by zhangxueming on 15/6/30. // Copyright (c) 2015年 ...