机器视觉-2 缺陷检测常见场景与常用检测方法

目录

        根据背景和图像特征的不同,可以将主要缺陷检测场景分为三类:

单调背景图像:通常是指图像背景较为简单,颜色或亮度比较均匀。这种情况下,缺陷通常表现为与背景明显不同的区域。

b9128dcf739147d191edcba8928b2b0e.png

规则纹理背景:规则纹理背景指图像中具有重复的纹理或图案,缺陷表现为纹理中断或异常。

b0c70131d0dd4d419b6239c94ed87c8d.png

无规则图像背景:无规则图像指背景复杂多变,没有明显的规则或模式。在这种情况下,缺陷检测需要更加复杂的处理方法。

96c8063218544c0a8ed9a35f688c2ed7.png

每种背景类型的缺陷检测方法各有侧重。

二、缺陷检测常用方法

1. 单调背景

方法1: 阈值分割

阈值分割适用于背景单一且缺陷与背景有明显差异的情况。

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() {
    Mat src = imread("image_path");
    if(src.empty()) {
        cerr << "Image load failed!" << endl;
        return -1;
    }

    Mat gray, binary;
    cvtColor(src, gray, COLOR_BGR2GRAY);
    threshold(gray, binary, 128, 255, THRESH_BINARY);

    imshow("Binary Image", binary);
    waitKey(0);

    return 0;
}

方法2: 差分法

差分法可以通过对比待检测图像与参考图像(无缺陷图像)的差异来检测缺陷。

Mat diff;
absdiff(src, ref_image, diff); // ref_image 是无缺陷的参考图像
threshold(diff, diff, 50, 255, THRESH_BINARY);

2. 规则纹理背景

方法1: 模板匹配

模板匹配适合在规则纹理中寻找缺陷,尤其是在纹理中某一部分出现异常时。

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() {
    Mat src = imread("image_path");
    Mat templ = imread("template_path");

    Mat result;
    matchTemplate(src, templ, result, TM_CCOEFF_NORMED);
    threshold(result, result, 0.8, 1.0, THRESH_BINARY);

    imshow("Template Matching", result);
    waitKey(0);

    return 0;
}

方法2: Gabor滤波器

Gabor滤波器能够有效地检测图像中的特定频率和方向的纹理,可以用于检测规则纹理中的缺陷。

// --- Gabor 滤波器 ---
Mat applyGaborFilter(const Mat& image) {
    Mat gaborKernel = getGaborKernel(Size(21, 21), 5, CV_PI / 4, 10, 0.5, 0, CV_32F);
    Mat filteredImage;
    filter2D(image, filteredImage, CV_8UC3, gaborKernel);
    return filteredImage;
}

方法3:傅里叶变换

傅里叶变换将图像从空间域转换到频域,能够分析图像中的周期性纹理特征。对于规则纹理图像,傅里叶变换可以清晰显示出图像中的周期性模式,通过识别频谱中的异常(如噪声或不规则峰值),可以快速定位纹理中的缺陷。特别是在规则重复纹理(如纺织品、印刷品)中,傅里叶变换非常有效。

// --- 傅里叶变换 ---
void applyFourierTransform(const Mat& image, Mat& magnitudeSpectrum, Mat& inverseImage) {
    Mat padded;                            
    int m = getOptimalDFTSize(image.rows);
    int n = getOptimalDFTSize(image.cols); 
    copyMakeBorder(image, padded, 0, m - image.rows, 0, n - image.cols, BORDER_CONSTANT, Scalar::all(0));

    Mat planes[] = { Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F) };
    Mat complexI;
    merge(planes, 2, complexI);         

    dft(complexI, complexI);            

    split(complexI, planes);           
    magnitude(planes[0], planes[1], planes[0]);
    magnitudeSpectrum = planes[0];

    magnitudeSpectrum += Scalar::all(1);                     
    log(magnitudeSpectrum, magnitudeSpectrum);

    magnitudeSpectrum = magnitudeSpectrum(Rect(0, 0, magnitudeSpectrum.cols & -2, magnitudeSpectrum.rows & -2));
    int cx = magnitudeSpectrum.cols / 2;
    int cy = magnitudeSpectrum.rows / 2;

    Mat q0(magnitudeSpectrum, Rect(0, 0, cx, cy));   
    Mat q1(magnitudeSpectrum, Rect(cx, 0, cx, cy));  
    Mat q2(magnitudeSpectrum, Rect(0, cy, cx, cy));  
    Mat q3(magnitudeSpectrum, Rect(cx, cy, cx, cy)); 

    Mat tmp;                           
    q0.copyTo(tmp);
    q3.copyTo(q0);
    tmp.copyTo(q3);

    q1.copyTo(tmp);
    q2.copyTo(q1);
    tmp.copyTo(q2);

    normalize(magnitudeSpectrum, magnitudeSpectrum, 0, 1, NORM_MINMAX);

    Mat invDFT, invDFTcvt;
    dft(complexI, invDFT, DFT_INVERSE | DFT_REAL_OUTPUT); 
    normalize(invDFT, inverseImage, 0, 1, NORM_MINMAX);
}

3. 无规则图像

方法1: 边缘检测 + 轮廓检测

通过边缘检测来提取图像中的边缘,再结合轮廓检测来识别不规则的缺陷区域。针对特定场景也可尝试使用差分法。

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() {
    Mat src = imread("image_path");
    Mat gray, edges;

    cvtColor(src, gray, COLOR_BGR2GRAY);
    Canny(gray, edges, 100, 200);

    vector<vector<Point>> contours;
    findContours(edges, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

    Mat result = src.clone();
    drawContours(result, contours, -1, Scalar(0, 0, 255), 2);

    imshow("Contours", result);
    waitKey(0);

    return 0;
}

方法2: 图像分割(如Watershed算法)

针对复杂背景,可以采用图像分割算法来分割不同区域,并在这些区域中寻找异常的部分。

Mat markers = Mat::zeros(src.size(), CV_32S);
// 需要先手动或通过其他方法设定 markers 的初始值
watershed(src, markers);
// 结果中的-1表示轮廓

方法3: 机器学习或深度学习方法

对于特别复杂的无规则背景图像,可以使用机器学习或深度学习方法(如SVM, CNN)进行训练和检测。

// 示例代码:使用预训练的深度学习模型进行缺陷检测
Net net = readNet("model_path");
Mat blob = blobFromImage(src, 1.0, Size(224, 224), Scalar(104, 117, 123));
net.setInput(blob);
Mat prob = net.forward();

通过针对不同背景类型采用相应的方法,可以提高缺陷检测的准确性和效率。

 


总结

    缺陷检测在工业制造和质量控制等领域中至关重要。根据图像背景的复杂程度和特征差异,缺陷检测方法通常分为三类:单调背景、规则纹理背景和无规则图像背景。在单调背景下,阈值分割和差分法能够有效地识别明显的缺陷区域。对于规则纹理背景,模板匹配和Gabor滤波器可以精确检测纹理中的异常变化。此外,傅里叶变换作为一种频域分析工具,能够识别周期性纹理中的缺陷,尤其适用于规则纹理背景下的缺陷检测。在无规则图像背景中,边缘检测、图像分割(如Watershed算法)以及深度学习方法适合用于处理复杂的缺陷模式。通过灵活应用这些方法,结合傅里叶变换对频率信息的分析,可以进一步提高缺陷检测的精度和效率,从而满足多样化的实际需求。

 

  • 19
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值