C++如何调用OpenCV完成运动目标捕捉,以下是详细攻略。
准备工作
在使用OpenCV前,需要安装OpenCV库。可以从OpenCV的官方网站(https://opencv.org/)下载,安装后需要在编译时链接到相关的库文件。
加载视频文件
首先需要加载视频文件,使用OpenCV中的cv::VideoCapture类。该类的构造函数接受视频文件路径作为参数,用于打开视频文件。
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
// 打开视频文件
VideoCapture cap("video.mp4");
return 0;
}
读取每一帧图像
使用cv::VideoCapture类的read方法,可以读取视频文件的每一帧图像,并用cv::Mat类型对象保存。
// 打开视频文件
VideoCapture cap("video.mp4");
Mat frame; // 保存读取到的每一帧图像
while (cap.read(frame)) // 循环读取每一帧图像
{
// 处理每一帧图像
...
}
提取运动目标
首先将第一帧图像作为背景帧,然后用当前帧图像与背景帧进行比较,计算差分图像,并对差分图像进行阈值处理,得到二值图像。最后使用cv::findContours函数查找二值图像中的轮廓。
Mat frame, foreground, background;
bool firstFrame = true;
while (cap.read(frame))
{
if (firstFrame)
{
// 第一帧作为背景
frame.copyTo(background);
firstFrame = false;
continue;
}
// 计算差分图像
absdiff(frame, background, foreground);
// 应用阈值,得到二值图像
threshold(foreground, foreground, 25, 255, THRESH_BINARY);
// 查找轮廓
vector<vector<Point> > contours;
findContours(foreground, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
...
}
绘制边框
在找到轮廓后,可以绘制边框,将运动目标框住。
Mat frame, foreground, background;
bool firstFrame = true;
while (cap.read(frame))
{
if (firstFrame)
{
// 第一帧作为背景
frame.copyTo(background);
firstFrame = false;
continue;
}
// 计算差分图像
absdiff(frame, background, foreground);
// 应用阈值,得到二值图像
threshold(foreground, foreground, 25, 255, THRESH_BINARY);
// 查找轮廓
vector<vector<Point> > contours;
findContours(foreground, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
// 绘制边框
for (int i = 0; i < contours.size(); i++)
{
Rect rect = boundingRect(contours[i]);
rectangle(frame, rect, Scalar(0, 255, 0), 2);
}
...
}
示例1:检测运动目标并保存图像
以下代码演示如何检测运动目标,并在运动目标框住时保存图像。
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
// 打开视频文件
VideoCapture cap("video.mp4");
Mat frame, foreground, background;
bool firstFrame = true;
int count = 0; // 计数器,用于生成文件名
while (cap.read(frame))
{
if (firstFrame)
{
// 第一帧作为背景
frame.copyTo(background);
firstFrame = false;
continue;
}
// 计算差分图像
absdiff(frame, background, foreground);
// 应用阈值,得到二值图像
threshold(foreground, foreground, 25, 255, THRESH_BINARY);
// 查找轮廓
vector<vector<Point> > contours;
findContours(foreground, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
// 绘制边框,保存图像
for (int i = 0; i < contours.size(); i++)
{
Rect rect = boundingRect(contours[i]);
// 保存运动目标图像
if (rect.area() > 1000)
{
Mat roi = frame(rect);
char filename[50];
sprintf(filename, "frame%d.jpg", count++);
imwrite(filename, roi);
}
rectangle(frame, rect, Scalar(0, 255, 0), 2);
}
imshow("Motion Detection", frame);
waitKey(30);
}
return 0;
}
示例2:检测运动目标并发出警报
以下代码演示如何检测运动目标,并在运动目标框住时发出警报。
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
// 打开视频文件
VideoCapture cap("video.mp4");
Mat frame, foreground, background;
bool firstFrame = true;
while (cap.read(frame))
{
if (firstFrame)
{
// 第一帧作为背景
frame.copyTo(background);
firstFrame = false;
continue;
}
// 计算差分图像
absdiff(frame, background, foreground);
// 应用阈值,得到二值图像
threshold(foreground, foreground, 25, 255, THRESH_BINARY);
// 查找轮廓
vector<vector<Point> > contours;
findContours(foreground, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
// 绘制边框,发出警报
bool motionDetected = false;
for (int i = 0; i < contours.size(); i++)
{
Rect rect = boundingRect(contours[i]);
if (rect.area() > 1000)
{
motionDetected = true;
}
rectangle(frame, rect, Scalar(0, 255, 0), 2);
}
if (motionDetected)
{
// 发出警报
putText(frame, "Motion Detected!", Point(10, 30), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 255), 2);
}
imshow("Motion Detection", frame);
waitKey(30);
}
return 0;
}
以上是C++如何调用OpenCV完成运动目标捕捉的详细攻略,希望对您有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++如何调用opencv完成运动目标捕捉详解 - Python技术站