返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++OpenCV实战之网孔检测的实现
  • 243
分享到

C++OpenCV实战之网孔检测的实现

2024-04-02 19:04:59 243人浏览 独家记忆
摘要

目录前言一、HSV通道转换二、图像修复2.1 OpenCV函数实现2.2 MyFunction三、轮廓提取四、效果显示五、源码总结前言 前段时间,有位粉丝私信我,给我发了一张图片,如

前言

前段时间,有位粉丝私信我,给我发了一张图片,如下图所示:

在这里贴出他的原话。

从他给的图片分析,该图存在遮挡,所以不能简单的二值化,然后提取图像轮廓去寻找结果。所以,我就想如何去掉这些遮挡物(即图像修复)。从图像可知,该遮挡物是黄色的线,所以,我就想可否使用hsv色彩空间提取出黄色,然后得到二值掩模图像,最后对原图进行修复。接下来,就一起看看是如何一步步实现的吧。

一、HSV通道转换

通过hsv通道转换,可以提取出图像中的黄色分量。

    //hsv颜色通道转换,提取图像中黄色线部分,生成掩膜图像
    Mat hsv;
    cvtColor(src, hsv, COLOR_BGR2HSV);

    Mat mask;
    inRange(hsv, Scalar(10, 50, 255), Scalar(40, 255, 255), mask);

结果如图所示:

二、图像修复

关于图像修复的相关知识可以参考我之前的博文。这里就不细说了。

OpenCV c++案例实战十四《图像修复》

OpenCV C++案例实战十七《图像去水印》

我们拿到上面的mask掩模图像,需要对其进行膨胀处理,使修复区域范围扩大。

    //将生成的掩膜mask膨胀一下,使掩膜区域放大
    Mat kernel = getStructuringElement(MORPH_RECT, Size(9, 9));
    dilate(mask, mask, kernel);

接下来,需要对图像进行修复。这里我提供两种修复方法,一种是OpenCV提供的inpaint函数,一种是我自己写的。

2.1 OpenCV函数实现

    //使用OpenCV自带的inpaint函数进行图像修复,得到目标图像
    Mat inpaintImg;
    inpaint(src, mask, inpaintImg, 1, INPAINT_NS);

效果如图所示。

2.2 MyFunction

通过修改图像像素达到图像修复的效果。具体请看源码注释。

    //自己写的算法,修改图像像素,完成图像修复
    Mat canvas = Mat::zeros(src.size(), src.type());
    int r = 1;//像素查找范围--表示在该像素点上下几行像素进行查找
    for (int i = r; i < src.rows- r; i++)
    {
        for (int j = 0; j < src.cols; j++)
        {        
            if (mask.at<uchar>(i, j) != 255)
            {   
                //对于非掩膜区域,直接将原像素进行像素赋值
                for (int c = 0; c < 3; c++)
                {
                    canvas.at<Vec3b>(i, j)[c] = src.at<Vec3b>(i, j)[c];
                }          
            }
            else
            {
                //找到距离该掩膜像素点最近的非掩膜区域像素进行赋值
                Point res = find_Nearest_Point(mask, i, j, r);
                for (int c = 0; c < 3; c++)
                {
                    canvas.at<Vec3b>(i, j)[c] = src.at<Vec3b>(res.x, res.y)[c];
                }
            }
        }
    }

效果如何所示

三、轮廓提取

接下来我们只需要对修复之后的图像进行轮廓提取就可以了。

    //将修复之后的目标图像进行图像预处理,提取轮廓
    Mat gray;
    cvtColor(canvas, gray, COLOR_BGR2GRAY);

    Mat gaussian;
    GaussianBlur(gray, gaussian, Size(3, 3), 0);

    Mat thresh;
    threshold(gaussian, thresh, 30, 255, THRESH_BINARY_INV);

    Mat kernel1 = getStructuringElement(MORPH_RECT, Size(3, 3));
    morphologyEx(thresh, thresh, MORPH_OPEN, kernel);

    //namedWindow("thresh", WINDOW_NORMAL);
    //imshow("thresh", thresh);

    //轮廓提取
    vector<vector<Point>>contours;
    findContours(thresh, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
    //经过面积,外接矩形特征筛选出目标区域
    vector<vector<Point>>EffectiveConts;
    for (int i = 0; i < contours.size(); i++)
    {
        double area = contourArea(contours[i]);

        if (area>100)
        {
            Rect rect = boundingRect(contours[i]);

            if (double(rect.height) > 30 && double(rect.width) > 30)
            {
                EffectiveConts.push_back(contours[i]);
            }
        }
    }

四、效果显示

    for (int i = 0; i < EffectiveConts.size(); i++)
    {
        //计算轮廓矩
        Moments Mo = moments(EffectiveConts[i]);
        //计算质心--即插孔坐标
        Point center = Point(Mo.m10 / Mo.m00, Mo.m01 / Mo.m00);
        //效果绘制
        Rect rect = boundingRect(EffectiveConts[i]);
        rectangle(src, rect, Scalar(0, 255, 0), 5);
        circle(src, center, 3, Scalar(0, 0, 255), -1);
    }

如图为该案例最终效果。

五、源码

#include<opencv2/opencv.hpp>
#include <iOStream>
#include<opencv2/photo.hpp>
using namespace std;
using namespace cv;

double EuDis(Point pt1, Point pt2)
{
    return sqrt(pow(pt1.x - pt2.x, 2) + pow(pt1.y - pt2.y, 2));
}

Point find_Nearest_Point(Mat mask , int currentrow, int currentcol, int r)
{  
    double mindis = 100000.0;
    Point res(0,0);

    //查找该像素点上下r行像素,找到最接近该像素的非掩膜区域像素
    for (int i = currentrow - r; i < currentrow + r; i++)
    {
        for (int j = 0; j < mask.cols; j++)
        {
            if (mask.at<uchar>(i, j) != 255)
            {
                //Point(currentrow, currentcol) 表示当前需要赋值的掩膜像素点
                double dis = EuDis(Point(currentrow, currentcol), Point(i, j));
                if (dis < mindis)
                {
                    mindis = dis;
                    res = Point(i, j); //目标像素点
                }
            }
        }
    }

    return res;
}

int main()
{
    Mat src = imread("test.jpg");
    if (src.empty())
    {
        cout << "No Image!" << endl;
        system("pause");
        return -1;
    }
  
    //hsv颜色通道转换,提取图像中黄色线部分,生成掩膜图像
    Mat hsv;
    cvtColor(src, hsv, COLOR_BGR2HSV);

    Mat mask;
    inRange(hsv, Scalar(10, 50, 255), Scalar(40, 255, 255), mask);
	
    //将生成的掩膜mask膨胀一下,使掩膜区域放大
    Mat kernel = getStructuringElement(MORPH_RECT, Size(9, 9));
    dilate(mask, mask, kernel);

    //使用OpenCV自带的inpaint函数进行图像修复,得到目标图像
    //Mat inpaintImg;
    //inpaint(src, mask, inpaintImg, 1, INPAINT_NS);
    //namedWindow("inpaintImg", WINDOW_NORMAL);
    //imshow("inpaintImg", inpaintImg);

    //自己写的算法,修改图像像素,完成图像修复
    Mat canvas = Mat::zeros(src.size(), src.type());
    int r = 1;//像素查找范围--表示在该像素点上下几行像素进行查找
    for (int i = r; i < src.rows- r; i++)
    {
        for (int j = 0; j < src.cols; j++)
        {        
            if (mask.at<uchar>(i, j) != 255)
            {   
                //对于非掩膜区域,直接将原像素进行像素赋值
                for (int c = 0; c < 3; c++)
                {
                    canvas.at<Vec3b>(i, j)[c] = src.at<Vec3b>(i, j)[c];
                }          
            }
            else
            {
                //找到距离该掩膜像素点最近的非掩膜区域像素进行赋值
                Point res = find_Nearest_Point(mask, i, j, r);
                for (int c = 0; c < 3; c++)
                {
                    canvas.at<Vec3b>(i, j)[c] = src.at<Vec3b>(res.x, res.y)[c];
                }
            }
        }
    }
    //namedWindow("canvas", WINDOW_NORMAL);
    //imshow("canvas", canvas);

    //将修复之后的目标图像进行图像预处理,提取轮廓
    Mat gray;
    cvtColor(canvas, gray, COLOR_BGR2GRAY);

    Mat gaussian;
    GaussianBlur(gray, gaussian, Size(3, 3), 0);

    Mat thresh;
    threshold(gaussian, thresh, 30, 255, THRESH_BINARY_INV);

    Mat kernel1 = getStructuringElement(MORPH_RECT, Size(3, 3));
    morphologyEx(thresh, thresh, MORPH_OPEN, kernel);

    //namedWindow("thresh", WINDOW_NORMAL);
    //imshow("thresh", thresh);

    //轮廓提取
    vector<vector<Point>>contours;
    findContours(thresh, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
    //经过面积,外接矩形特征筛选出目标区域
    vector<vector<Point>>EffectiveConts;
    for (int i = 0; i < contours.size(); i++)
    {
        double area = contourArea(contours[i]);

        if (area>100)
        {
            Rect rect = boundingRect(contours[i]);

            if (double(rect.height) > 30 && double(rect.width) > 30)
            {
                EffectiveConts.push_back(contours[i]);
            }
        }
    }

    for (int i = 0; i < EffectiveConts.size(); i++)
    {
        //计算轮廓矩
        Moments Mo = moments(EffectiveConts[i]);
        //计算质心--即插孔坐标
        Point center = Point(Mo.m10 / Mo.m00, Mo.m01 / Mo.m00);
        //效果绘制
        Rect rect = boundingRect(EffectiveConts[i]);
        rectangle(src, rect, Scalar(0, 255, 0), 5);
        circle(src, center, 3, Scalar(0, 0, 255), -1);
    }

    namedWindow("src", WINDOW_NORMAL);
    imshow("src", src);
    waiTKEy(0);
	system("pause");
    return 0;
}

总结

本文使用OpenCV C++实现网孔检测,主要操作有以下几点。

1、hsv通道转换,提取出黄色分量,得到掩模图像。

2、利用掩模图像对原图进行图像修复。

3、通过轮廓提取定位网孔位置。

以上就是C++ OpenCV实战之网孔检测的实现的详细内容,更多关于C++ OpenCV网孔检测的资料请关注编程网其它相关文章!

--结束END--

本文标题: C++OpenCV实战之网孔检测的实现

本文链接: https://lsjlt.com/news/148003.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C++OpenCV实战之网孔检测的实现
    目录前言一、HSV通道转换二、图像修复2.1 OpenCV函数实现2.2 MyFunction三、轮廓提取四、效果显示五、源码总结前言 前段时间,有位粉丝私信我,给我发了一张图片,如...
    99+
    2024-04-02
  • C++OpenCV实战之标记点检测的实现
    在实际应用中,能够直接利用霍夫圆检测这些理想方法的应用场景是非常少的,更多的是利用拟合的办法去寻找圆形。 大致思路如下,首先先选择要处理的ROI部分,记录下该图的左上点在原图的坐标,...
    99+
    2024-04-02
  • C++ OpenCV实战之车道检测
    目录前言一、获取车道ROI区域二、车道检测1.灰度、阈值2.获取非零像素点3.绘制车道线总结前言 本文将使用OpenCV C++ 进行车道检测。 一、获取车道ROI区域 原图如图所...
    99+
    2024-04-02
  • Python实战之OpenCV实现猫脸检测
    开发工具 Python版本:3.6.4 相关模块: cv2模块; 以及一些Python自带的模块。 环境搭建 安装Python并添加到环境变量,pip安装需要的相关模块即可。 原理简介 简单地讲一讲Haar分类器,也...
    99+
    2022-06-02
    OpenCV实现猫脸检测 Python OpenCV图像识别
  • Python+OpenCV实现单个圆形孔和针检测
    如果中间红色区域是针则可以用下面的代码检测,其阈值和斑点检测的参数根据图像像素值做相应修改 检测的主要思路是先通过找到外面的大圆,再通过圆心定位出一个ROI区域,在ROI区域中检测中...
    99+
    2024-04-02
  • C++ OpenCV实战之零部件的自动光学检测
    目录一、背景二、基础知识三、代码实现1、实现多窗口展示2、降噪处理3、背景去除4、连通图实现5、计算连通域面积6、轮廓检测四、总结一、背景 首先任务背景是AOI(自动光学检测) 最重...
    99+
    2024-04-02
  • 人脸检测实战终极之OpenCV+Python实现人脸对齐
    目录前言实现面部矫正器导入必要的包对齐人脸展示结果前言 这篇博文的目的是演示如何使用 OpenCV、Python 和面部标志对齐人脸。 给定一组面部标志(输入坐标),我们的目标是将图...
    99+
    2024-04-02
  • C++ OpenCV如何实现车道检测
    这篇文章主要为大家展示了“C++ OpenCV如何实现车道检测”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C++ OpenCV如何实现车道检测”这篇文章吧。一、获取车道RO...
    99+
    2023-06-28
  • 使用opencv实现车道线检测实战代码
    效果 void lane_detection(cv::Mat &src, cv::Mat &dst) { dst = cv::Mat::zeros(s...
    99+
    2024-04-02
  • opencv实现颜色检测
    本文实例为大家分享了opencv实现颜色检测的具体代码,供大家参考,具体内容如下 若要在OPencv 中实现颜色检测,首先要将待检测图像转换到HSV颜色空间中,但因为颜色是一个特定的...
    99+
    2024-04-02
  • OpenCV实现直线检测
    本文实例为大家分享了OpenCV实现直线检测的具体代码,供大家参考,具体内容如下 1 介绍 本文主要介绍OpenCV自带的直线检测函数HoughLines()的用法,这个函数的第一个...
    99+
    2024-04-02
  • opencv实现角点检测
    本文实例为大家分享了opencv实现角点检测的具体代码,供大家参考,具体内容如下 1、特征点的作用:使用特征点代表图像内容 运动目标跟踪物体识别图像配准全景图像拼接三维重建 2、Ha...
    99+
    2022-11-13
    opencv 角点检测
  • C++ OpenCV标记点检测怎么实现
    这篇文章主要介绍“C++ OpenCV标记点检测怎么实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C++ OpenCV标记点检测怎么实现”文章能帮助大家解决问题。效果如下:导...
    99+
    2023-06-29
  • C++ OpenCV实现二维码检测功能
    目录前言一、二维码检测二、二维码识别三、二维码绘制四、源码总结前言 本文将使用OpenCV C++ 进行二维码检测。 一、二维码检测 首先我们要先将图像进行预处理,通过灰度、滤波、...
    99+
    2024-04-02
  • Python人脸检测实战之疲劳检测
    目录使用 OpenCV 构建犯困检测器测试疲劳检测器今天我们实现疲劳检测。 如果眼睛已经闭上了一段时间,我们会认为他们开始打瞌睡并发出警报来唤醒他们并引起他们的注意。我们测试一段视频...
    99+
    2024-04-02
  • Python+Opencv文本检测的实现
    目录EAST 深度学习文本检测器项目结构实施说明使用 OpenCV 实现我们的文本检测器OpenCV 文本检测结果视频文字检测结果在本教程中,您将学习如何使用 OpenCV 使用 E...
    99+
    2024-04-02
  • C++利用Opencv实现多个圆形检测
    主要是利用霍夫圆检测、面积筛选等完成多个圆形检测,具体代码及结果如下。 第一部分是头文件(common.h): #pragma once #include<opencv2/op...
    99+
    2022-11-13
    C++ Opencv圆形检测 C++ 原型检测
  • Python OpenCV实现边缘检测
    本文实例为大家分享了Python OpenCV实现边缘检测的具体代码,供大家参考,具体内容如下 1. Sobel 算子检测 Sobel 算子是高斯平滑和微分运算的组合,抗噪能力很强,用途也很多,尤其是效率要求高但对细...
    99+
    2022-06-02
    python OpenCV 边缘检测
  • opencv实现棋盘格检测
    本文实例为大家分享了opencv实现棋盘格检测的具体代码,供大家参考,具体内容如下 代码: #include <iostream> #include <vector...
    99+
    2022-11-13
    opencv棋盘格检测 opencv棋盘检测 opencv检测
  • JavaCV摄像头实战之实现口罩检测
    目录本篇概览问题提前告知关于百度AI开放平台编码:添加依赖库编码:封装请求和响应百度AI开放平台的代码DetectService接口的实现主程序验证本篇概览 本文是《JavaCV的摄...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作