user1179317
user1179317

Reputation: 2923

cv2.VideoCapture not working in docker container on a mac host

I am unable to open the web cam or capture a video in an Ubuntu 16.04 docker container on a Mac OS Sierra 10.12.6 Host.

vid = cv2.VideoCapture(0)

where vid.isOpened() returns a False and ret, img = vid.read() returns False, None

I didnt just use opencv from pip. I compiled cv2 from the source. ffmpeg should be installed. Is the container not able to connect to the webcam device?

I tried running the docker with:

docker run -it --privileged --device=/dev/video0:/dev/video0 --entrypoint /bin/bash <ImageID>

My dockerfile is below:

#
# Ubuntu Dockerfile
#
# https://github.com/dockerfile/ubuntu
#

# Pull base image.
FROM ubuntu:16.04

# Install.
RUN \
  sed -i 's/# \(.*multiverse$\)/\1/g' /etc/apt/sources.list && \
  apt-get update && \
  apt-get -y upgrade && \
  apt-get install -y build-essential && \
  apt-get install -y software-properties-common && \
  apt-get install -y byobu curl git htop man unzip vim wget && \
  apt-get install -y cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev libv4l-dev && \
  apt-get install -y python-dev python-numpy libtbb2 libtbb-dev libjpeg8-dev libpng12-dev libtiff5-dev libjasper-dev libdc1394-22-dev && \
  apt-get install -y libxvidcore-dev libx264-dev && \
  apt-get install -y libgtk-3-dev && \
  apt-get install -y libatlas-base-dev gfortran && \
  apt-get install -y libopencv-dev && \
  rm -rf /var/lib/apt/lists/*


RUN apt-get update && apt-get install python2.7-dev python3.5-dev

# Set environment variables.
ENV HOME /root

# Define working directory.
WORKDIR /root

# Get OpenCV
RUN wget -O opencv.zip https://github.com/Itseez/opencv/archive/3.1.0.zip
RUN unzip opencv.zip
RUN wget -O opencv_contrib.zip https://github.com/Itseez/opencv_contrib/archive/3.1.0.zip
RUN unzip opencv_contrib.zip

# GET PIP
RUN apt-get update && apt-get install -y python3-pip
RUN pip3 install numpy

# Build OpenCV
## NOTE: cd wont work by itself, need to be with the actual command to be performed
WORKDIR /root/opencv-3.1.0
RUN mkdir build
WORKDIR /root/opencv-3.1.0/build
RUN cmake -D CMAKE_BUILD_TYPE=RELEASE \
  -D CMAKE_INSTALL_PREFIX=/usr/local \
  -D INSTALL_PYTHON_EXAMPLES=ON \
  -D INSTALL_C_EXAMPLES=OFF \
  -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib-3.1.0/modules \
  -D BUILD_EXAMPLES=ON \
  -D PYTHON_EXECUTABLE=/usr/bin/python3.5 \
  -D PYTHON_PACKAGES_PATH=/usr/local/lib/python3.5/site-packages \
  -D PYTHON_NUMPY_INCLUDE_DIR=/usr/local/lib/python3.5/dist-packages/numpy/core/include ..

RUN make -j4
RUN make install
RUN ldconfig

## RENAME BUILT cv2.so
WORKDIR /usr/local/lib/python3.5/dist-packages
RUN mv cv2.cpython-35m-x86_64-linux-gnu.so cv2.so
WORKDIR /usr/local/lib/python3.5/site-packages
RUN ln -s /usr/local/lib/python3.5/dist-packages/cv2.so cv2.so

## DELETE DIRECTORIES
# WORKDIR /root
# RUN rm -rf opencv-3.1.0 opencv_contrib-3.1.0 opencv.zip opencv_contrib.zip

# Define default command.
CMD ["bash"]

Upvotes: 3

Views: 4190

Answers (2)

QiangZiBro
QiangZiBro

Reputation: 89

I noticed the problem that Docker running on macOS can't use the camera. I do not feel like installing VM on my mac, but I want to use the convenience of Docker, so I designed the technical plan, which reads images from mac itself, and use docker container as a server.

The general:

  • Use docker as a service, listen to a port, receive and process images
  • Use macOS to read images, and give image analysis tasks to Docker container

The specific:

  • Read images from macOS, which's not difficult
  • Send images to Docker container via inter-process communication(IPC) like socket (I don't quite understand this so much now, I will research a little about it)
  • Process images use some specific algorithms
  • Return result to macOS host via IPC
  • Other easy jobs on mac

The method could be concluded as this image The method we use to connect mac and Docker

I haven't implemented it, but I searched there are some materials that may help, I list below:

Upvotes: 0

Tarun Lalwani
Tarun Lalwani

Reputation: 146630

You cannot do this using Docker for Mac. The problem is that Docker runs Hyperkit which in turn is based on Xhyve

If you read the Readme of xhyve

Notably absent are sound, USB, HID and any kind of graphics support. With a focus on server virtualization this is not strictly a requirement. bhyve may gain desktop virtualization capabilities in the future but this doesn't seem to be a priority.

So your docker container which is running inside the Hyperkit VM will never be able to access the device.

Your --device=/dev/video0:/dev/video0 is just mapping a device from inside the container and it may not be there in the VM at all.

So what are you alternatives? Instead of using Docker for Mac, use VirtualBox or VMWare fusion. Create a Ubuntu 16.04 or any other supported OS VM inside it. Shared the webcam device with the VM using settings for that VM. Now your VM OS will have the device.

Inside your VM install docker and access the device.

Upvotes: 3

Related Questions