借鉴别人的代码并做了小小的扩展,实现了自己需要的功能,并将实现过程中遇到的问题及解决办法做了总结,特此分享给大家,
import cv2
import numpy as np
import os
import os.path
list1 = []
rootdir = r"E:\VideoCapture" #视频文件夹路径
for filenames in os.walk(rootdir):
for filename in filenames[-1]: #获取文件名称
list1.append(filename)
for i in list1:
url_video = 'E:\\VideoCapture\\' + str(i) #源视频文件路径
print url_video
camera = cv2.VideoCapture(url_video) # 参数0表示第一个摄像头
# 判断视频是否打开
if (camera.isOpened()):
print('Open')
else:
print('摄像头未打开')
# 测试用,查看视频size
size = (int(camera.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)),
int(camera.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)))
print('size:'+repr(size))
es = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9, 4))
kernel = np.ones((5, 5), np.uint8)
background = None
count = 0
while True:
# print '*******************'
# 读取视频流
grabbed, frame_lwpCV = camera.read()
# 对帧进行预处理,先转灰度图,再进行高斯滤波。
# 用高斯滤波进行模糊处理,进行处理的原因:每个输入的视频都会因自然震动、光照变化或者摄像头本身等原因而产生噪声。对噪声进行平滑是为了避免在运动和跟踪时将其检测出来。
if grabbed:
gray_lwpCV = cv2.cvtColor(frame_lwpCV, cv2.COLOR_BGR2GRAY)
gray_lwpCV = cv2.GaussianBlur(gray_lwpCV, (21, 21), 0)
# 将第一帧设置为整个输入的背景
if background is None:
background = gray_lwpCV
continue
# 对于每个从背景之后读取的帧都会计算其与背景之间的差异,并得到一个差分图(different map)。
# 还需要应用阈值来得到一幅黑白图像,并通过下面代码来膨胀(dilate)图像,从而对孔(hole)和缺陷(imperfection)进行归一化处理
diff = cv2.absdiff(background, gray_lwpCV)
diff = cv2.threshold(diff, 25, 255, cv2.THRESH_BINARY)[1] # 二值化阈值处理
diff = cv2.dilate(diff, es, iterations=2) # 形态学膨胀
# 显示矩形框
contours, hierarchy = cv2.findContours(diff.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 该函数计算一幅图像中目标的轮廓
if contours != []:
count = 1
for c in contours:
if cv2.contourArea(c) < 1500: # 对于矩形区域,只显示大于给定阈值的轮廓,所以一些微小的变化不会显示。对于光照不变和噪声低的摄像头可不设定轮廓最小尺寸的阈值
continue
(x, y, w, h) = cv2.boundingRect(c) # 该函数计算矩形的边界框
cv2.rectangle(frame_lwpCV, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.imshow('contours', frame_lwpCV)
cv2.imshow('dis', diff)
key = cv2.waitKey(5) & 0xFF
# print '%%%%%%%%%%%%%%%%%%%%%%%%%'
# 按'q'健退出循环
if key == ord('q'):
print '完成1'
break
else:
print '完成2'
break
camera.release()
cv2.destroyAllWindows()
if count == 0:
os.remove(url_video) #删除没有运动物体的视频文件
print('删除空文件' +url_video + " is OK!")
问题1:
image, contours, hierarchy = cv2.findContours(diff.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 该函数计算一幅图像中目标的轮廓
ValueError: need more than 2 values to unpack
解决办法:
删除image
contours, hierarchy = cv2.findContours(diff.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
问题2:
OpenCV Error: Assertion failed (scn == 3 || scn == 4) in cv::cvtColor, file ..\..\..\opencv-2.4.13.7\modules\imgproc\src\color.cpp, line 3783
Traceback (most recent call last):
File "E:/work/zy-detection-eval/py/yundongjiance.py", line 69, in <module>
gray_lwpCV = cv2.cvtColor(frame_lwpCV, cv2.COLOR_BGR2GRAY)
cv2.error: ..\..\..\opencv-2.4.13.7\modules\imgproc\src\color.cpp:3783: error: (-215) scn == 3 || scn == 4 in function cv::cvtColor
解决办法:
因为缺少安全性检测,读取的某些帧可能是空得导致这个问题出现。如果使用OpenCV读取照片路径错误也会类似的行为提示。
grabbed, frame_lwpCV = camera.read()
if grabbed: #加入判断是否有视频流
gray_lwpCV = cv2.cvtColor(frame_lwpCV, cv2.COLOR_BGR2GRAY)
问题3:
程序运行后出现显示框如果不按‘q’键退出显示框就会无响应
解决办法:
if grabbed:
...
else:
break
问题4:
删除不需要文件时,进程无法访问文件,因为另一个程序正在使用此文件。
if count == 0:
print url_video
os.remove(url_video)
print('删除空文件' +url_video + " is OK!")
camera.release()
cv2.destroyAllWindows()
错误:
WindowsError: [Error 32] : 'E:\\test_video\\1.avi'
解决办法:
关闭文件后再删除
camera.release()
cv2.destroyAllWindows()
if count == 0:
print url_video
os.remove(url_video)
print('删除空文件' +url_video + " is OK!")
参照以下博客:
链接: https://blog.csdn.net/lwplwf/article/details/73526831