videocapture 保存图片_VideoCapture.read()返回过去的图像

在Raspberry Pi上使用Python3.6和OpenCV进行图像捕捉时,发现VideoCapture.read()返回的图像存在延迟,大约10分钟前的图像。该问题在运行一小时后出现,同时出现OpenCV错误。解决方案是通过设置时间戳并使用cam.grab()来避免帧缓冲导致的问题。
摘要由CSDN通过智能技术生成

I'm running python3.6 with openCV on the Raspberry pi(OS is Raspbian)

The approximate structure of the code is as follows.

The image is captured at time interval(3~5 min).

Captured image is processed in functions and returns measure(kind of accuracy)

Iterate 1.~2. until end_check() returns True

Problem is that the most recent taken image is out of date. It looks it was taken almost 10 minutes ago. All images recently taken are late. But the images taken at the beginning seem to be timed. And the time recorded in all .jpg files entered correctly

+It looks this problem is occured after more than a hour. (20~22 iterates)

Images are captured with cam0.read() in the cv2 package. Below is main part of the code. It is quite long to upload full code. It someone request, I will update.

def run(interval,model_list):

cam0 = cv2.VideoCapture(0) #Only cam0 is used. cam2 is just to record.

camdir = "/home/pi/capstone/cam0/"

cam2 = cv2.VideoCapture(1)

cam2dir = "/home/pi/capstone/cam2/"

runNo = 0

acc_list = list()

error_list = list()

end = False

while(end == False):

print(runNo,"th run")

img_name = "%s.jpg" %runNo

frame, res = cam0.read() #`res` is the image which will be processed

cv2.imwrite(os.path.join(camdir,img_name),res)

_ , cam2pic = cam2.read()

cv2.imwrite(os.path.join(cam2dir,img_name),cam2pic)

try:

temp = Real(res)

mat = temp.match(model_list)

acc_list.append([mat,runNo])

print("Accuracy=", mat)

except ValueError:

acc_list.append(["ValueError",runNo])

error_list.append(["ValueError",runNo])

except AttributeError:

acc_list.append(["AttributeError", runNo])

error_list.append(["AttributeError",runNo])

except SmallObjectError:

acc_list.append(["SmallObjectError", runNo])

error_list.append(["SmallObjectError",runNo])

runNo = runNo+1

endNo = 40

if(runNo/2 > endNo):

end_check(res, end)

elif(runNo > endNo):

end = True

sleep(interval*60)

with open("acc_list.txt", "w") as output: #records for tracking errors

output.write(str(acc_list))

with open("err_list.txt", "w") as output:

output.write(str(error_list))

cam0.release()

cam2.release()

run(3.5,model_list)

(+) Some newly found things and guess

The images time gap is getting bigger with code running

Code finally showed OpenCV Error

It looks kind of Video signal is stored in RAM on R-pi and .read() returning out-dated image in RAM

Stored Video signal in RAM araise resource problem

Below is the OpenCV Error

OpenCV Error: Assertion failed (dsize.area() > 0 || (inv_scale_x > 0 && inv_scale_y > 0)) in resize, file /home/pi/opencv/opencv-3.4.0/modules/imgproc/src/resize.cpp, line 4045

Traceback (most recent call last):

File "runpi.py", line 264, in

run(3.5,model_list)

File "runpi.py", line 234, in run

mat = temp.match(model_list)

File "runpi.py", line 184, in match

self.__resize(model.get_m_inform())

File "runpi.py", line 147, in __resize

self.mask = cv2.resize(self.mask, None, fx=reratio, fy=reratio, interpolation = inter_method)

cv2.error: /home/pi/opencv/opencv-3.4.0/modules/imgproc/src/resize.cpp:4045: error: (-215) dsize.area() > 0 || (inv_scale_x > 0 && inv_scale_y > 0) in function resize

(+) Some part of code araising Error

This is __.resize() method. When I process the image that occured OpenCV Error manually, it works well even if OpenCV Error pointing out kind of image size matter. So I thought it is not matter of image itself or size got from md_inf(). Anyway Here is code.

def __resize(self, md_inf):

#md_inf = [219, 122, 132, 171, 262]

reratio = md_inf[0]/self.y

if(reratio>1):

inter_method = cv2.INTER_LINEAR

else:

inter_method = cv2.INTER_AREA

###below is line 147###

self.mask = cv2.resize(self.mask, None, fx=reratio, fy=reratio, interpolation = inter_method)

temp = np.zeros((md_inf[3], md_inf[4]), np.uint8)

m_cx, m_cy = md_inf[1:3]

_, contour, _ = cv2.findContours(self.mask, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

total_contour = contour[0]

for ctr in contour[1:]:

total_contour = np.concatenate((total_contour, ctr), axis =0)

mmt = cv2.moments(total_contour)

if(mmt['m00'] < 7500):

raise SmallObjectError

self.cy = int(mmt['m10']/mmt['m00']) #y is horrizon axis

self.cx = int(mmt['m01']/mmt['m00']) #x is vertical axis

x, y = self.mask.shape

adjust = m_cx - self.cx + x - temp.shape[0]

if(adjust > 0):

m_cx = m_cx - adjust

temp[(m_cx-self.cx):(m_cx-self.cx) +x, (m_cy-self.cy):(m_cy-self.cy) +y] = self.mask

self.mask = temp

解决方案

I agree with Mark Serchell's comment. The way I am using is to set variable to time + x seconds and check. OpenCV have useful feature for skiping frames like cam.grab(). It will just read that frame from buffer but will not do anything with it. In that way you can avoid "suffering from buffering". Simple code would be:

import cv2

import time

cam = cv2.VideoCapture(url)

ret,frame = cam.read()

timeCheck = time.time()

future = 10*60 # delay

while ret:

if time.time() >= timeCheck:

ret,frame = cam.read()

# Do your staff here

timeCheck = time.time()+future

else:

# Read from buffer, but skip it

ret = cam.grab() # note that grab() function returnt only status code,not the frame

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值