裂缝和缺陷检测
发布时间
阅读量:
阅读量
裂缝比如水泥地、陶瓷的裂痕,缺陷比如盘子的缺口等,做的就是这些检测。裂缝检测参考这里,缺陷检测主要使用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

其中 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

效果图:
裂缝检测
缺损检测
全部评论 (0)
还没有任何评论哟~
