基于opencv的缺陷检测

1..基于opencv 差分图像二值分析的刀片缺陷检测

cpp 复制代码
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
string rootdir = "F:/Study/opencv/opencv-4.8.0/opencv/sources/samples/data/";
void sort_box(vector<Rect> &boxes) {
	int size = boxes.size();
	for (int i = 0; i < size - 1; i++) {
		for (int j = i; j < size; j++) {
			int x = boxes[j].x;
			int y = boxes[j].y;
			if (y < boxes[i].y) {
				Rect temp = boxes[i];
				boxes[i] = boxes[j];
				boxes[j] = temp;
			}
		}
	}
}

void detect_defect(Mat &binary, vector<Rect> rects, vector<Rect> &defect, Mat &tpl) {
	int h = tpl.rows;
	int w = tpl.cols;
	int size = rects.size();
	for (int i = 0; i < size; i++) {
		// 构建diff
		Mat roi = binary(rects[i]);
		resize(roi, roi, tpl.size());
		Mat mask;
		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);
		//imshow("mask", mask);
		//waitKey(0);*/

		// 根据diff查找缺陷,阈值化
		int count = 0;
		for (int row = 0; row < h; row++) {
			for (int col = 0; col < w; col++) {
				int pv = mask.at<uchar>(row, col);
				if (pv == 255) {
					count++;
				}
			}
		}

		// 填充一个像素宽
		int mh = mask.rows + 2;
		int mw = mask.cols + 2;
		Mat m1 = Mat::zeros(Size(mw, mh), mask.type());
		Rect mroi;
		mroi.x = 1;
		mroi.y = 1;
		mroi.height = mask.rows;
		mroi.width = mask.cols;
		mask.copyTo(m1(mroi));
		/*imshow("mask2", mask);
		imshow("ml", m1);*/
		waitKey(0);
		// 轮廓分析
		vector<vector<Point>> contours;
		vector<Vec4i> hierarchy;
		findContours(m1, contours, hierarchy, RETR_LIST, CHAIN_APPROX_SIMPLE);
		bool find = false;
		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)) {
				continue;
			}
			double area = contourArea(contours[t]);
			if (area > 10) {
				printf("ratio : %.2f, area : %.2f \n", ratio, area);
				find = true;
			}
		}

		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);

	// 图像二值化
	Mat gray, binary;
	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);

	// 轮廓发现
	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;
	vector<Rect> rects;
	findContours(binary, contours, hierarchy, RETR_LIST, CHAIN_APPROX_SIMPLE);
	int height = src.rows;
	for (size_t t = 0; t < contours.size(); t++) {
		Rect rect = boundingRect(contours[t]);
		double area = contourArea(contours[t]);
		if (rect.height > (height / 2)) {
			continue;
		}
		if (area < 150) {
			continue;
		}
		/*imshow("roi", binary(rect));
		waitKey(0);*/
		rects.push_back(rect);
	}

	// 对每个刀片进行比对检测
	sort_box(rects);
	vector<Rect> defects;
	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);
	}
	imshow("多个缺陷检测", src);
	waitKey(0);
}
int main() {
	Mat src=imread(rootdir+"ce_01.jpg");
	multiple_defects_detection(src);
	return 0;
}

2.基于opencv DNN模块的UNet道路裂纹检测

cpp 复制代码
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
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);
	inputBlob /= 0.5;

	// 执行图像分类
	Mat prob;
	net.setInput(inputBlob);
	prob = net.forward();

	// 得到最可能分类输出
	Mat probMat = prob.reshape(1, 1);
	Point classNumber;
	double classProb;
	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);
	waitKey(0);
}
int main() {
	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);
	return 0;
}
相关推荐
想用offer打牌1 分钟前
Reasoning + Acting: ReAct范式与ReAct Agent
人工智能·后端·llm
老蒋新思维2 分钟前
创客匠人分享:从“个人品牌”到“智能系统”,创始人IP如何穿越变现周期?
网络·人工智能·网络协议·tcp/ip·重构·创始人ip·创客匠人
汉克老师3 分钟前
小学生0基础学大语言模型应用(第0课 课前准备)
人工智能·语言模型·自然语言处理·小学生0基础学习大语言模型
智驱力人工智能4 分钟前
从合规到习惯 海上作业未穿救生衣AI识别系统的工程实践与体系价值 未穿救生衣检测 AI救生衣状态识别 边缘计算救生衣监测设备
人工智能·深度学习·opencv·算法·目标检测·边缘计算
猎板PCB黄浩6 分钟前
高多层线路板工厂专业选型指南:全流程评估体系与猎板适配场景解析
大数据·人工智能·算法·pcb
悟道心8 分钟前
2.自然语言处理NLP - 文本预处理
人工智能·自然语言处理
霖大侠9 分钟前
Squeeze-and-Excitation Networks
人工智能·算法·机器学习·transformer
天竺鼠不该去劝架25 分钟前
财务自动化怎么做?财务RPA选型清单与路径
人工智能·科技·自动化
好奇龙猫1 小时前
人工智能学习-AI-MIT公开课-第三节:推理:目标树与基于规则的专家系统-笔记
人工智能·笔记·学习
正经人_x1 小时前
学习日记28:Run, Don’t Walk: Chasing Higher FLOPS for Faster Neural Networks
人工智能·深度学习·cnn