Advertisement

裂缝和缺陷检测

阅读量:

裂缝比如水泥地、陶瓷的裂痕,缺陷比如盘子的缺口等,做的就是这些检测。裂缝检测参考这里,缺陷检测主要使用opencv一个连通域分析函数,如下所示:

复制代码
 int cv::connectedComponents (

    
     cv::InputArrayn image, // input 8-bit single-channel (binary)
    
     cv::OutputArray labels, // output label map
    
     int connectivity = 8, // 4- or 8-connected components
    
     int ltype = CV_32S // Output label type (CV_32S or CV_16U)
    
 );
    
 int cv::connectedComponentsWithStats (
    
     cv::InputArrayn image, // input 8-bit single-channel (binary)
    
     cv::OutputArray labels, // output label map
    
     cv::OutputArray stats, // Nx5 matrix (CV_32S) of statistics:
    
     // [x0, y0, width0, height0, area0;
    
     // ... ; x(N-1), y(N-1), width(N-1),
    
     // height(N-1), area(N-1)]
    
     cv::OutputArray centroids, // Nx2 CV_64F matrix of centroids:
    
     // [ cx0, cy0; ... ; cx(N-1), cy(N-1)]
    
     int connectivity = 8, // 4- or 8-connected components
    
     int ltype = CV_32S // Output label type (CV_32S or CV_16U)
    
 );
    
    
    
    
    cpp
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-07-12/qNlVk59hagnfPDvSx8eRduiZLsHU.png)

其中 connectedComponents()仅仅创建了一个标记图(图中不同连通域使用不同的标记,和原图宽高一致), connectedComponentsWithStats()完成上面任务后,还提供每个连通区域的重要信息bounding box, area, and center of mass( centroid). 如果不需要连通域的质心,将参数centroids设置为 cv::noArray()(可能会出错)。函数返回值为连通区域的总数N,范围为[0,N-1] 其中0代表背景。源码

部分代码如下:

defectDetection.cpp

复制代码
 #include "defectDetection.h"

    
 #include "opencv2/features2d.hpp"
    
 #include "opencv2/highgui/highgui.hpp"
    
  
    
 std::vector<DefectDetectSt> biob(cv::Mat& src, int minArea, int maxArea) {
    
 	cv::Mat gray;
    
 	if (src.channels() == 3) {
    
 		cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY);
    
 	}
    
 	else {
    
 		gray = src;
    
 	}
    
 	//cv::imshow("gray", gray);
    
  
    
 	gray = 255 - gray;
    
 	cv::Mat thres;
    
 	cv::threshold(gray, thres, 230, 255, cv::THRESH_BINARY);
    
 	//cv::imshow("thres", thres);
    
 	thres = 255 - thres;
    
 	std::vector<std::vector<cv::Point>> contours;
    
 	std::vector<cv::Vec4i> hierarchy;
    
 	cv::findContours(thres, contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE, cv::Point());
    
 	cv::Rect boundRect;
    
 	for (int i = 0; i < contours.size(); ++i) {
    
 		boundRect = cv::boundingRect((cv::Mat)contours[i]);
    
 		if (((boundRect.width * boundRect.height) > 600) && (abs(boundRect.width - boundRect.height) < 5)) {
    
 			int x = boundRect.x + boundRect.width / 2;
    
 			int y = boundRect.y + boundRect.height / 2;
    
 			int rad = boundRect.height / 2;
    
 			cv::circle(thres, cv::Point(x, y), rad, cv::Scalar(255, 255, 255), 2);
    
 		}
    
 	}
    
 	//cv::imshow("thres", thres);
    
  
    
 	thres = 255 - thres;
    
 	std::vector<DefectDetectSt> ret;
    
 	cv::Mat connect, stats, centroids;
    
 	int areaNum = cv::connectedComponentsWithStats(thres, connect, stats, centroids, 8, CV_16U);
    
 	for (int i = 1; i < areaNum; ++i) {
    
 		int area = stats.at<int>(i, cv::CC_STAT_AREA);
    
 		if (area >= minArea && area < maxArea) {
    
 			DefectDetectSt dds;
    
 			dds.centerX = centroids.at<double>(i, 0);
    
 			dds.centerY = centroids.at<double>(i, 1);
    
 			
    
 			dds.rect.x = stats.at<int>(i, cv::CC_STAT_LEFT);
    
 			dds.rect.y = stats.at<int>(i, cv::CC_STAT_TOP);
    
 			dds.rect.width = stats.at<int>(i, cv::CC_STAT_WIDTH);
    
 			dds.rect.height = stats.at<int>(i, cv::CC_STAT_HEIGHT);
    
 			dds.area = area;
    
 			ret.push_back(dds);
    
  
    
 			cv::circle(src, cv::Point(dds.centerX, dds.centerY), 2, cv::Scalar(0, 255, 0), 2, 8, 0);
    
 			cv::rectangle(src, dds.rect, cv::Scalar(0, 0, 255), 1, 8, 0);
    
 		}
    
 	}
    
 }
    
    
    
    
    cpp
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-07-12/TqnlKSF8dozNZfBgXOu9JMYAsDGx.png)

效果图:
裂缝检测
缺损检测

全部评论 (0)

还没有任何评论哟~