文章目录
- 前言
- 一、效果展示
- 二、实现方法
- 构造形态学操作所需的核:
- 创建背景减除模型:
- 形态学操作:
- 轮廓检测:
- 三、代码
- python代码
- C++代码
- 总结
- 参考文档
前言
很久没更新文章了,这次因为工作场景需要检测动态目标,特此记录一下。
一、效果展示
二、实现方法
基于OpenCV库的背景减除方法实现的视频中的移动目标检测示例。通过从输入视频中提取前景目标,然后在特定区域内绘制检测到的移动物体的边界框。主要函数方法如下:
构造形态学操作所需的核:
cv2.getStructuringElement
: 创建形态学操作所需的结构元素,这里使用椭圆形的结构元素。
创建背景减除模型:
cv2.createBackgroundSubtractorMOG2()
: 创建一个高斯混合模型背景减除器,用于提取视频中的前景。
形态学操作:
cv2.morphologyEx(fgmk, cv2.MORPH_OPEN, kernel)
: 对前景图像进行形态学开运算,用于去除噪声并平滑前景目标。
轮廓检测:
cv2.findContours(fgmk.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
: 寻找前景图像中的轮廓。
三、代码
需要根据自己的视频适当微调参数
python代码
import cv2
import numpy as npdef main(path):# 第一步:使用cv2.VideoCapture读取视频camera = cv2.VideoCapture(path)width = int(camera.get(cv2.CAP_PROP_FRAME_WIDTH))height = int(camera.get(cv2.CAP_PROP_FRAME_HEIGHT))per_width = int(width / 4)per_height = int(height / 2)# 第二步:cv2.getStructuringElement构造形态学使用的kernelkernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))# 第三步:构造高斯混合模型model = cv2.createBackgroundSubtractorMOG2()# model = cv2.createBackgroundSubtractorKNN()# 设定区域,后面可以用于判断是否在区域内(可以设置为多边形)contour = np.array([[0, 0], [3 * per_width, per_height], [3 * per_width, height], [0, height]])while True:# 第四步:读取视频中的图片,并使用高斯模型进行拟合ret, frame = camera.read()# 运用高斯模型进行拟合,在两个标准差内设置为0,在两个标准差外设置为255fgmk = model.apply(frame)# 第五步:使用形态学的开运算做背景的去除fgmk = cv2.morphologyEx(fgmk, cv2.MORPH_OPEN, kernel)# 第六步:cv2.findContours计算fgmk的轮廓contours, hierarchy = cv2.findContours(fgmk.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) # 该函数计算一幅图像中目标的轮廓for c in contours:# 过滤面积较小的扰动if cv2.contourArea(c) < 80:continueelse:x, y, w, h = cv2.boundingRect(c) # 该函数计算矩形的边界框center = (int(x + w / 2), int(y + h / 2))# 判断点是否在多边形区域内result = cv2.pointPolygonTest(contour, center, False)if result > 0:cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2)# 第八步:进行图片的展示cv2.imshow('fgmk', fgmk)cv2.imshow('frame', frame)if cv2.waitKey(1) & 0xff == 27:breakcamera.release()cv2.destroyAllWindows()if __name__ == '__main__':path = "./video/test.mp4"main(path)
C++代码
#include <iostream>
#include <opencv2/opencv.hpp>using namespace std;
using namespace cv;int main(int argc, char** argv) {string path = "../test2.mp4";// 第一步:使用VideoCapture读取视频VideoCapture camera(path);int width = static_cast<int>(camera.get(CAP_PROP_FRAME_WIDTH));int height = static_cast<int>(camera.get(CAP_PROP_FRAME_HEIGHT));int per_width = width / 4;int per_height = height / 2;// 第二步:getStructuringElement构造形态学使用的kernelMat kernel = getStructuringElement(MORPH_ELLIPSE, Size(3, 3));// 第三步:构造高斯混合模型Ptr<BackgroundSubtractorMOG2> model = createBackgroundSubtractorMOG2();// Ptr<BackgroundSubtractorKNN> model = createBackgroundSubtractorKNN();// 设定区域,后面可以用于判断是否在区域内(可以设置为多边形)vector<Point> contour = {Point(0, 0), Point(3 * per_width, per_height), Point(3 * per_width, height), Point(0, height)};while (true) {// 第四步:读取视频中的图片,并使用高斯模型进行拟合Mat frame;bool ret = camera.read(frame);if (!ret) break;// 运用高斯模型进行拟合,在两个标准差内设置为0,在两个标准差外设置为255Mat fgmk;model->apply(frame, fgmk);// 第五步:使用形态学的开运算做背景的去除morphologyEx(fgmk, fgmk, MORPH_OPEN, kernel);// 第六步:findContours计算fgmk的轮廓vector<vector<Point>> contours;vector<Vec4i> hierarchy;findContours(fgmk.clone(), contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);for (const auto& c : contours) {if (contourArea(c) < 80)continue;else {Rect rect = boundingRect(c);Point center(rect.x + rect.width / 2, rect.y + rect.height / 2);// 判断点是否在多边形区域内double result = pointPolygonTest(contour, center, false);if (result > 0)rectangle(frame, rect, Scalar(0, 0, 255), 2);}}// 第八步:进行图片的展示imshow("fgmk", fgmk);imshow("frame", frame);if (waitKey(1) == 27) // 按下ESC键退出break;}camera.release();destroyAllWindows();return 0;
}
总结
这段代码演示了背景减除方法在移动目标检测中的应用,通过检测前景目标并在特定区域内绘制边界框,可以用于一些简单的运动分析和目标跟踪应用。
参考文档
https://blog.csdn.net/Gavinmiaoc/article/details/96474368
https://blog.csdn.net/drippingstone/article/details/116186462
如果阅读本文对你有用,欢迎一键三连呀!!!
2023年8月9日17:15:40