C++使用OpenCV进行物体识别与检测的三种方法

 更新时间:2025年04月03日 08:46:02   作者:威哥说编程  
物体识别与检测是计算机视觉中的核心任务之一,它被广泛应用于自动驾驶、安防监控、图像分析等领域,通过物体检测技术,计算机能够从图像中识别出特定的物体或目标,本文将介绍如何使用 C++ 和 OpenCV 库进行物体识别与检测,需要的朋友可以参考下

1. OpenCV 环境配置回顾

在进行物体识别与检测之前,需要先确保安装并配置好 OpenCV 库。如果你还没有配置 OpenCV,可以参考以下步骤:

  1. 安装 OpenCV:你可以通过官网下载安装包,或者使用 vcpkg 或 conan 等包管理工具来安装 OpenCV。

  2. 配置 IDE:确保 IDE(如 Visual Studio 或 CLion)正确设置了 OpenCV 的路径,包含头文件路径和库文件路径。

2. Haar 特征分类器

Haar 特征分类器是一种基于机器学习的物体检测方法,最早用于人脸检测。OpenCV 提供了预训练的 Haar 分类器模型,可以快速进行人脸、眼睛、行人等物体的检测。

人脸检测

OpenCV 提供了多个预训练的分类器,如 haarcascade_frontalface_default.xml 用于人脸检测。我们可以直接加载这个分类器进行人脸检测。

#include <opencv2/opencv.hpp>
using namespace cv;
 
int main() {
    // 读取输入图像
    Mat image = imread("people.jpg");
 
    if (image.empty()) {
        std::cout << "Error loading image!" << std::endl;
        return -1;
    }
 
    // 将图像转换为灰度图
    Mat grayImage;
    cvtColor(image, grayImage, COLOR_BGR2GRAY);
 
    // 加载预训练的人脸分类器
    CascadeClassifier faceCascade;
    if (!faceCascade.load("haarcascade_frontalface_default.xml")) {
        std::cout << "Error loading cascade file!" << std::endl;
        return -1;
    }
 
    // 检测人脸
    std::vector<Rect> faces;
    faceCascade.detectMultiScale(grayImage, faces);
 
    // 绘制矩形框标记人脸
    for (size_t i = 0; i < faces.size(); i++) {
        rectangle(image, faces[i], Scalar(0, 255, 0), 2);
    }
 
    // 显示检测结果
    imshow("Detected Faces", image);
    waitKey(0);
 
    return 0;
}
  • CascadeClassifier::load() 方法用于加载预训练的 Haar 分类器文件。

  • detectMultiScale() 方法用于检测图像中的人脸,返回值是一个 Rect 向量,包含检测到的人脸矩形区域。

  • rectangle() 方法用来在图像上绘制矩形框。

其他分类器

OpenCV 提供了多种 Haar 分类器,用于检测眼睛、上半身、下半身等物体。例如:

CascadeClassifier eyeCascade;
eyeCascade.load("haarcascade_eye.xml");
eyeCascade.detectMultiScale(grayImage, eyes);

3. HOG 特征与行人检测

HOG(Histogram of Oriented Gradients)特征是另一种常用于物体检测的技术,特别适用于行人检测。OpenCV 中提供了一个 HOGDescriptor 类,用于提取 HOG 特征,并结合支持向量机(SVM)进行行人检测。

行人检测

#include <opencv2/opencv.hpp>
#include <opencv2/objdetect.hpp>
using namespace cv;
 
int main() {
    // 读取输入图像
    Mat image = imread("people.jpg");
 
    if (image.empty()) {
        std::cout << "Error loading image!" << std::endl;
        return -1;
    }
 
    // 创建 HOG 描述符
    HOGDescriptor hog;
    hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
 
    // 检测图像中的行人
    std::vector<Rect> foundLocations;
    hog.detectMultiScale(image, foundLocations);
 
    // 在图像中绘制检测到的行人位置
    for (size_t i = 0; i < foundLocations.size(); i++) {
        rectangle(image, foundLocations[i], Scalar(0, 255, 0), 2);
    }
 
    // 显示检测结果
    imshow("Detected People", image);
    waitKey(0);
 
    return 0;
}
  • HOGDescriptor 是用于提取 HOG 特征的 OpenCV 类,detectMultiScale() 方法用来进行行人检测。

  • getDefaultPeopleDetector() 是一个预训练的行人检测器。

4. 基于深度学习的物体检测

除了传统的机器学习方法,基于深度学习的物体检测已经成为主流。OpenCV 支持通过深度学习框架(如 Caffe、TensorFlow、ONNX)加载并使用预训练的深度学习模型进行物体检测。

使用预训练模型进行物体检测

以 YOLO(You Only Look Once)为例,YOLO 是一个非常流行的实时物体检测模型,它能够同时检测图像中的多个物体并返回类别与位置。OpenCV 支持加载和使用 YOLO 模型进行物体检测。

  1. 下载 YOLO 模型

    • 下载 YOLOv3 权重文件(yolov3.weights)和配置文件(yolov3.cfg)。

    • 下载 COCO 类别文件(coco.names)。

  2. 使用 YOLO 模型进行物体检测

#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
using namespace cv;
using namespace cv::dnn;
 
int main() {
    // 加载 YOLO 模型
    Net net = readNet("yolov3.weights", "yolov3.cfg");
    std::vector<String> outNames = net.getUnconnectedOutLayersNames();
 
    // 加载类别名称
    std::ifstream ifs("coco.names");
    std::vector<std::string> classes;
    std::string line;
    while (getline(ifs, line)) {
        classes.push_back(line);
    }
 
    // 读取输入图像
    Mat image = imread("image.jpg");
 
    // 转换图像为 YOLO 输入格式
    Mat blob = blobFromImage(image, 1 / 255.0, Size(416, 416), Scalar(), true, false);
 
    // 设置网络输入
    net.setInput(blob);
 
    // 获取 YOLO 输出
    std::vector<Mat> outs;
    net.forward(outs, outNames);
 
    // 处理输出
    for (size_t i = 0; i < outs.size(); i++) {
        Mat detectionMat = outs[i];
        for (int j = 0; j < detectionMat.rows; j++) {
            // 提取检测框信息(置信度、类标签、边界框)
            float confidence = detectionMat.at<float>(j, 4);
            if (confidence > 0.5) {  // 只显示置信度大于 0.5 的检测结果
                int classId = -1;
                float maxClassConf = -1;
                for (int k = 5; k < detectionMat.cols; k++) {
                    if (detectionMat.at<float>(j, k) > maxClassConf) {
                        maxClassConf = detectionMat.at<float>(j, k);
                        classId = k - 5;
                    }
                }
 
                // 计算边界框
                int x = int(detectionMat.at<float>(j, 0) * image.cols);
                int y = int(detectionMat.at<float>(j, 1) * image.rows);
                int width = int(detectionMat.at<float>(j, 2) * image.cols);
                int height = int(detectionMat.at<float>(j, 3) * image.rows);
 
                // 绘制边界框
                rectangle(image, Rect(x, y, width, height), Scalar(0, 255, 0), 2);
                putText(image, classes[classId], Point(x, y - 5), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 255, 0), 2);
            }
        }
    }
 
    // 显示检测结果
    imshow("YOLO Object Detection", image);
    waitKey(0);
 
    return 0;
}
  • readNet() 方法加载 YOLO 模型的权重和配置文件。

  • blobFromImage() 方法将输入图像转换为适合 YOLO 模型的输入格式。

  • forward() 方法执行前向推理,获取检测结果。

  • 根据 YOLO 输出的边界框、置信度和类别信息,我们可以在图像上绘制边界框并显示物体类别。

5. 总结

在本文中,我们介绍了如何使用 C++ 和 OpenCV 进行物体识别与检测。我们覆盖了以下几种常见的方法:

  • Haar 特征分类器:用于人脸、眼睛等物体检测,适合实时检测任务。

  • HOG 特征与行人检测:利用 HOG 特征结合 SVM 进行行人检测。

  • 基于深度学习的物体检测:使用 YOLO 等深度学习模型进行物体检测,能够识别多种物体并返回其类别和位置。

这些方法适用于不同的应用场景,可以根据具体需求选择合适的算法和模型。在未来的开发中,物体检测技术将继续发挥重要作用,助力人工智能的进一步发展。

以上就是C++使用OpenCV进行物体识别与检测的三种方法的详细内容,更多关于C++ OpenCV物体识别与检测的资料请关注脚本之家其它相关文章!

相关文章

  • C++动态内存分配的核心机制与最佳实践(从对象生命周期到智能管理)

    C++动态内存分配的核心机制与最佳实践(从对象生命周期到智能管理)

    C++的动态内存分配机制通过new/delete和智能指针实现了对象生命周期的管理,解决了C语言中内存与对象状态脱节的问题,本文将系统梳理C++动态内存分配的核心机制、使用规范与最佳实践,感兴趣的朋友一起看看吧
    2026-01-01
  • C语言图书管理系统简洁版

    C语言图书管理系统简洁版

    这篇文章主要为大家详细介绍了C语言图书管理系统简洁版,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • 关于C++中的友元函数的一些总结

    关于C++中的友元函数的一些总结

    以下是对C++中的友元函数进行了详细的总结介绍,需要的朋友可以过来参考下
    2013-09-09
  • c++面试题字符串拷贝函数示例

    c++面试题字符串拷贝函数示例

    这个也算是企业招工里面比较常见的一道笔试面试题了,非常简单。个人觉得考的主要是对指针使用的熟练程度,还有对字符串类内部原理的掌握程度
    2013-12-12
  • vs code 配置python虚拟环境的方法

    vs code 配置python虚拟环境的方法

    这篇文章主要介绍了vs code 配置python虚拟环境的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • C++数据结构之链表的创建

    C++数据结构之链表的创建

    这篇文章主要介绍了C++数据结构之链表的创建的相关资料,希望通过本文帮助到大家,让大家理解掌握这部分内容,需要的朋友可以参考下
    2017-10-10
  • C语言递归宏的具体使用

    C语言递归宏的具体使用

    本文介绍了阶段进行多次符号替换,从而模拟递归效果,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-11-11
  • c语言实现找最大值最小值位置查找

    c语言实现找最大值最小值位置查找

    这篇文章主要介绍了c语言实现找最大值最小值位置查找,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • 五个经典链表OJ题带你进阶C++链表篇

    五个经典链表OJ题带你进阶C++链表篇

    做题之前呢,小编想提醒下大家,要三思而后行,不要一上来就嘎嘎敲代码,要先学会自己画图分析,把自己的思路捋清楚,不要到时候写代码五分钟,调试两小时,记住,编程思路很重要
    2022-03-03
  • C语言命令行参数的使用详解

    C语言命令行参数的使用详解

    本文主要介绍了C语言命令行参数的使用详解,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07

最新评论