環境
Ubuntu20.04
Python 3.9
vscode 1.52.1
anaconda 4.8.3
経緯
以下のようなopencvのコードをvscode上で実行させたのですが、、、
import numpy as np
import cv2
import os
image_dir = "Data/train_images/"
annotation_dir = "Data/train_annotation"
def show_image(num_str: str):
image_path = os.path.join(image_dir, f"train_{num_str}.jpg")
img = cv2.imread(image_path)
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == "__main__":
show_image("0001")
エラーも吐かずに正常終了。しかし、画像は表示されないという状態でした。
#解法
vscodeのターミナルで以下のように打つと表示できるようになりました。
$ export DISPLAY=:0
どうも、DISPLAYが見つからずにheadlessモードになっていたので、エラーが出ずに正常終了になっていたようです。
そもそも、vscodeのターミナルにおいてはxeyesがxeyes -display :0
としなければ表示できませんでした。加えて、通常のターミナルにおいては、特に対策を行わなくてもxeyes表示はできていたので、vscodeのターミナル実装に問題があるようです。
なんで解法がわかったか。
まず、他の描画系のライブラリであるmatplotlibが動作するかを以下で試しました。
すると同様に、エラー無しで無表示でした。
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
# グラフとして描画するデータ
x = np.array([1,2,3,4])
y = np.array([2,3,4,5])
# グラフを描画
plt.plot(x, y)
plt.show()
次に、描画プラグインを指定するよう、以下のようにコード編集しました。
import matplotlib
matplotlib.use('TkAgg') # <- Added
import matplotlib.pyplot as plt
import numpy as np
# グラフとして描画するデータ
x = np.array([1,2,3,4])
y = np.array([2,3,4,5])
# グラフを描画
plt.plot(x, y)
plt.show()
すると、以下のエラーが出ました。
Exception has occurred: ImportError
Cannot load backend 'TkAgg' which requires the 'tk' interactive framework, as 'headless' is currently running
File "/home/user/Programs/fish/test.py", line 6, in <module>
import matplotlib.pyplot as plt
tkってそもそもpythonにほぼ同梱されているよな?と思い、試しに以下を実行させました。
import tkinter as Tk
la = Tk.Label(None, text='Hello World!', font=('Times', '18'))
la.pack()
la.mainloop()
すると以下のようなエラーが。
Exception has occurred: TclError
couldn't connect to display ""
File "/home/user/Programs/fish/test2.py", line 3, in <module>
la = Tk.Label(None, text='Hello World!', font=('Times', '18'))
以前この記事で同様なエラーが出ていたので、同じようにDISPLAY=:0
対応したら、解決出来ました。