进入正题,本篇对网格缺陷检测的思路很简单:
动态阈值处理
面积筛选显示缺陷
opencv实现:
Mat src = imread("D:/opencv练习图片/网格缺陷检测1.png");
imshow("原图", src);
cvtColor(src, gray, COLOR_RGB2GRAY);
GaussianBlur(gray, gray, Size(3, 3), 1, 0); //双阈值方法
threshold(gray, binary1, 25, 255, THRESH_BINARY);
threshold(gray, binary2, 80, 255, THRESH_BINARY_INV);
bitwise_and(binary1, binary2, binary);
imshow("双阈值二值化", binary);
vector<vector<Point>>contours;
findContours(binary, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point()); for (int i = 0; i < contours.size(); i++)
{ float area = contourArea(contours[i]); if (area>350)
{
drawContours(src, contours, i, Scalar(0, 0, 255), 2, 8); int baseline = 0;
Size textSize = getTextSize("Mesh Not OK", FONT_HERSHEY_SIMPLEX, 1.0, 2, &baseline);
rectangle(src, Rect(10, 10, textSize.width, textSize.height + baseline), Scalar(212, 233, 252), -1, 8);
putText(src, "Mesh Not OK", Point(10, 5 + textSize.height + baseline), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 255), 2, 8);
} else
{ int baseline = 0;
Size textSize = getTextSize("Mesh OK", FONT_HERSHEY_SIMPLEX, 1.0, 2, &baseline);
rectangle(src, Rect(10, 10, textSize.width, textSize.height + baseline), Scalar(212, 233, 252), -1, 8);
putText(src, "Mesh OK", Point(10, 5 + textSize.height + baseline), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 255), 2, 8);
}
}
imshow("缺陷", src);

这里采用的是双阈值处理。我们可以对比三种阈值处理的情况:
(1)全局阈值OTSU方法:

可以看到有部分正常孔洞和网格相连,会导致正常孔洞也被标记为缺陷。
(2)自适应阈值:

可以看到效果还不错。
(3)双阈值:

对比自适应阈值,可以看到分割的还是比较明显一点的。