19

I'm trying to use Docker for one of our projects which uses OpenCV to process webcam feed (Python). But I can't seem to get access to the webcam within docker, here's the code which I use to test webcam access:

python -c "import cv2;print(cv2.VideoCapture(0).isOpened())"

And here's what I tried so far,

 docker run --device=/dev/video0 -it rec bash

 docker run --privileged --device=/dev/video0 -it rec bash

 sudo docker run --privileged --device=/dev/video0:/dev/video0 -it rec bash

All of these return False, what am I doing wrong?

Grim Reaper
  • 550
  • 1
  • 5
  • 18
  • 1
    I don't think there's a guarantee that `cv2.VideoCapture(0)` is actually `/dev/video0`. Have you tried *video1* and so on? Which Linux is this? – karlphillip Jun 30 '17 at 18:18
  • 1
    [Have you seen these?](https://stackoverflow.com/q/34302096/176769) – karlphillip Jun 30 '17 at 18:20
  • 1
    @karlphillip Yes, I tried those and its Ubuntu 16.04. – Grim Reaper Jun 30 '17 at 18:31
  • 1
    I know this may be implied... But is `/dev/video0` actually known to work on the host? Has it been tested with something like VLC (`vlc v4l2:///dev/video0`)? I know it also may not matter, but for completeness sake it would be prudent to mention the versions of stuff involved and probably the `Dockerfile` you used to build the `rec` image. – Andy Shinn Jul 01 '17 at 04:24
  • 1
    @AndyShinn I've tried running that on the host, it works without any problems. And the docker image is based on https://github.com/ageitgey/face_recognition#face-recognition – Grim Reaper Jul 01 '17 at 05:51

4 Answers4

9

The Dockerfile in the link you provided doesn't specify how opencv was installed, can you provide the Dockerfile you used? Or how you installed opencv?

VideoCapture(0) won't work if you install opencv via pip.

You're using --device=/dev/video0:/dev/video0 correctly.

EDIT: This thread is more than five years old. Perhaps things have changed, but I can confirm that installing opencv via pip works fine. I stumbled upon this thread because I was facing a similar issue where my app could not access the camera when running inside a docker container. In case my the issue was with the user account I was using to run the python application inside the docker. I had the following lines in my Dockerfile:

RUN adduser -u 5678 --disabled-password --gecos "" appuser && \
    chown -R appuser /app
USER appuser

Adding appuser to video group as shown below fixed the issue:

RUN adduser -u 5678 --disabled-password --gecos "" appuser && \
    adduser appuser video && \
    chown -R appuser /app
USER appuser

By the way, there is no need for the --privileged flag in this case. Keep in mind that my setup runs on devices running Ubuntu/Debian based linux OS.

pale bone
  • 1,746
  • 2
  • 19
  • 26
  • 1
    Ah, I did install opencv via pip. How should I have installed it? – Grim Reaper Sep 14 '17 at 17:27
  • try using this [dockerfile](https://github.com/IanPhilips/dlib-opencv/blob/master/Dockerfile.dlib.cv) instead. It is ubuntu 14.04 and includes dlib and opencv – pale bone Sep 14 '17 at 17:49
  • I also added some lines for you to uncomment at the end of the dockerfile that were in the facial recognition dockerfile – pale bone Sep 14 '17 at 17:56
3

Try to use this:

-v /dev/video0:/dev/video0

in place of

--device=/dev/video0 

and execute:

$ xhost + 

before docker run

vezunchik
  • 3,669
  • 3
  • 16
  • 25
1

The easisest way I found to have a dockerized OpenCV able to connect to your webcam is by using the following Dockerfile :

FROM ubuntu:20.04

ENV TERM=xterm
ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y --no-install-recommends \
    libopencv-dev \
    python3-opencv \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

WORKDIR /app
ADD . /app

ENV PYTHONUNBUFFERED=1
ENV PYTHONPATH=/app

and then build it and run in this way :

docker build -t opencv-webcam .
docker run -it -v $PWD:/app/ --device=/dev/video0:/dev/video0 -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=$DISPLAY opencv-webcam bash

and run the following script inside the container with python3 script.py:

import cv2


WINDOW_NAME = "Opencv Webcam"

def run():

    cv2.namedWindow(WINDOW_NAME)

    video_capture = cv2.VideoCapture(0)

    while True:
        ret, frame = video_capture.read()
        print(ret, frame.shape)

        cv2.imshow(WINDOW_NAME, frame)
        cv2.waitKey(1)

if __name__ == "__main__":
    run()
fallino
  • 1,381
  • 11
  • 9
0

I ran into issues when using a non-privileged Dockerfile (i.e. with a USER line):

The container must be started with --user {UID} ; NOT --user {UID}:{GID} (same for user: line in docker-compose.yml! If the gid is set, weirdly this will not inherit the video group permission needed for access to the webcam files (/dev/video0 etc.). Also, the internal Dockerfile user must be added to the video group; add this after the USER line (and after installing sudo and adding the user to sudoers):

RUN sudo usermod -a -G video <InternalUsername>

Before you try theses steps: run everything in privileged mode to test if your problem lies really here.

Oliver Zendel
  • 2,695
  • 34
  • 29