C++ OpenCV 项目实战
OpenCV 项目实战是将理论知识应用于实际问题的过程。
通过项目实战,可以巩固 OpenCV 的使用技能,并解决现实中的计算机视觉问题。
以下是常见的 OpenCV 项目类型:
图像处理类项目:如图像滤镜、图像修复、图像增强等。
目标检测与跟踪类项目:如人脸检测、车牌识别、运动目标跟踪等。
深度学习类项目:如图像分类、目标检测、语义分割等。
视频处理类项目:如视频分析、实时视频处理、视频特效等。
简单项目
图像滤镜应用
图像滤镜是图像处理中的基础操作之一,通过应用不同的滤镜,可以改变图像的外观和风格。
OpenCV 提供了丰富的函数来实现各种图像滤镜效果。
灰度滤镜
灰度滤镜是将彩色图像转换为灰度图像的过程。灰度图像只有一个通道,每个像素的值表示亮度。
实例
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;
}
高斯模糊
高斯模糊是一种常用的模糊滤镜,它可以有效地去除图像中的噪声。
实例
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;
}
以下实例实现一个图像滤镜应用,支持多种滤镜效果(如灰度化、模糊、边缘检测等)。
实例
#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 级联分类器,可以用于检测图像或视频中的人脸。
实现步骤:
加载 Haar 级联分类器模型。
打开摄像头或视频文件。
对每一帧进行人脸检测。
绘制检测结果并显示。
实例
#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 可以用于车牌检测和字符识别。
实例
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 应用,例如在图像上叠加虚拟物体。
实例
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 可以用于检测视频中的运动物体。
实例
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。
实例
#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 模型实现目标检测。
实现步骤:
加载 YOLO 模型和配置文件。
加载类别标签。
对输入图像进行预处理。
运行模型并解析检测结果。
绘制检测框并显示结果。
实例
#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;
}
视频处理类项目:实时视频特效
实现一个实时视频特效应用,支持多种特效(如边缘检测、模糊、颜色反转等)。
实现步骤:
打开摄像头或视频文件。
对每一帧应用特效。
显示处理后的视频。
实例
#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;
}