1、基于帧差法的动目标检测 (1)视频图像预处理 a)彩色图像转化为灰度图像 b)数据类型由uint8转化为double c)数据归一化 (2)帧差法获得候选区域 a)前、后帧图像做帧差 b)利用Otsu自适应算法获得阈值 c)对阈值进行门限保护 d)利用阈值对帧差结果进行分割 e)分割候选区域的位置限制 (3)动目标检测 a)对候选区域进行形态学闭运算、开运算 b)候选区域连通区域标记,得到连通区域的四界和质心坐标信息 c)根据实际应用,去除不满足实际情况的连通域 d)对被分割成多个区域的目标,进行区域合并,连续2次 e)整理判定为疑似动目标的信息代码实现
时间: 2023-11-27 14:51:42 浏览: 130
这是一个基于帧差法的动目标检测的流程。具体的实现方式有很多种,这里提供一种代码实现供参考。
```
import cv2
import numpy as np
# 彩色图像转化为灰度图像
def rgb2gray(frame):
return cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 数据类型由uint8转化为double,数据归一化
def normalize(frame):
return cv2.normalize(frame.astype('float'), None, 0.0, 1.0, cv2.NORM_MINMAX)
# 帧差法获得候选区域
def get_candidate_regions(prev_frame, curr_frame):
# 前、后帧图像做帧差
diff = cv2.absdiff(prev_frame, curr_frame)
# 利用Otsu自适应算法获得阈值
_, thresh = cv2.threshold(diff, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# 对阈值进行门限保护
thresh[thresh < 30] = 0
# 利用阈值对帧差结果进行分割
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
candidate_regions = []
for contour in contours:
# 分割候选区域的位置限制
if cv2.contourArea(contour) > 100 and cv2.contourArea(contour) < 10000:
x, y, w, h = cv2.boundingRect(contour)
candidate_regions.append((x, y, w, h))
return candidate_regions
# 动目标检测
def motion_detection(prev_frame, curr_frame):
# 对候选区域进行形态学闭运算、开运算
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
diff = cv2.absdiff(prev_frame, curr_frame)
_, thresh = cv2.threshold(diff, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
thresh[thresh < 30] = 0
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
# 候选区域连通区域标记,得到连通区域的四界和质心坐标信息
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
detections = []
for contour in contours:
x, y, w, h = cv2.boundingRect(contour)
# 根据实际应用,去除不满足实际情况的连通域
if w / h > 0.4 and w / h < 2.5 and h > 30 and w > 30:
# 对被分割成多个区域的目标,进行区域合并,连续2次
thresh_roi = thresh[y:y + h, x:x + w]
contours_roi, _ = cv2.findContours(thresh_roi, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
if len(contours_roi) > 1:
for i in range(len(contours_roi)):
x_roi, y_roi, w_roi, h_roi = cv2.boundingRect(contours_roi[i])
detections.append((x + x_roi, y + y_roi, w_roi, h_roi))
else:
detections.append((x, y, w, h))
return detections
# 整理判定为疑似动目标的信息
def detect_motion(frame):
gray_frame = rgb2gray(frame)
normalized_frame = normalize(gray_frame)
candidate_regions = get_candidate_regions(prev_frame, normalized_frame)
detections = motion_detection(prev_frame, normalized_frame)
return detections
# 主程序
if __name__ == '__main__':
cap = cv2.VideoCapture('test.mp4')
ret, frame = cap.read()
prev_frame = normalize(rgb2gray(frame))
while True:
ret, frame = cap.read()
if not ret:
break
curr_frame = normalize(rgb2gray(frame))
detections = detect_motion(frame)
# 在原图上标记出检测到的目标
for detection in detections:
x, y, w, h = detection
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
prev_frame = curr_frame
cap.release()
cv2.destroyAllWindows()
```
这个代码实现中,使用OpenCV库进行图像处理和计算。在每一帧视频中,首先将彩色图像转化为灰度图像,并将数据类型由uint8转化为double,并进行数据归一化。然后使用帧差法获得候选区域,再进行形态学闭运算、开运算等处理,最终得到动目标检测的结果。在代码实现中,还对候选区域的位置进行了限制,并对被分割成多个区域的目标进行了区域合并处理。最后,将检测到的结果在原图上标记出来。
阅读全文