Модуль OpenCV не повторяет цикл в Raspberry Pi 4. Отлично работает в Windows

#python #opencv #raspberry-pi #windows-10 #raspberry-pi4

#python #opencv #raspberry-pi #windows-10 #raspberry-pi4

Вопрос:

Позвольте мне начать с того, что я новичок в Python и Raspberry Pi.

Я «сделал» (больше похоже на скопированное из большого количества различий. исходные и скомпилированные) модуль в Windows для захвата изображений с веб-камеры при нажатии клавиши и сохранения его в папке (код прилагается). Он отлично работает в Windows и повторяет цикл, но выдает ошибку на Raspberry Pi после первого цикла.

Код для Windows:-

 # Import Modules #######################################################################################################

from datetime import datetime
import cv2
import time
import queue
import threading


# Module Level Variables ###############################################################################################


inpath = "D:\Python Projects\OCR Trial2\Input\Training Data\"
outpath = "D:\Python Projects\OCR Trial2\Output\"
intpath = "D:\Python Projects\OCR Trial2\Intermediate\"
file_Prefix = 'IMG100'
file_Extension = '.png'


# Class Definitions ####################################################################################################

class VideoCapture:

    def __init__(self, name):
        self.cap = cv2.VideoCapture(name)
        self.q = queue.Queue()
        t = threading.Thread(target=self._reader)
        t.daemon = True
        t.start()

    def _reader(self):
        while True:
            ret, frame = self.cap.read()
            if not ret:
                break
            if not self.q.empty():
                try:
                    self.q.get_nowait()
                except queue.Empty:
                    pass
            self.q.put(frame)

    def read(self):
        return self.q.get()

# Functions ############################################################################################################

def main():
    while True:
        try:
            windowName = "Live Video Feed"
            cv2.namedWindow(windowName)

            if cv2.waitKey(1) == ord("c"):

                time.sleep(1)
                now = datetime.now()
                formatted_time = now.strftime('%Y-%m-%d %H-%M-%S.%f')[:-3]
                cam = VideoCapture(0   cv2.CAP_DSHOW)
                frame1 = cam.read()
                cv2.imshow(windowName,frame1)
                cv2.imwrite(intpath   file_Prefix   formatted_time   file_Extension, frame1)
                print(formatted_time)
            else:
                continue
        except:
            pass

# Execute Code #########################################################################################################

if __name__ == "__main__":
    main()
 

Вывод для Windows:-

 2021-01-06 17-20-05.255
2021-01-06 17-20-07.404
2021-01-06 17-20-08.601
2021-01-06 17-20-10.766
2021-01-06 17-20-12.408

Process finished with exit code -1
 

Код для Raspberry Pi:-

 # Import Modules #######################################################################################################

from datetime import datetime
import cv2
import time
import queue
import threading

# Module Level Variables ###############################################################################################



intpath = "/home/pi/Python Images/"
file_Prefix = 'IMG100'
file_Extension = '.png'


# Class Definitions ####################################################################################################

class VideoCapture:

    def __init__(self, name):
        self.cap = cv2.VideoCapture(name)
        self.q = queue.Queue()
        t = threading.Thread(target=self._reader)
        t.daemon = True
        t.start()

    def _reader(self):
        while True:
            ret, frame = self.cap.read()
            if not ret:
                break
            if not self.q.empty():
                try:
                    self.q.get_nowait()
                except queue.Empty:
                    pass
            self.q.put(frame)

    def read(self):
        return self.q.get()

# Functions ############################################################################################################


def main():
    while True:
        try:
            windowName = "Live Video Feed"
            cv2.namedWindow(windowName)

            if cv2.waitKey(1) == ord("c"):

                time.sleep(1)
                now = datetime.now()
                formatted_time = now.strftime('%Y-%m-%d %H-%M-%S.%f')[:-3]
                cam = VideoCapture(0)
                frame1 = cam.read()
                cv2.imshow(windowName,frame1)
                cv2.imwrite(intpath   file_Prefix   formatted_time   file_Extension, frame1)
                print(formatted_time)
            else:
                continue
        except:
            pass

# Execute Code #########################################################################################################


if __name__ == "__main__":
    main()
 

Выход для Raspberry Pi :-

 2021-01-06 17-07-59.501
[ WARN:4] global /tmp/pip-wheel-qd18ncao/opencv-python/opencv/modules/videoio/src/cap_v4l.cpp (893) open VIDEOIO(V4L2:/dev/video0): can't open camera by index

Process finished with exit code 137 (interrupted by signal 9: SIGKILL)
 

Модуль Open CV на Raspberry Pi был установлен с помощью PIP, а не скомпилирован вручную. Общие функции OpenCV, такие как захват видео и imshow, отлично работают на Raspberry Pi, и он успешно захватывает первую фотографию, но не может захватить вторую.
Пожалуйста, подскажите, в чем может быть проблема, что я могу попробовать дальше.

Редактировать 1 — Добавлена вся ошибка после печати исключения:-

 /home/pi/PycharmProjects/pythonProject/venv/bin/python "/home/pi/PycharmProjects/pythonProject/Image Capture.py"
2021-01-07 15-07-36.555
[ WARN:4] global /tmp/pip-wheel-qd18ncao/opencv-python/opencv/modules/videoio/src/cap_v4l.cpp (893) open VIDEOIO(V4L2:/dev/video0): can't open camera by index
Traceback (most recent call last):
  File "/home/pi/PycharmProjects/pythonProject/Image Capture.py", line 72, in <module>
    main()
  File "/home/pi/PycharmProjects/pythonProject/Image Capture.py", line 59, in main
    frame1 = cam.read()
  File "/home/pi/PycharmProjects/pythonProject/Image Capture.py", line 42, in read
    return self.q.get()
  File "/usr/lib/python3.7/queue.py", line 170, in get
    self.not_empty.wait()
  File "/usr/lib/python3.7/threading.py", line 296, in wait
    waiter.acquire()
KeyboardInterrupt

Process finished with exit code 1
 

Комментарии:

1. всегда помещайте полное сообщение об ошибке (начинающееся со слова «Traceback») в вопрос (не комментарий) в виде текста (не скриншота). Есть и другая полезная информация.

2. для работы с веб-камерой может потребоваться некоторый внешний модуль C / C (драйвер)

3. ваша ошибка может быть cam = VideoCapture(0) внутри цикла. Вы должны использовать его только один раз — перед циклом. Если вы попытаетесь использовать его во второй раз, система не сможет получить к нему доступ до того, как он все еще будет использоваться предыдущим cam = VideoCapture(0)

4. Кстати: возможно, вы могли бы получить более подробную информацию, если бы не использовали except: pass — он скрывает сообщение об ошибке, и вы не знаете, что есть проблема. Вы должны использовать по крайней мере except Exception as ex: print(ex)

5. в сообщении об ошибке явно указано «не удается открыть камеру по индексу», потому что серверной частью является V4L2, который требует абсолютных путей к /dev/video*

Ответ №1:

Ваша ошибка может быть cam = VideoCapture(0) внутри цикла.

Вы должны создать его только один раз — перед циклом.

Если вы попытаетесь использовать его во второй раз (например, в цикле), система не сможет получить к нему доступ до того, как он все еще будет использовать предыдущий cam = VideoCapture(0) .