VideoCapture.read()返回过去的图像

时间:2018-05-03 08:57:04

标签: image opencv raspberry-pi

我在python3.6上运行openCV Raspberry pi(操作系统为Raspbian

代码的近似结构如下。

  1. image以时间间隔(3~5分钟)捕获。

  2. 捕获的image在函数中处理并返回度量(精确度)

  3. 迭代1.~2。直到end_check()返回True
  4. 问题是最近拍摄的image已过期。它看起来差不多是在10分钟前拍摄的。最近拍摄的所有图像都很晚。但是在开始时采用的images似乎是定时的。并且所有.jpg个文件中记录的时间输入正确 +看起来这个问题在一个多小时后就出现了。 (20~22次迭代)

    Images包中使用cam0.read()捕获

    cv2。下面是代码的主要部分。上传完整代码需要很长时间。有人要求,我会更新。

    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)
    

    (+)一些新发现的事情和猜测

    • 代码运行时images时间差距越来越大
    • 代码终于显示OpenCV Error
    • 看起来Video signal存储在R-pi.read()的RAM中,image
    • 中的RAM已过时Video signal
    • RAM araise资源问题
    • 中存储了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 <module> 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

    __.resize()

    (+)代码的某些部分用于错误

    这是image方法。当我手动处理发生OpenCV Error的{​​{1}}时,即使OpenCV Error指出image大小的问题,它也能正常运行。所以我认为image本身或size来自md_inf()无关紧要。无论如何这是代码。

    def __resize(self, md_inf):       
        #md_inf = [219, 122, 132, 171, 262] <-sample
        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
    

1 个答案:

答案 0 :(得分:0)

我同意Mark Serchell的评论。我使用的方法是将变量设置为time + x seconds并检查。 OpenCV具有用于滑动cam.grab()等帧的有用功能。它只会从缓冲区中读取该帧,但不会对其执行任何操作。这样你就可以避免“遭受缓冲”。简单的代码是:

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