C++ OpenCV怎么实现形状识别功能

发布时间:2022-07-11 10:15:01 作者:iii
来源:亿速云 阅读:309

C++ OpenCV怎么实现形状识别功能

引言

在计算机视觉领域,形状识别是一个非常重要的任务。通过识别图像中的形状,我们可以实现物体检测、目标跟踪、图像分割等多种应用。OpenCV 是一个功能强大的开源计算机视觉库,提供了丰富的图像处理和计算机视觉算法。本文将详细介绍如何使用 C++ 和 OpenCV 实现形状识别功能。

1. 准备工作

在开始之前,我们需要确保已经安装了 OpenCV 库。如果还没有安装,可以参考 OpenCV 的官方文档进行安装。

1.1 安装 OpenCV

在 Ubuntu 系统上,可以使用以下命令安装 OpenCV:

sudo apt-get update
sudo apt-get install libopencv-dev

在 Windows 系统上,可以从 OpenCV 官网下载预编译的库,并配置开发环境。

1.2 创建 C++ 项目

创建一个新的 C++ 项目,并在项目中包含 OpenCV 的头文件和库文件。例如,在 CMake 项目中,可以这样配置 CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(ShapeRecognition)

set(CMAKE_CXX_STANDARD 14)

find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})

add_executable(ShapeRecognition main.cpp)

target_link_libraries(ShapeRecognition ${OpenCV_LIBS})

2. 图像预处理

在进行形状识别之前,通常需要对图像进行一些预处理操作,以提高识别的准确性。常见的预处理步骤包括灰度化、二值化、去噪等。

2.1 读取图像

首先,我们需要读取一张图像。可以使用 OpenCV 的 imread 函数来读取图像:

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

int main() {
    cv::Mat image = cv::imread("image.jpg");
    if (image.empty()) {
        std::cerr << "Could not open or find the image!" << std::endl;
        return -1;
    }
    cv::imshow("Original Image", image);
    cv::waitKey(0);
    return 0;
}

2.2 灰度化

将彩色图像转换为灰度图像可以减少计算量,并且在一些情况下可以提高形状识别的效果。可以使用 cvtColor 函数将图像转换为灰度图像:

cv::Mat grayImage;
cv::cvtColor(image, grayImage, cv::COLOR_BGR2GRAY);
cv::imshow("Gray Image", grayImage);
cv::waitKey(0);

2.3 二值化

二值化是将灰度图像转换为黑白图像的过程。可以使用 threshold 函数进行二值化:

cv::Mat binaryImage;
cv::threshold(grayImage, binaryImage, 128, 255, cv::THRESH_BINARY);
cv::imshow("Binary Image", binaryImage);
cv::waitKey(0);

2.4 去噪

去噪是为了去除图像中的噪声,使得形状更加清晰。可以使用 GaussianBlur 函数进行高斯模糊:

cv::Mat blurredImage;
cv::GaussianBlur(binaryImage, blurredImage, cv::Size(5, 5), 0);
cv::imshow("Blurred Image", blurredImage);
cv::waitKey(0);

3. 形状检测

在图像预处理之后,我们可以开始进行形状检测。OpenCV 提供了多种方法来检测图像中的形状,常用的方法包括轮廓检测和霍夫变换。

3.1 轮廓检测

轮廓检测是检测图像中物体边界的一种方法。可以使用 findContours 函数来检测图像中的轮廓:

std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> hierarchy;
cv::findContours(blurredImage, contours, hierarchy, cv::RETR_TREE, cv::CHN_APPROX_SIMPLE);

cv::Mat contourImage = cv::Mat::zeros(blurredImage.size(), CV_8UC3);
for (size_t i = 0; i < contours.size(); i++) {
    cv::drawContours(contourImage, contours, i, cv::Scalar(0, 255, 0), 2);
}
cv::imshow("Contours", contourImage);
cv::waitKey(0);

3.2 形状识别

通过检测到的轮廓,我们可以进一步识别出图像中的形状。常见的形状包括圆形、矩形、三角形等。可以通过计算轮廓的几何特性来识别形状。

3.2.1 识别圆形

识别圆形可以使用 minEnclosingCircle 函数来计算轮廓的最小外接圆:

for (size_t i = 0; i < contours.size(); i++) {
    cv::Point2f center;
    float radius;
    cv::minEnclosingCircle(contours[i], center, radius);
    if (radius > 10) {  // 过滤掉太小的圆
        cv::circle(contourImage, center, radius, cv::Scalar(255, 0, 0), 2);
    }
}
cv::imshow("Circles", contourImage);
cv::waitKey(0);

3.2.2 识别矩形

识别矩形可以使用 approxPolyDP 函数来近似轮廓的多边形,并判断是否为矩形:

for (size_t i = 0; i < contours.size(); i++) {
    std::vector<cv::Point> approx;
    cv::approxPolyDP(contours[i], approx, cv::arcLength(contours[i], true) * 0.02, true);
    if (approx.size() == 4) {  // 判断是否为四边形
        cv::drawContours(contourImage, std::vector<std::vector<cv::Point>>{approx}, -1, cv::Scalar(0, 0, 255), 2);
    }
}
cv::imshow("Rectangles", contourImage);
cv::waitKey(0);

3.2.3 识别三角形

识别三角形可以通过判断轮廓的顶点数是否为 3:

for (size_t i = 0; i < contours.size(); i++) {
    std::vector<cv::Point> approx;
    cv::approxPolyDP(contours[i], approx, cv::arcLength(contours[i], true) * 0.02, true);
    if (approx.size() == 3) {  // 判断是否为三角形
        cv::drawContours(contourImage, std::vector<std::vector<cv::Point>>{approx}, -1, cv::Scalar(255, 255, 0), 2);
    }
}
cv::imshow("Triangles", contourImage);
cv::waitKey(0);

3.3 霍夫变换

霍夫变换是一种用于检测图像中直线、圆等几何形状的方法。OpenCV 提供了 HoughLinesHoughCircles 函数来检测直线和圆。

3.3.1 检测直线

可以使用 HoughLines 函数来检测图像中的直线:

std::vector<cv::Vec2f> lines;
cv::HoughLines(blurredImage, lines, 1, CV_PI / 180, 150);

cv::Mat lineImage = cv::Mat::zeros(blurredImage.size(), CV_8UC3);
for (size_t i = 0; i < lines.size(); i++) {
    float rho = lines[i][0], theta = lines[i][1];
    cv::Point pt1, pt2;
    double a = cos(theta), b = sin(theta);
    double x0 = a * rho, y0 = b * rho;
    pt1.x = cvRound(x0 + 1000 * (-b));
    pt1.y = cvRound(y0 + 1000 * (a));
    pt2.x = cvRound(x0 - 1000 * (-b));
    pt2.y = cvRound(y0 - 1000 * (a));
    cv::line(lineImage, pt1, pt2, cv::Scalar(0, 0, 255), 2);
}
cv::imshow("Lines", lineImage);
cv::waitKey(0);

3.3.2 检测圆

可以使用 HoughCircles 函数来检测图像中的圆:

std::vector<cv::Vec3f> circles;
cv::HoughCircles(blurredImage, circles, cv::HOUGH_GRADIENT, 1, blurredImage.rows / 8, 200, 100, 0, 0);

cv::Mat circleImage = cv::Mat::zeros(blurredImage.size(), CV_8UC3);
for (size_t i = 0; i < circles.size(); i++) {
    cv::Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
    int radius = cvRound(circles[i][2]);
    cv::circle(circleImage, center, radius, cv::Scalar(0, 255, 0), 2);
}
cv::imshow("Circles", circleImage);
cv::waitKey(0);

4. 结果展示

在完成形状识别之后,我们可以将识别结果展示出来。可以将识别到的形状在原图上标注出来,以便直观地查看识别效果。

cv::Mat resultImage = image.clone();
for (size_t i = 0; i < contours.size(); i++) {
    std::vector<cv::Point> approx;
    cv::approxPolyDP(contours[i], approx, cv::arcLength(contours[i], true) * 0.02, true);
    if (approx.size() == 3) {
        cv::drawContours(resultImage, std::vector<std::vector<cv::Point>>{approx}, -1, cv::Scalar(255, 255, 0), 2);
    } else if (approx.size() == 4) {
        cv::drawContours(resultImage, std::vector<std::vector<cv::Point>>{approx}, -1, cv::Scalar(0, 0, 255), 2);
    } else {
        cv::Point2f center;
        float radius;
        cv::minEnclosingCircle(contours[i], center, radius);
        if (radius > 10) {
            cv::circle(resultImage, center, radius, cv::Scalar(255, 0, 0), 2);
        }
    }
}
cv::imshow("Result", resultImage);
cv::waitKey(0);

5. 总结

本文详细介绍了如何使用 C++ 和 OpenCV 实现形状识别功能。通过图像预处理、轮廓检测、形状识别等步骤,我们可以有效地识别出图像中的各种形状。OpenCV 提供了丰富的函数和算法,使得形状识别变得相对简单。希望本文能够帮助读者理解和掌握形状识别的基本方法,并在实际项目中应用这些技术。

6. 参考文献


通过以上步骤,您可以使用 C++ 和 OpenCV 实现基本的形状识别功能。希望这篇文章对您有所帮助!

推荐阅读:
  1. OpenCV中几何形状识别与测量
  2. Python Opencv实现图像轮廓识别功能

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

c++ opencv

上一篇:glow工具在命令行怎么读取Markdown

下一篇:JS前端架构pnpm怎么构建Monorepo方式管理demo

相关阅读

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

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