基于PySimpleGUI+OpenCV的视频移动侦测
欢迎交流学习
功能描述
基于PySimpleGUI+OpenCV的视频移动侦测,利用OpenCV中的cv2.absdiff
函数,对视频中的每一帧与上一帧进行计算,并绘制轮廓,如将计算的轮廓数据放在list_cnts
,能够绘制移动路径。
模块功能
import cv2
import PySimpleGUI as psg
设计思路
代码实现
import cv2
import PySimpleGUI as psg
video = psg.Image(key='video')
video_1 = psg.Image(key='video_1')
tt_binary = psg.Text('阈值')
tt_line_width = psg.Text('线宽')
tt_cnts = psg.Text('轮廓数量:', size=(10, 1))
sl_binary = psg.Slider((0, 255), 127, key='sl_binary', orientation='h')
sl_line_width = psg.Slider((0, 10), 1, key='sl_line_width', orientation='h')
bt_wait = psg.Button(key='wait', button_text='暂停5秒')
layout = [
[tt_cnts, tt_binary, sl_binary, tt_line_width, sl_line_width, bt_wait],
[video, video_1],
]
cap = cv2.VideoCapture(r'IMG/1122.mp4') # 读取视频
# cap = cv2.VideoCapture(0) #打开摄像头
win = psg.Window('移动侦测', layout=layout, location=(20, 20))
frame_1 = None
frame_2 = None
list_cnts = []
# 视频处理
def handler_video():
global frame_2, frame_1
_, frame = cap.read()
frame = cv2.resize(frame, (400, 600))
frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
if frame_2 is None:
frame_2 = frame_gray.copy()
else:
frame_2 = frame_1.copy()
frame_1 = frame_gray.copy()
diff = cv2.absdiff(frame_1, frame_2)
# diff = cv2.compare(frame_1, frame_1, cv2.CMP_GE)
# 阈值调整
_, diff = cv2.threshold(diff, value['sl_binary'], 255, cv2.THRESH_BINARY)
# 轮廓查找,绘制
contours, hierarchy = cv2.findContours(diff, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
list_cnts.append(contours)
for cnts in list_cnts:
cv2.drawContours(frame, cnts, -1, (255, 255, 0), int(value['sl_line_width']))
tt_cnts.update(value=f'轮廓数量:{len(contours)}')
imgbytes = cv2.imencode('.png', frame)[1].tobytes()
imgbytes_diff = cv2.imencode('.png', frame_1)[1].tobytes()
video.update(data=imgbytes)
video_1.update(data=imgbytes_diff)
while cap.isOpened():
event, value = win.read(timeout=30)
if event in [None]:
win.read()
break
if event in ['wait']:
time.sleep(5)
handler_video()