基于opencv ,实现螺丝松动检测
opencv
OpenCV: 开源计算机视觉库
项目地址:https://gitcode.com/gh_mirrors/opencv31/opencv
免费下载资源
·
前言
目前地铁上检修螺丝后,会涂抹一种红色标记线,来代表检测完成,日后检修员就可以通过肉眼来观察螺丝是否松动,这样可以大大提高检修的效率问题。所以我们参照这个思路,通过opencv来实现螺丝是否松动检测。
正文
- 首先我们通过目标检测算法,识别出图像中螺丝的区域。这里不实现了就,自行通过yolo等算法实现。
- 识别出目标区域后,我们首先提取图像中的红色区域(假设我们用红色标记)
void extract_red_area(const cv::Mat &image, cv::Mat &redMat) { int width = image.cols; int height = image.rows; int x, y; double B = 0.0, G = 0.0, R = 0.0, H = 0.0, S = 0.0, V = 0.0; redMat = Mat::zeros(image.size(), CV_8UC1); for (x = 0; x < height; x++) { for (y = 0; y < width; y++) { B = image.at<Vec3b>(x, y)[0]; G = image.at<Vec3b>(x, y)[1]; R = image.at<Vec3b>(x, y)[2]; RGB2HSV(R, G, B, H, S, V); //红色范围,范围参考的网上。可以自己调 if ((H >= 312 && H <= 360) && (S >= 17 && S <= 100) && (V > 18 && V < 100)) redMat.at<uchar>(x, y) = 255; } } }
-
提取红色区域轮廓信息,这里我们需要过滤一些,因为有一些轮廓是我们不需要的。(根据实际情况来过滤)
// 2.提取轮廓 std::vector<std::vector<cv::Point>> contours; std::vector<cv::Vec4i> hierarchy; cv::findContours( redMat, // 输入二值图 contours, // 存储轮廓的向量 hierarchy, // 轮廓层次信息 RETR_TREE, // 检索所有轮廓并重建嵌套轮廓的完整层次结构 CHAIN_APPROX_NONE); // 每个轮廓的全部像素 printf("find %d contours \n", contours.size());
// 过滤轮廓 void filter_contours(std::vector<cv::Vec4i> &hierarchy, std::vector<std::vector<cv::Point>> &contours) { std::vector<std::vector<cv::Point>>::iterator itc = contours.begin(); std::vector<cv::Vec4i>::iterator itc_hierarchy = hierarchy.begin(); int i = 0; int min_size = 20; int max_size = 500; while (itc_hierarchy != hierarchy.end()) { //验证轮廓大小 //if (!(hierarchy[i][2] < 0 && hierarchy[i][3] < 0)) // 存在子轮廓/父轮廓 if (hierarchy[i][3] > 0) // 存在父轮廓 { itc = contours.erase(itc); itc_hierarchy = hierarchy.erase(itc_hierarchy); } else { //验证轮廓大小 if (itc->size() < min_size || itc->size() > max_size) { itc = contours.erase(itc); itc_hierarchy = hierarchy.erase(itc_hierarchy); } else { ++itc; ++itc_hierarchy; } ++i; } } }
-
提取每一个轮廓的最小外接矩形,并绘制最小外接矩形的每条边和中心点,并计算每一个区域的角度,最后通过每一个区域的角度来判断是否对齐。
void draw_center(cv::Mat &dstImg, std::vector<std::vector<cv::Point>> &contours, std::vector<cv::Point> &vec) { std::vector<RotatedRect> box(contours.size()); //定义最小外接矩形集合 Point2f rect[4]; for (int i = 0; i < contours.size(); i++) { box[i] = minAreaRect(Mat(contours[i])); cv::circle(dstImg, Point(box[i].center.x, box[i].center.y), 2, cv::Scalar(0, 255, 255), cv::FILLED); box[i].points(rect); for (int j = 0; j < 4; j++) { line(dstImg, rect[j], rect[(j + 1) % 4], Scalar(255, 0, 255), 1, 8); //绘制最小外接矩形每条边 } std::cout << "angel:" << box[i].angle << std::endl; } }
5. 以上差不多就是大概实现过程。主要实现思路就是: 识别螺丝 -> 提取红色区域 -> 识别轮廓 -> 筛选轮廓 -> 计算最小外接矩形、中心点、角度 -> 通过角度来判断是否对齐,从而来判断螺丝是否松动。
demo:基于opencv,实现螺丝防松动检测_螺丝松动检测-互联网文档类资源-CSDN下载
最后
以上实现思路都是个人想法,所以如果有小伙伴有更好的算法,欢迎楼下留言,非常感谢。最后祝大家新年快乐,在新的一年里工作顺利,技能大长。
GitHub 加速计划 / opencv31 / opencv
77.38 K
55.71 K
下载
OpenCV: 开源计算机视觉库
最近提交(Master分支:2 个月前 )
c3747a68
Added Universal Windows Package build to CI. 5 天前
9b635da5 - 5 天前
更多推荐
已为社区贡献4条内容
所有评论(0)