Reputation: 600
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?
Upvotes: 21
Views: 31217
Reputation: 1836
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.
Upvotes: 10
Reputation: 2901
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.
Upvotes: 0
Reputation: 1479
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()
Upvotes: 1
Reputation: 63
Try to use this:
-v /dev/video0:/dev/video0
in place of
--device=/dev/video0
and execute:
$ xhost +
before docker run
Upvotes: 3