资讯动态

基于FFT频域滤波的塑料制品表面缺陷检测方法与Halcon实现

发布时间:2026/10/16 20:17:24 来源:尧图企业网站定制
做机器视觉这几年我越来越确信一件事很多看似“靠打光就能解决”的塑料件表面缺陷最终都卡在纹理背景和真实缺陷纠缠不清的问题上。带网纹的注塑盖、拉丝面的外壳、带防伪纹的瓶盖直接做阈值分割缺陷和花纹混在一起区域要么漏检要么过杀。后来在一次视觉培训的交流里接触了用快速傅里叶变换FFT处理这类塑料制品表面检测的思路豁然开朗——把图像从空间域变换到频率域之后周期性纹理和缺陷在频谱上的分离度远比想象中清晰。这篇文章就围绕这个主题把FFT在塑料制品表面缺陷检测中的原理、Halcon实现流程、参数调优思路和实际项目里的坑完整展开讲讲。无论你是刚入门视觉的新人还是已经在做工业检测项目的老手这套方法都值得在自己的算法库里备一份。1. 塑料制品检测难在哪里为什么我一开始就想到了FFT1.1 塑料表面缺陷的特性与成像规律塑料制品的外观缺陷种类很多划痕、凹坑、异物、气泡、缺料、烧焦、水口印、顶白……不同缺陷的成像特征差异很大。划痕通常是细长的低灰度线凹坑是边缘有轻微阴影的暗斑异物可能比背景亮也可能比背景暗气泡则是内部折射造成的局部亮点。最麻烦的是很多塑料产品表面本身带着“花纹”或“纹理”注塑模具在表面加工出的菱形网纹、梨花纹、拉丝纹。瓶盖或瓶身上的防伪条纹、刻度线、logo凸起。透明或半透明材料内部由工艺产生的周期性条纹。这些纹理是产品外观的一部分不能被当成缺陷删掉。算法要做的是在保留纹理的同时把叠加在纹理之上的缺陷分离出来。1.2 直接空间域分割为什么行不通很多工程师第一反应是图像预处理中值滤波去噪、直方图拉伸增强对比度、然后动态阈值或局部阈值分割。但实际效果往往不理想。原因是纹理和缺陷在空间域的灰度表现高度重叠——一个划痕落在网纹沟槽里的亮度和网纹沟槽本身的亮度差不了太多一个凹坑的阴影边缘和菱形格子的暗部边界几乎一样。你不管是调高还是调低阈值缺陷和纹理的像素总是互相粘连。我也试过用形态学顶帽变换做背景估计纹理周期如果比较均匀顶帽能压掉一部分但换一个纹理密度不同的产品结构元素尺寸就得重新调鲁棒性很差。说到底空间域的处理手段是基于“局部灰度差异”而塑料表面的纹理和缺陷之间缺乏稳定的灰度差异作为区分依据。1.3 从纹理到频谱FFT进场后来我转变思路不在灰度里找区别而在频率里找区别。傅里叶变换把一个空间信号拆成不同频率、不同方向的正弦波分量。反映到图像上就是均匀的背景和光照变化集中在低频区域周期性纹理表现为频谱上的一些亮斑峰值而缺陷因为不具有严格的周期性通常弥散在一个较宽的频率范围内。也就是说频率域里纹理的谱峰位置是相对固定、可以预测的而缺陷的频谱是相对宽带的。我们可以构造一个滤波器在频域里专门压掉那些纹理对应的谱峰保留其余成分再逆变换回空间域。这时候纹理被抑制了剩下的主要是缺陷信号和噪声后续分割就容易得多。这就是FFT做塑料制品表面缺陷检测的基本逻辑。2. 读懂频谱图塑料表面成像的频率特征2.1 一张塑料表面的典型频谱长什么样学习FFT检测之前先把读频谱图的基础打牢。Halcon里对一幅灰度图做正向FFT后得到的是一个复数图像我们不直接看复数通常取幅度谱能量谱的平方根或者对数后再显示。简单理解频谱图的中心代表低频直流分量和缓慢变化的亮度越往外围频率越高而频谱中亮点的方位角对应原图中纹理的方向。举个例子如果塑料表面是竖直方向的细拉丝纹原图在水平方向上的灰度变化非常剧烈对应到频谱上你会看到在水平方向也就是频谱的垂直轴方向距离中心一定距离的地方有一对对称的亮斑。原理是实信号的傅里叶变换具有共轭对称性所以频谱亮点基本是成对出现的。我见过不少新手看频谱图时一头雾水分不清“低频亮斑”和“纹理峰”。这里有个经验低频亮斑永远在图像中心附近且形状偏圆润代表整幅图的亮度基线纹理峰则通常离中心有一段明显距离具有方向性是尖锐的亮点或短线。不同纹理密度对应不同的峰位距离纹理越细密峰离中心越远。2.2 缺陷信号和纹理信号在频谱上的分布差异缺陷的种类不同频谱表现也不同大面积的凹坑和压伤低频成分增强在频谱中心附近表现为比周围稍亮的区域但不像纹理峰那么尖锐。细划痕因为划痕是细长结构频谱能量分布在其法线方向上呈一条穿过中心的亮带方向与原图划痕方向垂直。点状异物能量分布比较均匀属于宽带信号在频谱上看不出特别集中的峰只是整体噪声底抬高。周期性纹理则完全不一样它只集中在少数离散频率点上。所以频域滤波的核心操作就是找准纹理峰的坐标和尺寸压掉它同时尽量不动其余频带。2.3 用一块正弦条纹板验证频率分离思路理论学习再多不如动手做一个实验。我建议你用Halcon自己生成一幅带正弦条纹的仿真图在上面叠加一个模拟缺陷的小圆斑然后分别看它们的频谱。* 生成256x256的灰度图作为背景 gen_image_const (Background, byte, 256, 256, 128) * 做一个垂直方向的正弦条纹周期约8个像素 sin_texture : 128 50 * sin(2 * 3.14159 * (X / 8.0))实际上Halcon里可以用正弦函数直接生成条纹图也可以在第三方工具里生成仿真图再读入。之后分别对“纯条纹图”“条纹圆斑图”做FFT对比频谱。你会发现纯条纹图只有一对清晰的对称峰叠加上圆斑后中心区域和周围噪声底都有变化但条纹峰基本还在原位置。这个实验虽然简单但能帮你建立起一个重要直觉如果滤波器只挖掉峰附近的频率分量那么条纹会被抑制得干干净净而缺陷的大部分能量仍然保留。我对每个刚开始学FFT检测的工程师都推荐先做这个实验它比直接上手真实项目更能理解参数含义。3. Halcon里实现FFT缺陷检测的完整流程3.1 成像与图像预处理阶段FFT检测不是万能的前面的成像质量会直接决定效果。我的经验是先保证缺陷在图像中有灰度或边缘轮廓的可辨识度再谈FFT滤波。如果照明角度完全不对凹坑和划痕一点对比度都没有FFT也救不回来。预处理阶段需要注意几点转灰度彩色图像通常先用rgb1_to_gray转成单通道灰度图减少运算量。截取ROI不要对整个视野做FFT。相机视野里通常包含背景、载具和配件边缘这些结构在频谱中也是能量源会干扰滤波器设计。把产品区域裁剪出来最好只保留表面检测区域。旋转或校正如果产品定位角度不稳定纹理方向会发生旋转频谱峰的位置也随之旋转这会让固定滤波器失效。尽量在采集端保证产品朝向一致或者先做角度定位。尺寸适配这个非常关键。Halcon的rft_generic对图像尺寸有约束通常要求宽高分别为2、3、5的幂做乘积。实际工业图像不一定满足比如1280x1024这样很常见的尺寸就不适合直接丢进去。我的处理方式是先用zoom_image_factor缩放到1024x1024同时记录缩放比例最后把检测区域再映射回原图坐标或者使用crop_domain裁剪到目标尺寸。3.2 正变换rft_generic 与频谱可视化主流程的第一步是正向FFT。我用Halcon自带的快速实数傅里叶变换算子* 读取并预处理图像 read_image (Image, plastic_cap.png) rgb1_to_gray (Image, GrayImage) * 取出圆形ROI并缩放到合适尺寸 reduce_domain (GrayImage, CircleROI, ImageReduced) zoom_image_factor (ImageReduced, ImageZoomed, 1024 / Width, 1024 / Height, constant) * 正向快速傅里叶变换输出复数图像 rft_generic (ImageZoomed, ImageFFT, to_freq, none, complex, Width)这里说明一下rft_generic的参数含义to_freq表示正向变换none表示不做归一化complex表示结果为复数图像最后的Width填原图像的宽度。这里的Width需要填与ImageFFT匹配的宽度参数实际用的时候注意检查。为了看清楚频谱特征把复数谱转成可视化的幅度谱* 求复数图像的模得到幅度谱 energy_generic (ImageFFT, ImageEnergy, sqrt) * 取对数增强动态范围便于人眼观察 log_image (ImageEnergy, ImageLog, 1.0)log_image的做法是把幅度做一个对数拉伸否则中心低频太亮、周围细节根本看不见。看频谱图的目的不是为了最终交付而是用来确定滤波器参数这一步对调参很重要。3.3 构造频域滤波器凹口、带通、高通组合使用滤波器设计是整个流程的核心环节。Halcon提供了一系列生成频域滤波器的算子常用的有gen_gauss_filter高斯滤波器、gen_sin_bandpass正弦带通、gen_bandpass、gen_bandstop等。我习惯按缺陷类型把滤波器分成几类滤波器类型作用适用场景高通去掉低频抑制光照不均和整体灰度渐变有轻微明暗不均的注塑件低通去掉高频噪声过度放大噪声后平衡处理正弦带通提取特定频段信息需要保留某一尺寸范围的缺陷凹口/带阻精确挖掉纹理谱峰表面有周期网格、条纹的产品实际项目中我通常把高通和凹口组合起来用。比如先建立高通滤波器强调中高频细节再用凹口滤波器把纹理峰压掉。Halcon里没有直接的“凹口滤波器”算子但我可以用多个窄带带阻滤波器叠加实现或者更简单的方式用gen_gauss_filter生成高斯通过运算构造一个在特定频率为零的滤波图。我用得最多的组合方案* 生成高频增强滤波器sigma控制高通强度 gen_gauss_filter (HighPass, 0.2, 0.2, 0.0, rft, Width, Height) * 生成一个凹口带阻假设纹理峰在频谱坐标(fx, fy)处尺寸为r gen_bandstop (Notch, CenterFrequency1, CenterFrequency2, BandWidth, n, rft, Width, Height)Halcon中创建凹口滤波器还有一种直观办法先生成一个全通的滤波器图像值全为1然后以纹理峰坐标为圆心将一个小圆形区域的像素值设为0。这样就可以直接用图像像素操作构造滤波器最后convol_fft时作用于频谱。不过我强烈建议不要手动像素赋值因为要考虑频谱的对称性、边缘连续性、平滑过渡等问题手写容易引入振铃。用gen_bandstop或组合gen_std_bandpass更专业。3.4 逆变换与空域后处理频域滤波完成后做逆FFT回空间域* 频域滤波相当于频域乘法 convol_fft (ImageFFT, ImageFilter, ImageFiltered) * 逆傅里叶变换结果转成byte类型灰度图 rft_generic (ImageFiltered, ImageResult, from_freq, none, byte, Width)convol_fft在频域做卷积本质是频谱逐点相乘。逆变换后得到的ImageResult中周期性纹理已经被显著抑制缺陷保留了下来。此时再走一套常规的空域处理* 动态阈值或绝对值阈值提取缺陷候选 threshold (ImageResult, RegionDefect, 10, 255) * 形态学开运算去掉孤立噪点 opening_circle (RegionDefect, RegionOpened, 1.5) * 按面积和形状筛选真实缺陷 select_shape (RegionOpened, SelectedDefects, area, and, 20, 99999)这里有个细节逆变换结果里缺陷的极性和原图不一定一致。划痕可能表现为暗线也可能因为滤波响应变成亮线。如果只取灰度大于阈值的区域可能会漏掉暗缺陷。更好的做法是取绝对值或者对ImageResult做一次分水岭让正负响应都能被捕捉。我通常先看结果图的灰度分布再决定是用threshold还是dual_threshold。4. 参数调优实验一次塑料盖表面纹理检测的真实案例4.1 案例背景与初始效果讲一个实际做过的模拟项目X直径约30mm的白色塑料盖盖顶模具表面是45度斜向菱形网纹网纹周期大约0.8mm。要检测的缺陷是顶面的细小凹坑和划痕尺寸在0.2~1.0mm之间。检测节拍要求每件不超过1.2秒。刚开始用直接空间域方案低角度环形光照明中值滤波后做局部阈值。结果是凹坑的识别率只有65%左右网纹沟槽经常被误判为划痕误检率高达30%。这个效果客户当然不满意。后来改用FFT方案。首先采集标准OK样品的图像裁剪圆形盖顶区域缩放至1024x1024做正变换后观察频谱发现频谱在45度方向、距离中心大约70像素的位置各有一对很亮的峰这正是网纹对应的谱峰。另外在中心低频区域有不规则的能量堆积这是盖顶的轻度球面隆起造成的灰度渐变。4.2 调整截止频率与滤波器形状后的变化第一版滤波器只用了简单高通gen_gauss_filter (HighPass, 0.05, 0.05, 0.0, rft, Width, Height)效果是低频亮度渐变被去掉了但网纹还在因为网纹并不是低频它处在中频段。逆变换后结果图里依然能看到明显的网纹轮廓阈值分割后全是密密麻麻的网纹边缘线缺陷被淹没在里面。这一步实验很有价值它提醒我不能只做一个宽带滤波器必须针对频谱峰的位置做精确抑制。于是我在高通基础上叠加了两个凹口带阻滤波器中心分别放在第一对峰和二次谐波峰的位置gen_bandstop (Notch1, 0.13, 0.13, 0.03, n, rft, Width, Height) gen_bandstop (Notch2, 0.26, 0.26, 0.03, n, rft, Width, Height)这里的0.13、0.26是归一化频率对应频谱峰位置0.03是带宽。带宽很关键调大了会把附近宽带缺陷的能量一起挖掉调小了又盖不住纹理峰。我第一版带宽给了0.05结果凹坑信号明显减弱后来逐步缩小到0.02~0.03才找到平衡点。4.3 加低通组合抑制光照不均第二个坑是高频噪声。逆变换后网纹是压掉了但高频颗粒噪声被高通滤波器放大阈值分割后出现大量小碎点。我本来想用面积筛选直接过滤但缺陷尺寸小的只有几十个像素和碎点很难区分。解决方式是在频域里加一个轻微的低通或者带通限制高通压低频凹口压特定纹理再叠加一个上限截止低通把超过缺陷极限频率的高频噪声砍掉。这一步其实就是在频域做一个“带通凹口”的组合把整个可用频段限制在0.02~0.4之间既保留目标尺寸的缺陷又不放大无意义的噪声。另外逆变换结果里的低频残留也会造成局部灰度漂移我用gauss_filter对结果图像做一次大sigma平滑作为背景估计然后从结果图中减去背景再做阈值。这相当于在空域二次补偿频域滤波不彻底的问题。4.4 最终方案与量化结果最终的Halcon检测流程是采集彩色图转灰度。圆形ROI裁剪 缩放到1024x1024。rft_generic正变换。构造高通双凹口上限低通的组合滤波器。convol_fft频域滤波。逆变换。空域背景减除 阈值分割 形态学筛选。把筛选出的缺陷区域映射回原图坐标叠加显示。在这个项目X上最终缺陷识别率从65%提升到91%误检率从30%压到4%左右单件处理时间约150ms加上通信和机构动作完全满足节拍要求。更重要的是算法对外部光照变化的鲁棒性明显变好不再像空域阈值方法那样动不动就要重新调参。5. 实际项目中绕不开的坑与对应处理方案5.1 尺寸限制与振铃效应前面提到的尺寸约束问题再强调一遍rft_generic对宽高有特定要求工业相机分辨率五花八门不是所有尺寸都能直接用。一个常见现象是没有调整尺寸就直接跑FFT算子报错或者结果图像边缘出现一圈明暗交替的振铃波纹。这往往是因为图像边界处的亮度跳变产生高频泄漏。两个有效应对手段缩放/裁剪到合法尺寸优先缩放到1024x1024或2048x2048注意缩放算法用constant减少插值带来的额外频谱分量。边界羽化对ROI边缘做一个高斯羽化或使用边缘渐变的mask让边缘亮度平滑过渡到背景能显著减少振铃。Halcon里可以用gauss_filter预处理ROI区域或者用paint_region把背景调成统一灰度。5.2 光照变化导致频谱漂移这是FFT方法最容易被“打死”在实际现场的一个原因。同一条产线上光源衰减、角度微变、环境光干扰都会让频谱图发生改变。我遇到过的情况是上午调试好的凹口位置到了下午频谱峰偏移了2~3个像素滤波效果就变差了。解决思路有两种动态更新滤波器周期性采集无缺陷样品实时计算频谱峰位置动态生成新的凹口滤波器写入到滤波器缓存中。频谱峰提取可以用Halcon的local_max在幅度谱上找峰值。尽量稳定成像用遮光罩、稳压光源、固定产品朝向。我个人经验是先把成像稳定性做到位再把算法的动态更新作为双保险。不要一上来就指望算法能自适应所有光照波动。5.3 滤波器设计过度拟合的风险调参时很容易陷入一个误区为了把当前这几十张图处理得很完美把滤波器设计得非常精细——挖了五个凹口、带宽调得极小、高通sigma调试到千分位。结果换一批产品或者模具磨损之后纹理周期稍微变了滤波器直接失效所有参数重新来一遍。我的建议是滤波器尽可能只用高通一两个主凹口上限低通凹口带宽宁可稍微大一点损失一点分辨率换鲁棒性。缺陷和纹理的差异如果本身不明显靠疯狂加凹口不如改善打光或改变照明角度频域滤波只是手段不是遮羞布。5.4 性能优化减少ROI范围与预生成滤波器在线检测对速度有要求尤其多相机工位。FFT本身是快速算法但一张2048x2048的灰度图正逆两次变换加滤波耗时还是会明显上升。优化经验排序如下先用ROI缩小处理面积没必要对整个视野做FFT只保留产品表面区域通常能减少一半以上的计算量。预先生成滤波器滤波器图像一旦确定就保存到变量甚至缓存文件里不要在每张图处理时重新生成。gen_gauss_filter、gen_bandstop这些生成算子也是要花时间的批量处理时差异很大。单次正变换复用如果一套光路下需要同时检测多个区域可以先对整个ROI做一次正变换然后对每个区域分别生成滤波器、分别滤波、分别逆变换避免重复FFT。降低图像分辨率如果缺陷最小尺寸远大于采集分辨率可以先把图缩到512x512再处理速度能快好几倍。不过这个要在缺陷可识别的前提下做。5.5 一个容易忽略的细节复数图像的内存开销FFT之后是复数图像每个像素由实部和虚部组成内存开销是灰度图的两倍以上。2048x2048的复数图像内存占用大约64MB甚至更多。如果现场同时跑多路相机、多线程处理内存会很快吃紧。建议处理完频谱及时清理中间变量或者用overwrite模式复用内存减少垃圾回收压力。6. 最后说点我的个人体会我在多个项目里用FFT处理塑料制品的纹理背景分离最大的感受是频谱分析最核心的价值不是直接给出缺陷而是让你更深刻地理解“图像里到底有什么成分”。很多空域方法调不出来的问题一旦把频谱画出来原因就一目了然——到底是光照渐变、周期性纹理、还是高频噪声三个问题在频谱上分得清清楚楚该滤哪个频带、留哪个频带心里有数。调试FFT滤波器时我习惯在Halcon的变量窗口里同时显示原图、频谱、滤波器、逆变换结果四张图每次改参数都盯着这四张图来回看而不是只看最后的检测区域。这样能很快建立起频域参数和空域效果之间的映射关系。如果你刚开始接触这套方法建议先拿Halcon自带的示例图像或自己采集的塑料样品多实验。等你掌握了对频谱峰的定位、凹口滤波器带宽的选择以及逆变换后阈值分割的处理节奏你会发现FFT并不是什么高深理论它只是一个非常趁手的工具能帮你解决一批过去觉得“打光搞不定、阈值调不动”的疑难杂症。这套思路同样可以推广到PCB板检测、纺织表面检测、金属拉丝面检测等场景一通百通。希望这篇分享能帮你打开新的思路。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑