Skip to content

C++ OpenCV 项目实战

OpenCV 项目实战是将理论知识应用于实际问题的过程。

通过项目实战,可以巩固 OpenCV 的使用技能,并解决现实中的计算机视觉问题。

以下是常见的 OpenCV 项目类型:

  1. 图像处理类项目:如图像滤镜、图像修复、图像增强等。

  2. 目标检测与跟踪类项目:如人脸检测、车牌识别、运动目标跟踪等。

  3. 深度学习类项目:如图像分类、目标检测、语义分割等。

  4. 视频处理类项目:如视频分析、实时视频处理、视频特效等。


简单项目

图像滤镜应用

图像滤镜是图像处理中的基础操作之一,通过应用不同的滤镜,可以改变图像的外观和风格。

OpenCV 提供了丰富的函数来实现各种图像滤镜效果。

灰度滤镜

灰度滤镜是将彩色图像转换为灰度图像的过程。灰度图像只有一个通道,每个像素的值表示亮度。

实例

python
#include <opencv2/opencv.hpp>

int main() {

    cv::Mat image = cv::imread("input.jpg");

    cv::Mat grayImage;

    cv::cvtColor(image, grayImage, cv::COLOR_BGR2GRAY);

    cv::imwrite("gray_output.jpg", grayImage);

    return 0;

}

高斯模糊

高斯模糊是一种常用的模糊滤镜,它可以有效地去除图像中的噪声。

实例

python
#include <opencv2/opencv.hpp>

int main() {

    cv::Mat image = cv::imread("input.jpg");

    cv::Mat blurredImage;

    cv::GaussianBlur(image, blurredImage, cv::Size(15, 15), 0);

    cv::imwrite("blurred_output.jpg", blurredImage);

    return 0;

}

以下实例实现一个图像滤镜应用,支持多种滤镜效果(如灰度化、模糊、边缘检测等)。

实例

python
#include <opencv2/opencv.hpp>

#include <iostream>

using namespace cv;

using namespace std;

int main() {

    // 读取图像

    Mat image = imread("image.jpg");

    if (image.empty()) {

        cout << "错误:无法加载图像,请检查路径是否正确。" << endl;

        return -1;

    }

    // 灰度化

    Mat gray;

    cvtColor(image, gray, COLOR_BGR2GRAY);

    // 高斯模糊

    Mat blurred;

    GaussianBlur(image, blurred, Size(15, 15), 0);

    // 边缘检测

    Mat edges;

    Canny(image, edges, 100, 200);

    // 显示结果

    imshow("Original Image", image);

    imshow("Gray Image", gray);

    imshow("Blurred Image", blurred);

    imshow("Edges", edges);

    // 保存结果

    imwrite("gray_image.jpg", gray);

    imwrite("blurred_image.jpg", blurred);

    imwrite("edges.jpg", edges);

    waitKey(0);

    return 0;

}

实时人脸检测

实时人脸检测是计算机视觉中的一个重要应用。

OpenCV 提供了预训练的 Haar 级联分类器,可以用于检测图像或视频中的人脸。

实现步骤:

  1. 加载 Haar 级联分类器模型。

  2. 打开摄像头或视频文件。

  3. 对每一帧进行人脸检测。

  4. 绘制检测结果并显示。

实例

python
#include <opencv2/opencv.hpp>

#include <iostream>

using namespace cv;

using namespace std;

int main() {

    // 加载 Haar 级联分类器

    CascadeClassifier faceCascade;

    if (!faceCascade.load("haarcascade_frontalface_default.xml")) {

        cout << "错误:无法加载 Haar 级联分类器!" << endl;

        return -1;

    }

    // 打开摄像头

    VideoCapture cap(0);

    if (!cap.isOpened()) {

        cout << "错误:无法打开摄像头!" << endl;

        return -1;

    }

    // 实时检测人脸

    Mat frame;

    while (true) {

        cap >> frame;

        if (frame.empty()) break;

        // 转换为灰度图像

        Mat gray;

        cvtColor(frame, gray, COLOR_BGR2GRAY);

        // 检测人脸

        vector<Rect> faces;

        faceCascade.detectMultiScale(gray, faces, 1.1, 3, 0, Size(30, 30));

        // 绘制检测结果

        for (const auto& face : faces) {

            rectangle(frame, face, Scalar(0, 255, 0), 2);

        }

        // 显示结果

        imshow("Face Detection", frame);

        // 按下 ESC 键退出

        if (waitKey(30) == 27) break;

    }

    // 释放资源

    cap.release();

    destroyAllWindows();

    return 0;

}

车牌识别

车牌识别是智能交通系统中的关键技术之一。

OpenCV 可以用于车牌检测和字符识别。

实例

javascript
#include <opencv2/opencv.hpp>

int main() {

    cv::Mat image = cv::imread("car.jpg");

    cv::Mat grayImage;

    cv::cvtColor(image, grayImage, cv::COLOR_BGR2GRAY);

    cv::CascadeClassifier plateCascade;

    plateCascade.load("haarcascade_russian_plate_number.xml");

    std::vector<cv::Rect> plates;

    plateCascade.detectMultiScale(grayImage, plates, 1.1, 2, 0 | cv::CASCADE_SCALE_IMAGE, cv::Size(30, 30));

    for (const auto& plate : plates) {

        cv::rectangle(image, plate, cv::Scalar(0, 255, 0), 2);

    }

    cv::imwrite("plate_output.jpg", image);

    return 0;

}

复杂项目

基于 OpenCV 的 AR 应用

增强现实(AR)是一种将虚拟信息叠加到现实世界中的技术。

OpenCV 可以用于实现简单的 AR 应用,例如在图像上叠加虚拟物体。

实例

python
#include <opencv2/opencv.hpp>

int main() {

    cv::Mat image = cv::imread("background.jpg");

    cv::Mat overlay = cv::imread("overlay.png", cv::IMREAD_UNCHANGED);

    cv::resize(overlay, overlay, cv::Size(100, 100));

    cv::Mat roi = image(cv::Rect(50, 50, overlay.cols, overlay.rows));

    overlay.copyTo(roi, overlay);

    cv::imwrite("ar_output.jpg", image);

    return 0;

}

视频监控与运动检测

视频监控与运动检测是安全监控系统中的重要功能。OpenCV 可以用于检测视频中的运动物体。

实例

python
#include <opencv2/opencv.hpp>

int main() {

    cv::VideoCapture cap(0);

    if (!cap.isOpened()) {

        std::cerr << "Error opening video stream" << std::endl;

        return -1;

    }

    cv::Mat frame, prevFrame, diffFrame;

    cap >> prevFrame;

    cv::cvtColor(prevFrame, prevFrame, cv::COLOR_BGR2GRAY);

    while (true) {

        cap >> frame;

        if (frame.empty()) break;

        cv::Mat grayFrame;

        cv::cvtColor(frame, grayFrame, cv::COLOR_BGR2GRAY);

        cv::absdiff(grayFrame, prevFrame, diffFrame);

        cv::threshold(diffFrame, diffFrame, 30, 255, cv::THRESH_BINARY);

        cv::imshow("Motion Detection", diffFrame);

        if (cv::waitKey(1) == 27) break; // ESC key to exit

        prevFrame = grayFrame.clone();

    }

    cap.release();

    cv::destroyAllWindows();

    return 0;

}

多目标跟踪

多目标跟踪是计算机视觉中的一个复杂问题,涉及在视频中同时跟踪多个目标。OpenCV 提供了多种跟踪算法,例如 KCF、MIL 和 CSRT。

实例

javascript
#include <opencv2/opencv.hpp>

#include <opencv2/tracking.hpp>

int main() {

    cv::VideoCapture cap("video.mp4");

    if (!cap.isOpened()) {

        std::cerr << "Error opening video stream" << std::endl;

        return -1;

    }

    cv::Ptr<cv::MultiTracker> multiTracker = cv::MultiTracker::create();

    cv::Mat frame;

    cap >> frame;

    std::vector<cv::Rect> bboxes;

    cv::selectROIs("Tracking", frame, bboxes);

    for (const auto& bbox : bboxes) {

        multiTracker->add(cv::TrackerKCF::create(), frame, bbox);

    }

    while (true) {

        cap >> frame;

        if (frame.empty()) break;

        multiTracker->update(frame);

        for (const auto& bbox : multiTracker->getObjects()) {

            cv::rectangle(frame, bbox, cv::Scalar(255, 0, 0), 2);

        }

        cv::imshow("Multi-Object Tracking", frame);

        if (cv::waitKey(1) == 27) break; // ESC key to exit

    }

    cap.release();

    cv::destroyAllWindows();

    return 0;

}

深度学习类项目:目标检测(YOLO)

使用 YOLO 模型实现目标检测。

实现步骤:

  1. 加载 YOLO 模型和配置文件。

  2. 加载类别标签。

  3. 对输入图像进行预处理。

  4. 运行模型并解析检测结果。

  5. 绘制检测框并显示结果。

实例

python
#include <opencv2/opencv.hpp>

#include <opencv2/dnn.hpp>

#include <iostream>

using namespace cv;

using namespace dnn;

using namespace std;

int main() {

    // 加载 YOLO 模型

    Net net = readNet("yolov3.weights", "yolov3.cfg");

    if (net.empty()) {

        cout << "错误:无法加载 YOLO 模型!" << endl;

        return -1;

    }

    // 加载类别标签

    ifstream classNamesFile("coco.names");

    vector<string> classNames;

    string className;

    while (getline(classNamesFile, className)) {

        classNames.push_back(className);

    }

    // 加载图像

    Mat image = imread("image.jpg");

    if (image.empty()) {

        cout << "错误:无法加载图像,请检查路径是否正确。" << endl;

        return -1;

    }

    // 预处理图像

    Mat blob = blobFromImage(image, 1 / 255.0, Size(416, 416), Scalar(0, 0, 0), true, false);

    net.setInput(blob);

    // 前向传播

    vector<Mat> outs;

    net.forward(outs, net.getUnconnectedOutLayersNames());

    // 解析检测结果

    float confThreshold = 0.5; // 置信度阈值

    vector<int> classIds;

    vector<float> confidences;

    vector<Rect> boxes;

    for (const auto& output : outs) {

        for (int i = 0; i < output.rows; i++) {

            Mat scores = output.row(i).colRange(5, output.cols);

            Point classIdPoint;

            double confidence;

            minMaxLoc(scores, nullptr, &confidence, nullptr, &classIdPoint);

            if (confidence > confThreshold) {

                int centerX = static_cast<int>(output.at<float>(i, 0) * image.cols);

                int centerY = static_cast<int>(output.at<float>(i, 1) * image.rows);

                int width = static_cast<int>(output.at<float>(i, 2) * image.cols);

                int height = static_cast<int>(output.at<float>(i, 3) * image.rows);

                int left = centerX - width / 2;

                int top = centerY - height / 2;

                classIds.push_back(classIdPoint.x);

                confidences.push_back(static_cast<float>(confidence));

                boxes.push_back(Rect(left, top, width, height));

            }

        }

    }

    // 非极大值抑制

    float nmsThreshold = 0.4; // NMS 阈值

    vector<int> indices;

    NMSBoxes(boxes, confidences, confThreshold, nmsThreshold, indices);

    // 绘制检测结果

    for (int idx : indices) {

        Rect box = boxes[idx];

        rectangle(image, box, Scalar(0, 255, 0), 2);

        string label = format("%s: %.2f", classNames[classIds[idx]].c_str(), confidences[idx]);

        putText(image, label, Point(box.x, box.y - 10), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0), 2);

    }

    // 显示结果

    imshow("Object Detection", image);

    waitKey(0);

    return 0;

}

视频处理类项目:实时视频特效

实现一个实时视频特效应用,支持多种特效(如边缘检测、模糊、颜色反转等)。

实现步骤:

  1. 打开摄像头或视频文件。

  2. 对每一帧应用特效。

  3. 显示处理后的视频。

实例

python
#include <opencv2/opencv.hpp>

#include <iostream>

using namespace cv;

using namespace std;

int main() {

    // 打开摄像头

    VideoCapture cap(0);

    if (!cap.isOpened()) {

        cout << "错误:无法打开摄像头!" << endl;

        return -1;

    }

    // 实时处理视频帧

    Mat frame, edges;

    while (true) {

        cap >> frame;

        if (frame.empty()) break;

        // 边缘检测

        Canny(frame, edges, 100, 200);

        // 显示结果

        imshow("Original Frame", frame);

        imshow("Edges", edges);

        // 按下 ESC 键退出

        if (waitKey(30) == 27) break;

    }

    // 释放资源

    cap.release();

    destroyAllWindows();

    return 0;

}

AI 思考中...

C++ OpenCV 机器学习与深度学习

C++ OpenCV 性能优化

基于 VitePress 构建,部署于 GitHub Pages