持续创作,加速成长!这是我参与「掘金日新计划 · 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;
}
今天先提供一下以上两个函数,第一个函数的结果,可以直接放到第二个函数中作为输入进行使用。这也体现了封装的好处,调用起来非常的方便。 下面放几张我处理的结果。
下面是背景差分的图像
下面是轮廓绘制图