我想制作一个支持OpenCV的易于运行的jupyter笔记本,并作为Docker镜像提供。
这个概念是让一个docker容器运行jupyter内核并通过主机中的浏览器访问笔记本。与this类似的东西。
然而,问题是OpenCV似乎依赖于正在运行的Gtk环境。因此尝试运行以下代码:
import numpy as np
import cv2
img = cv2.imread('pendulum.png',0)
cv2.imshow('image',img)
jupyter内核崩溃的结果:
(image:603): Gtk-WARNING **: cannot open display:
[I 15:23:49.808 NotebookApp] KernelRestarter: restarting kernel (1/5)
有没有办法绕过这种依赖关系并让Docker容器中的OpenCV在主机系统的浏览器中显示图像?
重现问题的步骤:
Dockerfile:
FROM ubuntu:16.04
RUN apt-get update
RUN apt-get update --fix-missing && apt-get install -y wget bzip2 ca-certificates \
libglib2.0-0 libxext6 libsm6 libxrender1 \
git mercurial subversion
RUN echo 'export PATH=/opt/conda/bin:$PATH' > /etc/profile.d/conda.sh && \
wget --quiet https://repo.continuum.io/archive/Anaconda3-4.0.0-Linux-x86_64.sh && \
/bin/bash /Anaconda3-4.0.0-Linux-x86_64.sh -b -p /opt/conda && \
rm /Anaconda3-4.0.0-Linux-x86_64.sh
ENV PATH /opt/conda/bin:$PATH
RUN conda install -y -c https://conda.binstar.org/menpo opencv3
RUN apt-get install -y libgomp1
RUN apt-get install -y libgtk2.0-0 x11-xserver-utils libcanberra-gtk3-module
RUN mkdir /home/user
RUN groupadd -r user -g 777 && \
useradd -u 431 -r -g user -d /home/user -s /sbin/nologin -c "Docker image user" user
RUN apt-get install -y libcanberra-gtk*
RUN chown -R user:user /home/user
USER user
WORKDIR /home/user
要执行的命令:
docker build -t opencv-play .
docker run -v /home/user/.Xauthority:/home/user/.Xauthority -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=unix$DISPLAY -u user -v `pwd`:/home/user -p 8008:8008 -t -i opencv-play
jupyter notebook --ip='*' --no-browser --port=8008 #Inside the container
#Open the browser, URL-> http://localhost:8008
#Run the above code in jupyter
答案 0 :(得分:3)
有两种可能的解决方案:
允许您的容器访问本地XServer。这将显示所有图形输出,就像您直接在主机上而不是在Docker容器中运行软件一样。为此,您需要设置DISPLAY
环境变量,并且需要将X11套接字传递给容器。在您的示例中,您将:
$ docker run -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=$DISPLAY -v `pwd`:/home/workspace -p 8008:8008 -t -i opencv-play
-v /tmp/.X11-unix:/tmp/.X11-unix
将X11套接字传递给容器-e DISPLAY=$DISPLAY
将显示环境变量设置为主机系统上的变量如果您不需要图形输出,则可以运行假冒'没有显示任何输出的X服务器。 Xvfb
是一个不需要任何访问监视器的显示服务器。要使用它,您需要在映像中安装Xvfb
,即将apt-get install xvfb
添加到Dockerfile。然后,当您运行容器时,首先需要启动xvfb并相应地设置DISPLAY
。我通常使用一个小脚本来执行此操作,然后启动您的命令,例如
#!/bin/bash
export DISPLAY=0:0
Xvfb $DISPLAY &
jupyter notebook --ip='*' --no-browser --port=8008
这将在后台启动Xvfb,然后启动jupyter,它将所有图形输出传递到0:0
上的Xvfb显示服务器。将此脚本添加到图像,然后按以下方式运行:
docker run -v `pwd`:/home/workspace -p 8008:8008 -t -i opencv-play /path/to/the/script
请注意,不需要将DISPLAY
传递给容器。
答案 1 :(得分:1)
我的建议是不要使用OpenCV进行绘图,而是使用matplotlib。 这为您提供了更好的绘图(OpenCV绘图功能非常有限),并且还允许直接笔记本输出。
您可以选择使用inline
后端,将每个绘图呈现为PNG(?)图像并将其显示在笔记本中。但是,这不允许缩放,平移等。
notebook
后端允许缩放等,但上次尝试时边缘非常粗糙。
无论哪种方式,要使用它,您都可以使用%matplotlib
魔法选择后端。
import matplotlib.pyplot as plt
%matplotlib inline
plt.imshow(img)
plt.title('My image')
plt.show()
对于notebook
后端,只需改为%matplotlib notebook
。
使用图片时,通常最好不要插入plt.imshow
来调用
plt.imshow(img, interpolation='none')
“正常”桌面后端(Gtk,Qt)需要调用plt.show()
,但inline
后端(以及notebook
后端不需要调用吗?我不需要记住)。
答案 2 :(得分:1)
为了能够在docker的jupyter内部运行opencv,我以与其他用户相同的方式进行了以下操作,但是方式更加明确:
在主持人中:
xhost +local:root
docker run -it --name yolo_cuda8 -v "/home/dl001/dhiren/robust_tracking/camera/:/home/notebooks" -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=$DISPLAY -p 8888:8888 new_cuda8 bash
内部容器:
jupyter notebook --port=8888 --ip=0.0.0.0 --allow-root --no-browser
值得通过发出 echo $ DISPLAY 命令来检查主机中的 DISPLAY 变量,并验证并设置docker容器中是否没有该变量。
env
export DISPLAY=:1
参考:
答案 3 :(得分:0)
在评论和其他研究之后,我设法让窗户加载但是一旦打开它们就无法关闭。 :P
以下是如何操作:
FROM ubuntu:16.04
RUN apt-get update
RUN apt-get update --fix-missing && apt-get install -y wget bzip2 ca-certificates \
libglib2.0-0 libxext6 libsm6 libxrender1 \
git mercurial subversion
RUN echo 'export PATH=/opt/conda/bin:$PATH' > /etc/profile.d/conda.sh && \
wget --quiet https://repo.continuum.io/archive/Anaconda3-4.0.0-Linux-x86_64.sh && \
/bin/bash /Anaconda3-4.0.0-Linux-x86_64.sh -b -p /opt/conda && \
rm /Anaconda3-4.0.0-Linux-x86_64.sh
ENV PATH /opt/conda/bin:$PATH
RUN conda install -y -c https://conda.binstar.org/menpo opencv3
RUN apt-get install -y libgomp1
RUN apt-get install -y libgtk2.0-0 x11-xserver-utils libcanberra-gtk3-module
RUN mkdir /home/user
RUN groupadd -r user -g 777 && \
useradd -u 431 -r -g user -d /home/user -s /sbin/nologin -c "Docker image user" user
RUN apt-get install -y libcanberra-gtk*
RUN chown -R user:user /home/user
USER user
WORKDIR /home/user
CMD jupyter notebook --ip='*' --no-browser --port=8008
运行图片:
docker run -v /home/user/.Xauthority:/home/user/.Xauthority -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=unix$DISPLAY -u root -v `pwd`:/home/user -p 8008:8008 -t -i opencv-play
启动笔记本(localhost:8008
)。
运行以下代码:
import numpy as np
import matplotlib.pyplot as plt
import cv2
img = cv2.imread('pendulum.jpg',0) #Make sure you have the image
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()