QT实现背景差分、轮廓检测

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第28天,

之前一直用python在做瑕疵检测的项目,图一个方便。到最后项目集成发现了一个问题,python不能封装为动态链接库,所以呢只能用QT重新来一遍,其中涉及到了一些图像增强算法(背景差分),以及检测瑕疵轮廓的方案,下面通过代码的形式分享出来,方便使用者直接进行调用。

关于QT配置Opencv的教程前面博客中我已经进行了详细的说明,这篇博客不再赘述,还没有配置好环境的在我前面的博客中可以找到相关的教程,而且教程对于windows11+opencv4.1.0+qt5.13.1也是有效的,我已经亲测过。

下面直接上代码

首先是背景差分,也就是利用不同的光源在相同位置进行照射采集两幅图像,对两幅图像进行相减,在一定程度上可以抑制掉背景元素所带来的干扰。

// 减除背景之外的干扰源
Mat Widget::Background_Weakening(String redImage_path, String blueImage_path, int x, int y, int x1, int y1, bool isChange)
{
    // 读取两幅图像
    Mat img_red = imread(redImage_path);
    Mat img_blue = imread(blueImage_path);
    // 对图像进行中值滤波
    Mat f_img_red;
    Mat f_img_blue;
    medianBlur(img_red,f_img_red, 3);
    medianBlur(img_blue,f_img_blue, 3);
    // 图像相减操作,也就是所谓的背景差分
    Mat sub_img;
    subtract(f_img_red, f_img_blue, sub_img, noArray());
    // 这个其实跟上面的subtract函数差不多,是计算两个图像矩阵对应位置做差的绝对值
    //absdiff(f_img_red, f_img_blue, sub_img);
    // 将处理的结果保存一下
    imwrite("sub_img.jpg", sub_img);
    // 将处理的结果返回,供其他函数进行调用
    return sub_img;
}

然后就是轮廓查找

// 检测轮廓
Mat Widget::DetectContours(Mat image, int canny_thresh_low, int canny_thresh_high, String contours_result_path)
{
    Mat img;
    Mat edge_img;
    // 先通过canny算子找到边缘
    Canny(image, edge_img, 0, 100);
    std::vector<std::vector<Point> > contours;
    std::vector<Vec4i> hierarchy;
    // 然后通过轮廓查找函数得到轮廓的一系列坐标
    findContours(edge_img,contours,hierarchy,RETR_LIST,CHAIN_APPROX_TC89_L1);
    // 然后将这一系列坐标进行绘制,在图像上形成明显的轮廓标记
    drawContours(image, contours, -1, (255, 0, 255),1);
    // 保存一下轮廓图像
    imwrite("contours.jpg", image);
    // 将得到的结果进行返回,供其它函数进行调用
    return image;
}

今天先提供一下以上两个函数,第一个函数的结果,可以直接放到第二个函数中作为输入进行使用。这也体现了封装的好处,调用起来非常的方便。 下面放几张我处理的结果。

下面是背景差分的图像

image.png

下面是轮廓绘制图

image.png

猜你喜欢

转载自juejin.im/post/7111859550328160270