赞
踩
很久没更新文章了,这次因为工作场景需要检测动态目标,特此记录一下。
基于OpenCV库的背景减除方法实现的视频中的移动目标检测示例。通过从输入视频中提取前景目标,然后在特定区域内绘制检测到的移动物体的边界框。主要函数方法如下:
cv2.getStructuringElement
: 创建形态学操作所需的结构元素,这里使用椭圆形的结构元素。
cv2.createBackgroundSubtractorMOG2()
: 创建一个高斯混合模型背景减除器,用于提取视频中的前景。
cv2.morphologyEx(fgmk, cv2.MORPH_OPEN, kernel)
: 对前景图像进行形态学开运算,用于去除噪声并平滑前景目标。
cv2.findContours(fgmk.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
: 寻找前景图像中的轮廓。
需要根据自己的视频适当微调参数
import cv2 import numpy as np def 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构造形态学使用的kernel kernel = 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,在两个标准差外设置为255 fgmk = 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: continue else: 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: break camera.release() cv2.destroyAllWindows() if __name__ == '__main__': path = "./video/test.mp4" main(path)
#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构造形态学使用的kernel Mat 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,在两个标准差外设置为255 Mat 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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。