VideoCapture.read () возвращает прошлое изображение - PullRequest
0 голосов
/ 03 мая 2018

Я бегу python3.6 с openCV на Raspberry pi (ОС Raspbian)

Примерная структура кода выглядит следующим образом.

  1. image фиксируется с интервалом времени (3 ~ 5 минут).

  2. Захвачено image обрабатывается в функциях и возвращает меру (вид точности)

  3. Итерация 1. ~ 2. пока end_check() не вернется True

Проблема в том, что последний принятый 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(), возвращая устаревшие 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 вручную, он работает хорошо, даже если 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 голосов
/ 04 мая 2018

Я согласен с комментарием 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...