C++ OpenCV如何实现轮廓发现

发布时间:2021-11-26 10:06:29 作者:小新
来源:亿速云 阅读:426

C++ OpenCV如何实现轮廓发现

概述

在图像处理和计算机视觉领域,轮廓发现是一个非常重要的任务。轮廓是指图像中物体的边界,通过轮廓发现,我们可以提取出图像中的物体形状、大小、位置等信息。OpenCV是一个强大的计算机视觉库,提供了丰富的函数和工具来实现轮廓发现。本文将详细介绍如何使用C++和OpenCV来实现轮廓发现。

准备工作

在开始之前,确保你已经安装了OpenCV库,并且配置好了C++开发环境。你可以通过以下命令来安装OpenCV:

sudo apt-get install libopencv-dev

读取图像

首先,我们需要读取一张图像。OpenCV提供了imread函数来读取图像文件。以下是一个简单的代码示例:

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() {
    // 读取图像
    Mat image = imread("example.jpg", IMREAD_COLOR);

    if (image.empty()) {
        cout << "Could not open or find the image" << endl;
        return -1;
    }

    // 显示原始图像
    namedWindow("Original Image", WINDOW_AUTOSIZE);
    imshow("Original Image", image);

    waitKey(0);
    return 0;
}

在这个示例中,我们读取了一张名为example.jpg的图像,并在窗口中显示出来。

图像预处理

在进行轮廓发现之前,通常需要对图像进行一些预处理操作,例如灰度化、二值化等。这些操作可以帮助我们更好地提取轮廓。

灰度化

灰度化是将彩色图像转换为灰度图像的过程。OpenCV提供了cvtColor函数来实现这一操作:

Mat grayImage;
cvtColor(image, grayImage, COLOR_BGR2GRAY);

// 显示灰度图像
namedWindow("Gray Image", WINDOW_AUTOSIZE);
imshow("Gray Image", grayImage);

二值化

二值化是将灰度图像转换为黑白图像的过程。OpenCV提供了threshold函数来实现这一操作:

Mat binaryImage;
threshold(grayImage, binaryImage, 128, 255, THRESH_BINARY);

// 显示二值图像
namedWindow("Binary Image", WINDOW_AUTOSIZE);
imshow("Binary Image", binaryImage);

在这个示例中,我们将灰度图像转换为二值图像,阈值为128。

轮廓发现

在完成图像预处理后,我们可以使用OpenCV的findContours函数来发现图像中的轮廓。findContours函数的基本用法如下:

vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(binaryImage, contours, hierarchy, RETR_TREE, CHN_APPROX_SIMPLE);

绘制轮廓

发现轮廓后,我们可以使用drawContours函数将轮廓绘制到图像上:

Mat contourImage = Mat::zeros(binaryImage.size(), CV_8UC3);
for (size_t i = 0; i < contours.size(); i++) {
    drawContours(contourImage, contours, (int)i, Scalar(0, 255, 0), 2, LINE_8, hierarchy, 0);
}

// 显示轮廓图像
namedWindow("Contours", WINDOW_AUTOSIZE);
imshow("Contours", contourImage);

在这个示例中,我们将所有轮廓绘制到一张黑色背景的图像上,轮廓颜色为绿色。

轮廓分析

发现轮廓后,我们还可以对轮廓进行进一步的分析,例如计算轮廓的面积、周长、边界框等。

计算轮廓面积

OpenCV提供了contourArea函数来计算轮廓的面积:

for (size_t i = 0; i < contours.size(); i++) {
    double area = contourArea(contours[i]);
    cout << "Contour " << i << " area: " << area << endl;
}

计算轮廓周长

OpenCV提供了arcLength函数来计算轮廓的周长:

for (size_t i = 0; i < contours.size(); i++) {
    double perimeter = arcLength(contours[i], true);
    cout << "Contour " << i << " perimeter: " << perimeter << endl;
}

计算边界框

OpenCV提供了boundingRect函数来计算轮廓的边界框:

for (size_t i = 0; i < contours.size(); i++) {
    Rect boundingBox = boundingRect(contours[i]);
    rectangle(contourImage, boundingBox, Scalar(255, 0, 0), 2);
}

在这个示例中,我们计算了每个轮廓的边界框,并将其绘制到轮廓图像上。

完整代码示例

以下是一个完整的C++ OpenCV轮廓发现代码示例:

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() {
    // 读取图像
    Mat image = imread("example.jpg", IMREAD_COLOR);

    if (image.empty()) {
        cout << "Could not open or find the image" << endl;
        return -1;
    }

    // 显示原始图像
    namedWindow("Original Image", WINDOW_AUTOSIZE);
    imshow("Original Image", image);

    // 灰度化
    Mat grayImage;
    cvtColor(image, grayImage, COLOR_BGR2GRAY);

    // 显示灰度图像
    namedWindow("Gray Image", WINDOW_AUTOSIZE);
    imshow("Gray Image", grayImage);

    // 二值化
    Mat binaryImage;
    threshold(grayImage, binaryImage, 128, 255, THRESH_BINARY);

    // 显示二值图像
    namedWindow("Binary Image", WINDOW_AUTOSIZE);
    imshow("Binary Image", binaryImage);

    // 轮廓发现
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    findContours(binaryImage, contours, hierarchy, RETR_TREE, CHN_APPROX_SIMPLE);

    // 绘制轮廓
    Mat contourImage = Mat::zeros(binaryImage.size(), CV_8UC3);
    for (size_t i = 0; i < contours.size(); i++) {
        drawContours(contourImage, contours, (int)i, Scalar(0, 255, 0), 2, LINE_8, hierarchy, 0);
    }

    // 显示轮廓图像
    namedWindow("Contours", WINDOW_AUTOSIZE);
    imshow("Contours", contourImage);

    // 轮廓分析
    for (size_t i = 0; i < contours.size(); i++) {
        double area = contourArea(contours[i]);
        double perimeter = arcLength(contours[i], true);
        Rect boundingBox = boundingRect(contours[i]);

        cout << "Contour " << i << " area: " << area << ", perimeter: " << perimeter << endl;
        rectangle(contourImage, boundingBox, Scalar(255, 0, 0), 2);
    }

    // 显示分析结果
    namedWindow("Analysis", WINDOW_AUTOSIZE);
    imshow("Analysis", contourImage);

    waitKey(0);
    return 0;
}

总结

本文详细介绍了如何使用C++和OpenCV来实现轮廓发现。我们从图像读取、预处理、轮廓发现、绘制轮廓到轮廓分析,逐步讲解了每个步骤的实现方法。通过这些步骤,你可以轻松地在自己的项目中实现轮廓发现功能。希望本文对你有所帮助!

推荐阅读:
  1. opencv3/C++轮廓的提取与筛选方式
  2. C++ OpenCV如何实现凸包检测

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

c++ opencv

上一篇:如何理解Socket的低层次Java网络编程

下一篇:C#如何实现基于Socket套接字的网络通信封装

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》