C++ OpenCV Project Practice

OpenCV project practice is the process of applying theoretical knowledge to real-world problems.

Through project practice, you can solidify your OpenCV skills and solve real-world computer vision problems.

The following are common types of OpenCV projects:

  1. Image Processing Projects: such as image filters, image inpainting, image enhancement, etc.

  2. Object Detection and Tracking Projects: such as face detection, license plate recognition, moving target tracking, etc.

  3. Deep Learning Projects: such as image classification, object detection, semantic segmentation, etc.

  4. Video Processing Projects: such as video analysis, real-time video processing, video effects, etc.


Simple Projects

Image Filter Application

Image filters are one of the basic operations in image processing. By applying different filters, you can change the appearance and style of an image.

OpenCV provides rich functions to implement various image filter effects.

Grayscale Filter

The grayscale filter is the process of converting a color image to a grayscale image. A grayscale image has only one channel, and the value of each pixel represents brightness.

Example

#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;
}

Gaussian Blur

Gaussian blur is a commonly used blur filter that can effectively remove noise from an image.

Example

#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;
}

The following example implements an image filter application that supports multiple filter effects (such as grayscale, blur, edge detection, etc.).

Example

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

using namespace cv;
using namespace std;

int main() {
    // Read image
    Mat image = imread("image.jpg");
    if (image.empty()) {
        cout << "Error: Unable to load image, please check whether the path is correct." << endl;
        return -1;
    }

    // Convert to grayscale
    Mat gray;
    cvtColor(image, gray, COLOR_BGR2GRAY);

    // Gaussian blur
    Mat blurred;
    GaussianBlur(image, blurred, Size(15, 15), 0);

    // Edge detection
    Mat edges;
    Canny(image, edges, 100, 200);

    // Display result
    imshow("Original Image", image);
    imshow("Gray Image", gray);
    imshow("Blurred Image", blurred);
    imshow("Edges", edges);

    // Save result
    imwrite("gray_image.jpg", gray);
    imwrite("blurred_image.jpg", blurred);
    imwrite("edges.jpg", edges);

    waitKey(0);
    return 0;
}

Real-time Face Detection

Real-time face detection is an important application in computer vision.

OpenCV provides a pre-trained Haar cascade classifier that can be used to detect faces in images or videos.

Implementation steps:

  1. Load the Haar cascade classifier model.

  2. Open the camera or video file.

  3. Perform face detection on each frame.

  4. Draw the detection results and display them.

Example

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

using namespace cv;
using namespace std;

int main() {
    // Load Haar cascade classifier
    CascadeClassifier faceCascade;
    if (!faceCascade.load("haarcascade_frontalface_default.xml")) {
        cout << "Error: Unable to load Haar cascade classifier!" << endl;
        return -1;
    }

    // Open camera
    VideoCapture cap(0);
    if (!cap.isOpened()) {
        cout << "Error: Unable to open camera!" << endl;
        return -1;
    }

    // Detect faces in real time
    Mat frame;
    while (true) {
        cap >> frame;
        if (frame.empty()) break;

        // Convert to grayscale image
        Mat gray;
        cvtColor(frame, gray, COLOR_BGR2GRAY);

        // Detect faces
        vector<Rect> faces;
        faceCascade.detectMultiScale(gray, faces, 1.1, 3, 0, Size(30, 30));

        // Draw detection results
        for (const auto& face : faces) {
            rectangle(frame, face, Scalar(0, 255, 0), 2);
        }

        // Display result
        imshow("Face Detection", frame);

        // Press ESC to exit
        if (waitKey(30) == 27) break;
    }

    // Release resources
    cap.release();
    destroyAllWindows();

    return 0;
}

License Plate Recognition

License plate recognition is one of the key technologies in intelligent transportation systems.

OpenCV can be used for license plate detection and character recognition.

Example

#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;
}

Complex Projects

OpenCV-Based AR Application

Augmented reality (AR) is a technology that overlays virtual information onto the real world.

OpenCV can be used to implement simple AR applications, such as overlaying virtual objects onto images.

Example

#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;
}

Video Surveillance and Motion Detection

Video surveillance and motion detection are important functions in security monitoring systems. OpenCV can be used to detect moving objects in videos.

Example

#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;
}

Multi-Object Tracking

Multi-object tracking is a complex problem in computer vision, involving the simultaneous tracking of multiple objects in a video. OpenCV provides several tracking algorithms, such as KCF, MIL, and CSRT.

Example

#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;
}

Deep Learning Projects: Object Detection (YOLO)

Use the YOLO model to implement object detection.

Implementation steps:

  1. Load the YOLO model and configuration file.

  2. Load class labels.

  3. Preprocess the input image.

  4. Run the model and parse the detection results.

  5. Draw bounding boxes and display the results.

Example

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

using namespace cv;
using namespace dnn;
using namespace std;

int main() {
    // Load YOLO model
    Net net = readNet("yolov3.weights", "yolov3.cfg");
    if (net.empty()) {
        cout << "Error: Unable to load YOLO model!" << endl;
        return -1;
    }

    // Load class labels
    ifstream classNamesFile("coco.names");
    vector<string> classNames;
    string className;
    while (getline(classNamesFile, className)) {
        classNames.push_back(className);
    }

    // Load image
    Mat image = imread("image.jpg");
    if (image.empty()) {
        cout << "Error: Unable to load image, please check whether the path is correct." << endl;
        return -1;
    }

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

    // Forward pass
    vector<Mat> outs;
    net.forward(outs, net.getUnconnectedOutLayersNames());

    // Parse detection results
    float confThreshold = 0.5; // Confidence threshold
    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));
            }
        }
    }

    // Non-maximum suppression
    float nmsThreshold = 0.4; // NMS threshold
    vector<int> indices;
    NMSBoxes(boxes, confidences, confThreshold, nmsThreshold, indices);

    // Draw detection results
    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);
    }

    // Display result
    imshow("Object Detection", image);
    waitKey(0);

    return 0;
}

Video Processing Projects: Real-time Video Effects

Implement a real-time video effects application that supports multiple effects (such as edge detection, blur, color inversion, etc.).

Implementation steps:

  1. Open the camera or video file.

  2. Apply effects to each frame.

  3. Display the processed video.

Example

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

using namespace cv;
using namespace std;

int main() {
    // Open camera
    VideoCapture cap(0);
    if (!cap.isOpened()) {
        cout << "Error: Unable to open camera!" << endl;
        return -1;
    }

    // Process video frames in real time
    Mat frame, edges;
    while (true) {
        cap >> frame;
        if (frame.empty()) break;

        // Edge detection
        Canny(frame, edges, 100, 200);

        // Display result
        imshow("Original Frame", frame);
        imshow("Edges", edges);

        // Press ESC to exit
        if (waitKey(30) == 27) break;
    }

    // Release resources
    cap.release();
    destroyAllWindows();

    return 0;
}
Other Extensions