[PYTHON] Docker x visualization didn't work and I was addicted to it, so I summarized it!

Introduction

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!

Development environment

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

Download Docker image

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

Deploy Docker container

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

Package installation

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 an image display program

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()

Trouble 1: OpenCV cannot be imported correctly

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!

Trouble 2: Image cannot be displayed

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! !! !!

in conclusion

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! !! !!

References

[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

Docker x visualization didn't work and I was addicted to it, so I summarized it!
I set up TensowFlow and was addicted to it, so make a note
I installed PySide2, but pyside2-uic didn't work, so I managed to do it.
[Introduction to json] No, I was addicted to it. .. .. ♬
I tried to use Twitter Scraper on AWS Lambda and it didn't work.
I was addicted to trying logging.getLogger in Flask 1.1.x
[IOS] GIF animation with Pythonista3. I was addicted to it.
PyTorch's book was difficult to understand, so I supplemented it
[Qualification] I passed LinuC Level 1, so I will write about how to study and how it was.
I was addicted to multiprocessing + psycopg2
W3C Validators didn't work with Sublime Text3 so I made it work
I want to create a pipfile and reflect it in docker
I was addicted to confusing class variables and instance variables in Python
I was addicted to pip install mysqlclient
Use Python from Java with Jython. I was also addicted to it.
I was addicted to Flask on dotCloud
(Beginner) I don't understand SSH and Linux command ssh-keygen, so I summarized it.
The file name was bad in Python and I was addicted to import
I studied about Linux, so I summarized it.
What I was addicted to Python autorun
I was addicted to trying Cython with PyCharm, so make a note
The tree.plot_tree of scikit-learn was very easy and convenient, so I tried to summarize how to use it easily.
I tried to use Java with Termux using Termux Arch but it didn't work
Somehow the code I wrote worked and I was impressed, so I will post it
When I tried to create a virtual environment with Python, it didn't work
I was able to mock AWS-Batch with python, moto, so I will leave it
I didn't understand the Resize of TensorFlow so I tried to summarize it visually.
I tried my best to make an optimization function, but it didn't work.
When I tried to create a project using Python on Docker with PyCharm, it didn't work, but it worked with Docker Compose.
What I was addicted to when combining class inheritance and Joint Table Inheritance in SQLAlchemy
A story that I was addicted to at np.where
I was able to repeat it in Python: lambda
What I was addicted to when using Python tornado
I learned MNIST with Caffe and tried to draw it (MAC OS X El Capitan)
There was a doppelganger, so I tried to distinguish it with artificial intelligence (laughs) (Part 1)
When I try to push with heroku, it doesn't work
What I was addicted to when migrating Processing users to Python
To the point where Python's Celery and RabbitMQ (Docker) work
[Fixed] I was addicted to alphanumeric judgment of Python strings
[For black screen phobia] I want to know about Linux and shells, so I illustrated it loosely.
I tried using pyenv, which I hated without eating, and it was too convenient to sit down.
I was a little addicted to installing Python3.3 + mod_wsgi3.4 on Sakura VPS (CentOS), so a retrospective memo
When I tried to scrape using requests in python, I was addicted to SSLError, so a workaround memo
I wrote AWS Lambda, and I was a little addicted to the default value of Python arguments
I tried to use deep learning to extract the part where the plant is shown from the photo of the balcony, but it didn't work, so I will summarize the contents of trial and error. Part 2