🎆

Streamlit Community CloudでOpenCVアプリを公開する

2022/09/09に公開

先に結論

opencv-python-headlessを使いましょう。

最小サンプルコード
https://github.com/shimat/streamlit_with_opencv_sample

公開したサンプル
https://shimat-streamlit-with-opencv-sample-main-t0iuwf.streamlitapp.com/

Streamlit Community Cloudについて

Community Cloudは、Streamlitの公式ホスティングサービスです。[1]
https://streamlit.io/cloud

以下を用意するだけで、無料でStreamlitアプリを世界に公開できます。

  • GitHubリポジトリ (public)
  • エントリポイントとなるPythonファイル
  • requirements.txt

OpenCVは使えるのか?

ではOpenCVを使うアプリケーションは公開できるのか?やってみると失敗しました。

requirements.txt
opencv-python==4.6.0.66
streamlit==1.12.2
main.py
import streamlit as st
import numpy as np
import cv2

st.title("Streamlit + OpenCV Sample")

img = np.zeros((500, 500, 3), np.uint8)
cv2.rectangle(img, (100, 100), (400, 400), color=(255, 0, 0), thickness=-1)

st.image(img)

特にOpenCVを持ち出す意味もないほどのコードですが、これを公開してみると、以下のエラーになります。

2022-09-09 07:21:54.808 Uncaught app exception
Traceback (most recent call last):
  File "/home/appuser/venv/lib/python3.10/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 556, in _run_script
    exec(code, module.__dict__)
  File "/app/streamlit_with_opencv_sample/main.py", line 3, in <module>
    import cv2
  File "/home/appuser/venv/lib/python3.10/site-packages/cv2/__init__.py", line 181, in <module>
    bootstrap()
  File "/home/appuser/venv/lib/python3.10/site-packages/cv2/__init__.py", line 153, in bootstrap
    native_module = importlib.import_module("cv2")
  File "/usr/local/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
ImportError: libGL.so.1: cannot open shared object file: No such file or directory

この ImportError: libGL.so.1 というのは、opencv-pythonを使う場合にかなり頻出エラーで、巷には多くの情報があります。Dockerコンテナなど、GUIが無い環境で実行しようとして怒られるのがだいたい共通しています。

解決法として、追加パッケージをaptで入れる、というのが多いですが、Streamlit Community Cloudでそれは苦しいので、そもそもlibGL.so.1がいらないOpenCVを使いましょう。

requirements.txt
opencv-python-headless==4.6.0.66
streamlit==1.12.2

opencv-python-headless はGUIに依存する拡張が取り除かれており、OpenGL(libGL.so)への依存もなくなりました。

動作イメージ

めでたしめでたし。

脚注
  1. 以前はStreamlit Sharingと言っていた気がします。 ↩︎

Discussion