When using a vision library such as OpenCV on Docker, it is necessary to connect the Docker container and the display of the local PC, but I did not know this method and it took a long time, so I encountered it on the way I would like to summarize the troubles that have occurred and their solutions!
Ubuntu! Check the details with the following command!
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.3 LTS"
$ arch
x86_64
First, download the Docker image from Docker Hub. You can freely download and save Docker images published on Docker Hub.
$ docker pull ubuntu:18.04
Launch a Docker container using the saved Docker image. There are various options when deploying a Docker container [1] [2] //qiita.com/tnarihi/items/275c009e9dec1306893f).
The options used this time are -it
, --privileged
, --env
, --volume
, --name
.
First, -it
makes it possible to use Bash on the Docker container by assigning a pseudo terminal to the Docker container.
Then --privileged
allows access to all devices.
--env
specifies the environment variables to use inside the Docker container.
--volume
allows you to mount the host OS directory on the guest OS [3] /).
You can specify the container name with --name
.
$ docker run -it \
--privileged \
--env="DISPLAY=$DISPLAY" \
--volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
--volume="$HOME/ws/:/home/" \
--name="ubuntu_cv2" \
ubuntu:18.04
First of all, it is Ubuntu's usual update and upgrade.
# apt-get update
# apt-get upgrade
Next, install Vim as an editor.
# apt-get install vim
Python is used as the programming language.
# apt-get install python3.6 \
python3-dev \
python3-pip \
libffi-dev \
libssl-dev
Install OpenCV using pip.
# pip3 install opencv-python
Create a basic program to display images using OpenCV.
open_image.py
import cv2
# Load an color image
img = cv2.imread('test.jpg')
# Show the image
cv2.imshow('image',img)
# Stop when 0 pressed
cv2.waitKey(0)
cv2.destroyAllWindows()
First, run Python and test if OpenCV can be imported correctly.
# python3
>>> import cv2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.6/dist-packages/cv2/__init__.py", line 3, in <module>
from .cv2 import *
ImportError: libSM.so.6: cannot open shared object file: No such file or directory
Sure enough, I can't import OpenCV due to an error. This error can be resolved by installing libsm6
, libxext6
, and libxrender-dev
[4].
# apt-get install -y libsm6 libxext6 libxrender-dev
After installation, try importing OpenCV again.
# python3
>>> import cv2
It's OK!
Let's execute the ʻopen_image.py` created earlier.
# python3 open_image.py
No protocol specified
: cannot connect to X server :1
It seems that the display connection with the PC has failed. The reason was that the host PC refused the connection request from the guest PC to the host PC display. Open another terminal and execute the following command on the host PC side to allow connection to the display [[5]](https://unix.stackexchange.com/questions/121716/unable-to-open-x -server) [6] [7] can do.
$ xhost +
access control disabled, clients can connect from any host
Let's go back to the terminal where the Docker container was running and run ʻopen_image.py`.
# python3 open_image.py
X Error: BadAccess (attempt to access private resource denied) 10
Extension: 130 (MIT-SHM)
Minor opcode: 1 (X_ShmAttach)
Resource id: 0x247
...
I got another error. After investigating the cause of the error, it seems that it can be solved by adding QT_X11_NO_MITSHM = 1
to the environment variable. First, open the .bashrc
file in Vim.
# vim ~/.bashrc
Next, add the environment variable QT_X11_NO_MITSHM = 1
.
export QT_X11_NO_MITSHM=1
After saving the .bashrc
file, execute the source
command [8] to reflect the addition of environment variables.
# source ~/.bashrc
Use the ʻecho` command to see if the environment variables have been added correctly.
# echo $QT_X11_NO_MITSHM
1
It's OK! I'm honest for the third time. Let's run ʻopen_image.py`!
# python3 open_image.py
The image is displayed! !! !!
Although there were various troubles, I was able to successfully connect the Docker container and the PC display and display the image with OpenCV. From this verification, it was also found that it is good to add the environment variable QT_X11_NO_MITSHM = 1
as shown below when deploying the Docker container.
$ docker run -it \
--privileged \
--env="DISPLAY=$DISPLAY" \
--env="QT_X11_NO_MITSHM=1" \
--volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
--volume="$HOME/ws/:/home/" \
--name="ubuntu_cv2" \
ubuntu:18.04
I will do my best to become a Docker master from now on! Thank you to everyone who read it! !! !!
[1] Docker run options, https://docs.docker.com/v17.12/edge/engine/reference/commandline/run/ [2] Example of docker run, https://qiita.com/tnarihi/items/275c009e9dec1306893f [3] How to mount on docker, https://docs.docker.com/v17.09/engine/admin/volumes/bind-mounts/ [4] How to solve opencv import error, https://github.com/NVIDIA/nvidia-docker/issues/864 [5] Open X server, https://unix.stackexchange.com/questions/121716/unable-to-open-x-server [6] Allowing computers access, https://www.stitson.com/pub/book_html/node72.html [7] About xhost, https://wiki.archlinux.jp/index.php/Xhost [8] Source command, https://bash.cyberciti.biz/guide/Source_command
Recommended Posts