1..基于opencv 差分图像二值分析的刀片缺陷检测
string rootdir = "F:/Study/opencv/opencv-4.8.0/opencv/sources/samples/data/";
void sort_box(vector &boxes) {
for (int i = 0; i < size - 1; i++) {
for (int j = i; j < size; j++) {
void detect_defect(Mat &binary, vector rects, vector &defect, Mat &tpl) {
for (int i = 0; i < size; i++) {
Mat roi = binary(rects[i]);
resize(roi, roi, tpl.size());
subtract(tpl, roi, mask);
Mat se = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
morphologyEx(mask, mask, MORPH_OPEN, se);
threshold(mask, mask, 0, 255, THRESH_BINARY);
for (int row = 0; row < h; row++) {
for (int col = 0; col < w; col++) {
int pv = mask.at(row, col);
Mat m1 = Mat::zeros(Size(mw, mh), mask.type());
findContours(m1, contours, hierarchy, RETR_LIST, CHAIN_APPROX_SIMPLE);
for (size_t t = 0; t < contours.size(); t++) {
Rect rect = boundingRect(contours[t]);
float ratio = (float)rect.width / ((float)rect.height);
if (ratio > 4.0 && (rect.y < 5 || (m1.rows - (rect.height + rect.y)) < 10)) {
double area = contourArea(contours[t]);
printf("ratio : %.2f, area : %.2f \n", ratio, area);
if (count > 50 && find) {
printf("count : %d \n", count);
defect.push_back(rects[i]);
void multiple_defects_detection(Mat &src) {
Mat tpl = imread(rootdir + "dt.png", IMREAD_GRAYSCALE);
cvtColor(src, gray, COLOR_BGR2GRAY);
threshold(gray, binary, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
imshow("binary", binary);
imwrite("D:/binary.png", binary);
Mat se = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
morphologyEx(binary, binary, MORPH_OPEN, se);
findContours(binary, contours, hierarchy, RETR_LIST, CHAIN_APPROX_SIMPLE);
for (size_t t = 0; t < contours.size(); t++) {
Rect rect = boundingRect(contours[t]);
double area = contourArea(contours[t]);
if (rect.height > (height / 2)) {
detect_defect(binary, rects, defects, tpl);
for (int i = 0; i < defects.size(); i++) {
rectangle(src, defects[i], Scalar(0, 0, 255), 2, 8, 0);
putText(src, "bad", defects[i].tl(), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(255, 0, 0), 2, 8);
Mat src=imread(rootdir+"ce_01.jpg");
multiple_defects_detection(src);
2.基于opencv DNN模块的UNet道路裂纹检测
string model_dir="F:/Study/opencv/opencv-4.8.0/opencv/sources/samples/data/";
void resnet_surface_detection(Mat &image) {
String defect_labels[] = { "In","Sc","Cr","PS","RS","Pa" };
dnn::Net net = dnn::readNetFromONNX(model_dir + "surface_defect_resnet18.onnx");
Mat inputBlob = dnn::blobFromImage(image, 0.00392, Size(200, 200), Scalar(127, 127, 127), false, false);
Mat probMat = prob.reshape(1, 1);
minMaxLoc(probMat, NULL, &classProb, NULL, &classNumber);
int classidx = classNumber.x;
printf("\n current image classification : %s, possible : %.2f\n", defect_labels[classidx].c_str(), classProb);
putText(image, defect_labels[classidx].c_str(), Point(20, 40), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 255), 2, 8);
imshow("基于分类的缺陷检测", image);
Mat image = imread("F:/Study/opencv/opencv-4.8.0/opencv/sources/samples/data/NEU-CLS/NEU-CLS/Ps_1.bmp");
resnet_surface_detection(image);