2016-05-11 7 views
5

Я пытаюсь получить изображения с веб-камеры с opencv и python. Код такой базовый, как:BeagleBone Black OpenCV Python слишком медленный

import cv2 
import time 
cap=cv2.VideoCapture(0) 
cap.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH,640) 
cap.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT,480) 
cap.set(cv2.cv.CV_CAP_PROP_FPS, 20) 

a=30 
t=time.time() 
while (a>0): 
     now=time.time() 
     print now-t 
     t=now 
     ret,frame=cap.read() 
     #Some processes 
     print a,ret 
     print frame.shape 
     a=a-1 
     k=cv2.waitKey(20) 
     if k==27: 
       break 
cv2.destroyAllWindows() 

Но он работает медленно. Выход программы:

VIDIOC_QUERYMENU: Invalid argument 
VIDIOC_QUERYMENU: Invalid argument 
VIDIOC_QUERYMENU: Invalid argument 
VIDIOC_QUERYMENU: Invalid argument 
VIDIOC_QUERYMENU: Invalid argument 
VIDIOC_QUERYMENU: Invalid argument 
HIGHGUI ERROR: V4L: Property <unknown property string>(5) not supported by device 
8.82148742676e-06 
select timeout 
30 True 
(480, 640, 3) 
2.10035800934 
select timeout 
29 True 
(480, 640, 3) 
2.06729602814 
select timeout 
28 True 
(480, 640, 3) 
2.07144904137 
select timeout 

Конфигурация:

  • Beaglebone Черный RevC
  • Debian-wheezly
  • OpenCV 2,4
  • питона 2,7
+1

Для этой проблемы, вероятно, не поможет, но если вы используете OpenCV на самом деле сделать резюме вещи, вы, вероятно, хотите, чтобы проверить, что OpenCV вы используете скомпилирован против расширений NEON. (doogle opencv beaglebone neon, вероятно, найдет полезную информацию, например http://blog.lemoneerlabs.com/3rdParty/Darling_BBB_30fps_DRAFT.html) – Foon

+0

«opencv 2.4» - вам нужно быть более конкретным, было число 2.4 .x выпусков OpenCV в течение нескольких лет. –

ответ

3

я столкнулся с подобной проблемой, когда я работал на проект с использованием OpenCV 2.4.9 на платформе Intel Edison. Перед выполнением какой-либо обработки он занимал примерно 80 мс, чтобы выполнить захват кадра. Оказывается, что логика захвата камеры OpenCV для Linux, похоже, не реализована должным образом, по крайней мере, в версии 2.4.9. В базовом драйвере используется только один буфер, поэтому для его работы невозможно использовать многопоточность на прикладном уровне - пока вы не попытаетесь захватить следующий кадр, единственный буфер в драйвере V4L2 заблокирован.

Решение не должно использовать класс VideoCapture от OpenCV. Возможно, в какой-то момент было исправлено использование разумного количества буферов, но с 2.4.9 это не так. Фактически, если вы посмотрите на статью того же автора, что и ссылка, предоставленная @Nickil Maveli, вы обнаружите, что как только он предоставит предложения по улучшению FPS на малиновом Pi, он перестает использовать VideoCapture OpenCV. Я не считаю, что это совпадение.

Это мое сообщение об этом на форуме Intel Edison: https://communities.intel.com/thread/58544.

Я в основном закончил писать свой собственный класс для обработки кадров, используя V4L2. Таким образом, вы можете предоставить круговой список буферов и позволить правильной развязке захватить фрейм и логику приложения. Это было сделано на C++, хотя для приложения на C++. Предполагая, что приведенная выше ссылка дает свои обещания, это может быть гораздо более простым подходом. Я не уверен, будет ли это работать на BeagleBone, но, может быть, есть что-то похожее на PiCamera. Удачи.

EDIT: Я взглянул на исходный код для 2.4.11 OpenCV. Похоже, теперь они по умолчанию используют 4 буфера, но вы должны использовать V4L2, чтобы воспользоваться этим. Если вы внимательно посмотрите на сообщение об ошибке HIGHGUI ERROR: V4L: Property..., вы увидите, что оно ссылается на V4L, а не на V4L2. Это означает, что сборка OpenCV, которую вы используете, падает на старый драйвер V4L. Помимо сингулярного буфера, вызывающего проблемы с производительностью, вы используете древний драйвер, который, вероятно, имеет множество ограничений и проблем с производительностью.

Лучше всего было бы создать OpenCV самостоятельно, чтобы убедиться, что он использует V4L2. Если я правильно помню, процесс настройки OpenCV проверяет, установлены ли на машине драйверы V4L2 и строит их соответственно, поэтому вы должны убедиться, что V4L2 и любые связанные с ним пакеты разработчика установлены на компьютере, который используется для сборки OpenCV.

+0

буфер находится в аппаратной памяти, я думаю (по моему опыту). – user5698387

3

"секрет" к получению более высокий FPS при обработке видеопотоков с помощью OpenCV - это перемещение ввода/вывода (то есть считывание кадров из датчика камеры) в отдельный поток.

При вызове метода read() вместе с cv2.VideoCapture функции, это делает весь процесс очень медленный, как он должен ждать для каждой операции ввода/вывода должны быть завершены для того, чтобы перейти к следующему (Blocking Process).

Для достижения этого увеличения/уменьшения задержки FPS наша цель - переместить отсчет кадров с веб-камеры или устройства USB на совершенно другой поток, полностью отделенный от нашего основного сценария Python.

Это позволит непрерывно считывать кадры из потока ввода-вывода, пока наш корневой поток обрабатывает текущий кадр. Как только корневой поток завершит обработку своего фрейма, ему просто нужно захватить текущий кадр из потока ввода-вывода. Это достигается без необходимости ждать блокировки операций ввода-вывода.

Вы можете прочитать Increasing webcam FPS with Python and OpenCV, чтобы знать шаги в реализации потоков.


EDIT

На основе обсуждений в наших комментариях, я чувствую, вы можете переписать код следующим образом:

import cv2 

cv2.namedWindow("output") 
cap = cv2.VideoCapture(0) 

if cap.isOpened():    # Getting the first frame 
    ret, frame = cap.read() 
else: 
    ret = False 

while ret: 
    cv2.imshow("output", frame) 
    ret, frame = cap.read() 
    key = cv2.waitKey(20) 
    if key == 27:     # exit on Escape key 
     break 
cv2.destroyWindow("output") 
+0

Я делал то же самое, но python и opencv все еще слишком медленны. – acs

+0

Попробуйте установить fps камеры на 'cap.set (cv2.cv.CV_CAP_PROP_FPS, 30)' и посмотреть результаты. –

+0

Тем не менее. под редакцией – acs

1

попробуйте этот! Я заменил какой-то код в разделе cap.set()

import cv2 
import time 
cap=cv2.VideoCapture(0) 
cap.set(3,640) 
cap.set(4,480) 
cap.set(5, 20) 

a=30 
t=time.time() 
while (a>0): 
     now=time.time() 
     print now-t 
     t=now 
     ret,frame=cap.read() 
     #Some processes 
     print a,ret 
     print frame.shape 
     a=a-1 
     k=cv2.waitKey(20) 
     if k==27: 
       break 
cv2.destroyAllWindows() 

вывод (веб-камера pc), ваш код был неправильным для меня.

>>0.0 
>>30 True 
>>(480, 640, 3) 
>>0.246999979019 
>>29 True 
>>(480, 640, 3) 
>>0.0249998569489 
>>28 True 
>>(480, 640, 3) 
>>0.0280001163483 
>>27 True 
>>(480, 640, 3) 
>>0.0320000648499 
+0

Исходные вызовы функции 'cap.set' были в порядке. Используемые константы @acs оценивают те же значения, которые вы указали вручную. Это не является причиной проблемы производительности. – Aenimated1