Python – OpenCV – Docker – program stuck at cv.VideoCapture(0) line when using custom docker image

  docker, opencv, python

First, while I’m waiting for an answer here, I am still looking around in google, but since my situation is pretty specific I doubt that I am going to find a similar post.

Also, I use ubuntu 20.04, python3.8.5 and OpenCV 4.5.1.

Now, please do understand that my framecap.py file, the program which I have a problem with, work perfectly well outside my container.
This is framecap.py:

import numpy as np
import cv2 as cv
import time
print(cv.__version__)
print("test-2")
# camSet = 'v4l2src device=/dev/video0 ! video/x-raw,format=BGRx ! videoconvert ! autovideosink'
# camSet = 'videotestsrc ! video/x-raw,format=YUY2 ! videoconvert ! autovideosink'
print("test-1")

camSet = 0
print("test0")

cam = cv.VideoCapture(camSet)
print("test1")

if not cam.isOpened():
    print("Cannot open camera")
    exit()
print("test2")

frame_array = []
print("test3")

counter=0
print("test4")

while counter<=20:
    print(counter, "1")

    ret, frame = cam.read()
    print(counter, "2")

    cv.imshow('myCam', frame)
    print(counter, "3")

    # if frame is read correctly ret is True
    if not ret:
        print("Can't receive frame (stream end?). Exiting ...")
        break
    height, width, layers = frame.shape
    print(counter, "4")

    size = (width,height)
    print(counter, "5")

    frame_array.append(frame)
    print(counter, "6")

    if cv.waitKey(1) == ord('q'):
        break
    counter+=1
    print(counter, "7")

cam.release()
out = cv.VideoWriter('testvideo.avi' ,cv.VideoWriter_fourcc(*'DIVX'), 30, size)
for i in range(len(frame_array)):
    out.write(frame_array[i])
out.release()

cv.destroyAllWindows()

Now, when executed inside my container, this is the outcome:

[email protected]:/data# python3 framecap.py
4.5.1
test-2
test-1
test0

And it stay at test0 until I Ctrl + C

Since this work outside my container, it obviously don’t come from my python file. Thus, the following is my command to launch the container:

$ sudo docker run -dit --name test -v ~/datapython:/data --rm --device /dev/video0 --net=host -e DISPLAY=$DISPLAY opencv-gstreamer bash

Now, the Dockerfile:

FROM python:3.8-slim-buster
FROM restreamio/gstreamer:1.18.2.0-prod
WORKDIR /app


RUN apt update && apt install -y python3-pip
RUN python3 -m pip install --upgrade pip
RUN pip install --upgrade setuptools
# Various Python and C/build deps
# RUN apt-get update && apt-get install -y 
#     gstreamer1.0*
# RUN apt install -y ubuntu-restricted-extras
RUN apt install -y build-essential cmake git pkg-config libgtk-3-dev 
    libavcodec-dev libavformat-dev libswscale-dev libv4l-dev 
    libxvidcore-dev libx264-dev libjpeg-dev libpng-dev libtiff-dev 
    gfortran openexr libatlas-base-dev python3-dev python3-numpy 
    libtbb2 libtbb-dev libdc1394-22-dev libopenexr-dev 
    libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev



# Install Open CV - Warning, this takes absolutely forever

RUN git clone https://github.com/opencv/opencv.git /home/thomas/Desktop/opencv-gstreamer/opencv && 
    cd /home/thomas/Desktop/opencv-gstreamer/opencv && 
    git checkout 4.5.1 && 
#     unzip 4.5.1.zip && 
#     rm 4.5.1.zip && 
#     mv opencv-3.0.0 OpenCV && 
#     cd OpenCV && 
    mkdir build && 
    cd build && 
    cmake -D CMAKE_BUILD_TYPE=RELEASE 
    -D INSTALL_PYTHON_EXAMPLES=ON 
    -D INSTALL_C_EXAMPLES=OFF 
    -D PYTHON_EXECUTABLE=$(which python3) 
    -D BUILD_opencv_python2=OFF 
    -D CMAKE_INSTALL_PREFIX=$(python3 -c "import sys; print(sys.prefix)") 
    -D PYTHON3_EXECUTABLE=$(which python3) 
    -D PYTHON3_INCLUDE_DIR=$(python3 -c "from distutils.sysconfig import get_python_inc; print(get_python_inc())") 
    -D PYTHON3_PACKAGES_PATH=$(python3 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())") 
    -D WITH_GSTREAMER=ON 
    -D BUILD_EXAMPLES=ON .. && 
    make -j4 && 
    make install


COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt

COPY . .

CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0"]

I would like to know if I missed something in my image build to allow my framecap.py to do his work, or in my container run command, but I haven’t found an answer yet…

NOTE:
The webcam that i use has a little blue light if it is On. When executing my python file in the container, this light is present, meaning that my webcam is working.

Also, this is requirements.txt :

click==7.1.2
Flask==1.1.2
itsdangerous==1.1.0
Jinja2==2.11.3
MarkupSafe==1.1.1
Werkzeug==1.0.1

Source: Docker Questions

LEAVE A COMMENT