当前位置 博文首页 > 唯有自己强大:复杂背景的缺陷提取

    唯有自己强大:复杂背景的缺陷提取

    作者:唯有自己强大 时间:2021-06-18 18:25

    摘要

    本篇用halcon和opencv分别实现对于复杂背景下的缺陷提取实战


    如下图,背景很复杂,周围划痕都是正常区域。要提取中间小块的黑色区域(缺陷区域)。单纯用频域滤波和阈值提取,效果一般。都会把周围的划痕提取出来。

    Halcon实现

    思路:

    通过中值滤波后,对图像进行动态阈值提取细化缺陷部分,结合开运算,闭运算提取缺陷。

    read_image (Image, 'D:/opencv练习图片/复杂背景提取缺陷.jpg')
    dev_set_line_width (3)
    threshold (Image, Region, 30, 255)
    reduce_domain (Image, Region, ImageReduced)
    mean_image (ImageReduced, ImageMean, 150, 150)
    dyn_threshold (ImageReduced, ImageMean, SmallRaw, 37, 'dark')
    opening_circle (SmallRaw, RegionOpening,4.5)
    closing_circle (RegionOpening, RegionClosing, 7)
    connection (RegionClosing, ConnectedRegions)
    dev_set_color ('red')
    dev_display (Image)
    dev_set_draw ('margin')
    dev_display (ConnectedRegions)

     Opencv实现

     实现方法与思路:

    1. 原图转灰度图后使用核大小201(奇数)做中值滤波;
    2. 灰度图与滤波图像做差,阈值处理
    3. 形态学进一步提取缺陷
    4. 轮廓查找,通过面积筛选缺陷,显示
    int main(int argc, char** argv)
    {
        Mat src = imread("D:/opencv练习图片/复杂背景提取缺陷.jpg");
        imshow("输入图像", src);
        Mat gray, gray_mean,dst,binary1, binary2, binary;
        cvtColor(src, gray, COLOR_BGR2GRAY);
        medianBlur(gray, gray_mean, 201);
        imshow("中值滤波", gray_mean);
        addWeighted(gray, -1, gray_mean, 1, 0, dst);
        imshow("做差", dst);
        //阈值提取
        threshold(dst, binary1, 10, 255, THRESH_BINARY|THRESH_OTSU);
        imshow("二值化", binary1);
        Mat src_open, src_close;
        //形态学
        Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(7, 7), Point(-1, -1));
        morphologyEx(binary1, src_open, MORPH_OPEN, kernel, Point(-1, -1));
        imshow("开运算", src_open);
        morphologyEx(src_open, src_close, MORPH_CLOSE, kernel, Point(-1, -1));
        imshow("闭运算", src_close);
        vector<vector<Point>>contours;
        findContours(src_close, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point());
        for (int i = 0; i < contours.size(); i++)
        {
            float area = contourArea(contours[i]);
            cout << area << endl;
            if (area > 1000)
            {
                drawContours(src, contours, i, Scalar(0, 0, 255), 2, 8);
            }
        }
        imshow("结果", src);
        waitKey(0);
        return 0;
    }

    这里巧用了addWeighted函数进行做差,得出图像:

    然后二值化,寻找轮廓,筛选得出缺陷轮廓。

     

    bk