How to setting the docker parameter to use the opencv (imshow)?
PS. export DISPLAY=:0.0 or export DISPLAY=:0 are not work for me.
Error log
Unable to init server: Could not connect: Connection refused
terminate called after throwing an instance of 'cv::Exception'
what(): OpenCV(4.7.0) /tmp/opencv/modules/highgui/src/window_gtk.cpp:635: error: (-2:Unspecified error) Can't initialize GTK backend in function 'cvInitSystem'
Aborted
main.cpp
// g++ opencv-camera.cpp -o a.out `pkg-config --cflags --libs opencv`
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main() {
//VideoCapture cap(0);
VideoCapture cap = cv2.VideoCapture("chaplin.mp4")
if (!cap.isOpened()) {
cout << "Cannot open camera\n";
return 1;
}
Mat frame;
Mat gray;
//namedWindow("live", WINDOW_AUTOSIZE);
while (true) {
bool ret = cap.read(frame); // or cap >> frame;
if (!ret) {
cout << "Can't receive frame (stream end?). Exiting ...\n";
break;
}
cvtColor(frame, gray, COLOR_BGR2GRAY);
imshow("live", frame);
if (waitKey(1) == 'q') {
break;
}
}
return 0;
}
Yes, it is the docker issue for windows system. There is a $DISPLAY parameter on linux, but I don’t know for windows.
Installing the opencv cost a long time, so I provide the python version to speed up the debug time.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import cv2
#cap = cv2.VideoCapture(0)
cap = cv2.VideoCapture("chaplin.mp4")
if not cap.isOpened():
print("Cannot open camera")
exit()
#cv2.namedWindow("live", cv2.WINDOW_AUTOSIZE);
while(True):
ret, frame = cap.read()
if not ret:
print("Can't receive frame (stream end?). Exiting ...")
break
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('live', frame)
#cv2.imshow('live', gray)
if cv2.waitKey(1) == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
error log
qt.qpa.xcb: could not connect to display :0
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "/usr/local/lib/python3.8/dist-packages/cv2/qt/plugins" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
Available platform plugins are: xcb.
Aborted
Did you check the OpenVino docs? To speed processing up, you would need to use -device.
If you are running Windows, then Docker Desktop is normally running Docker images inside a Linux VM. I don’t think any graphical output is possible that way, no GUI, no OpenCV imshow(), only command line.
Are you running Windows Desktop or did you install docker-ce inside a WSL2 distribution?
What’s the output of wsl --version (execute on Windows)
WSLg has been around in WSL2 for a while now. It starts a Wayland X-Server in the WSL2 utility vm, the x-server is available in every distribution via unix domain socket /tmp/.X11-unix/X0. The Wayland server will render the output on the Windows Host using rdp. The rdp client will be started with the distribution, but will be hidden until a GUI application is actually started.
You might want to try if adding these arguments helps: -v /tmp/.X11-unix/X0:/tmp/.X11-unix/X0 -e DISPLAY=:0
I just checked it on Docker Desktop v4.24.2 using this example (I used first image I found that runs a x-application directly):
docker run -it --rm -e DISPLAY=:0 -v '/tmp/.X11-unix:/tmp/.X11-unix' mtabishk/firefox:v1.0.0
Result:
If executed in Windows: throws an error
if executed in a WSl2 distribution with enabled Docker integration: works like a charm, application window gets rendered on the host
The last result would be identical, if docker-ce was installed in a WSL2 distribution.
If you want to be able to execute the command in Windows, you apparently need the old-school approach that requires a xserver in Windows or need to include vnc in your image.