OpenCVを用いた録画ソフトを作ろうと思い立ちました。PythonでOpenCVを使ってプログラムを書く場合はpipでインストールするだけで割と簡単に導入できるのですが、今回はクロスコンパイルが可能なことに魅力を感じgo言語で書くことにしました。
Go言語では直接OpenCVを使用することはできないのですが、その代わりGoCVというものが利用できます。あまり詳細に理解してはいませんが、当初の私は「GoCV = OpenCVのGo言語版!」と言う認識でしたが、そうではなく「Go言語からOpenCVを使用できるようにしたラッパー」なようです。従ってGoCVをダウンロードするだけでなく、OpenCVそのものをソースコードからビルドして配置する必要があります。
Windows10 Home環境でGoCVの環境構築を行いましたが、主にOpenCVをソースビルドするために必要なコンポーネントであるMINGW-64
のバージョン選定に伴ってかなりハマりました。
環境
今回はParallels Desktop 19
を使ってMacBook Pro上に仮想マシンとしてWindows 10 Homeを用意した環境下で管渠構築を行っています。
- Windown 10 Home (Parallels Desktop 19 for mac Pro Edition) 64bit
環境構築完了後の各コンポーネントのバージョン
GoCVを使えるようにするには最低限下記のコンポーネントが必要です。先に、最終的にGoCVが使えるようになった時点での各コンポーネントのバージョン情報を下記に記載します。
-
Go
: go1.21.5 windows/amd64 (2024/1/1 時点最新) -
CMake
: 3.28.1 (2024/1/1 時点最新) -
MinGW-64
のgcc
バージョン : 8.1.0 -
GoCV
: v0.35.0 (2024/1/1 時点最新)-
GoCV
v0.35.0 がサポートしているOpenCV
のバージョンは4.8.1です
-
環境構築手順
まず過去の自分に言ってあげたいこととしては 公式の提供しているビルド手順をちゃんと読め ということです。GoCVの環境構築手順を紹介してくださっている記事もいくつかありましたが、記事の執筆時期が結構過去であったりするのでMinGW-64
などのコンポーネントのバージョン情報が微妙に合わずなかなかうまくいかないことが多かったです。じゃあどこを読んで参考にすればいいの? ということについての私なりの答えは ダウンロードしてきたGoCVプロジェクトの中にあるReadme です。後ほど説明します。
環境構築の手順は下記です。
- Goのインストール
- GoCVのダウンロード
- MinGW-64のインストール
- CMakeのインストール
- OpenCVのビルド
- GoCVの動作確認 (サンプルコードの実行)
Goのインストール
これは下記の記事を参考にどうぞ。GoSDKをインストールします
今回は2024/1/1時点で最新のgoバージョンである1.21.5
がインストールされました。インストールの際に環境変数へのPathは自動的に設定されるはずです。コマンドプロンプトを開きgo version
を実行します。下記の通りバージョン情報が表示されればインストールが完了しています。
> go version
go version go1.21.5 windows/amd64
GoCVのダウンロード
まず適当な場所で(もし作業用ディレクトリを決めて入ればそこで)下記のコマンドを実行します。これにより今いるディレクトリ内にgo.modファイルが生成されます。これ自体にあまり意味は無いですが、後のgo get
を実行する上で必要です。
go mod init <好きな文字列>
この後にgo get -u -d gocv.io/x/gocv
を叩くとgocvのプロジェクトフォルダ一式がダウンロードされます。今いるディレクトリ内に go.mod ファイルが存在しなければ「go.modがないよ!」とエラーが出るはずです。
> go get -u -d gocv.io/x/gocv
go: downloading gocv.io/x/gocv v0.35.0
go: added gocv.io/x/gocv v0.35.0
では一体どこにダウンロードされるのか?と言うと<GOPATH>\pkg\mod\gocv.io\x\gocv@v0.35.0
です。ここで<GOPATH>
はGO言語のインストール時に設定され、前述したインストール時に何も意識しなければ C:\Users\<ユーザ名>\go
になります。実際に<GOPATH>
を確認したい場合はgo env
コマンドで確認できます。またパスの最後のgocv@v0.35.0
は、ダウンロードしたGoCVのバージョンによって変わります。2024/1/1現在では0.35.0が最新でした。
> go env
・
・
(色々とGoに関する変数が表示される)
・
・
set GOPATH=C:\Users\hogehoge\go # ココを確認する
・
・
・
この後最も重要なのはココです。ダウンロードしたGoCVのフォルダ(<GOPATH>\pkg\mod\gocv.io\x\gocv@v0.35.0
)をファイルエクスプローラで開きます。その中にReadme.md
があります。この中のWindows
のセクションに環境構築の方法や手順が明記されています。これに従って作業をするとスムーズに環境構築ができるはずです。
...とココで記事を終わってしまうのはアレなので、それを踏まえて手順を説明してきます。
CMakeのインストール
下記のリンクから Windowsのx64用のインストーラ cmake-3.28.1-windows-x86_64.msi
(2024/1/1時点最新) をダウンロードします。おそらくCMakeのバージョンは神経質になる必要はないので、とりあえず最新版をインストールしました。
ダウンロードしたインストーラをダブルクリックで実行します。インストール中は基本デフォルトの設定でインストールを進めていきますが、途中「CMakeへのパスをシステム環境変数に追加するか」のチェックボックスがあるのでチェックしておきましょう(デフォルトは「パスを追加しない」にチェックがついている)。もしここでチェックし損ねても後で追加すればOKです。
一応下記のコマンドでCMakeが正常にインストールされていることと、パスが通っていることを確認しておきます。
>cmake --version
cmake version 3.28.1
CMake suite maintained and supported by Kitware (kitware.com/cmake).
MinGW-64のインストール (どハマりポイント)
ここが一番ハマりました「インストールするMinGWのバージョンなんてなんでもええやろ!」と思ってたらかなりハマりました。。。適当なMinGW-64をインストールしてしまうとOpenCVのビルド時にエラーが発生します。
下記のSourceforgeのサイトから MinGW-W64 GCC-8.1.0 から x86-64-posix-seh をダウンロードしてください。x86_64-8.1.0-release-posix-seh-rt_v6-rev0.7z という圧縮ファイルがダウンロードされます。
ダウンロードした圧縮ファイルを回答します。解凍するためにはフリーソフトの7zip
のインストールが必要ですので、下記からダウンロード&インストールしてください。
解凍後のフォルダをまるごとC:\Program Files
上にコピーして配置します。インストール自体はこれで完了です。この後、Windowsのシステム環境変数Path
にC:\Program Files\mingw64\bin
を新規追加します(このパスの値は解凍後のフォルダ名などに合わせて変更してください)。
この状態で下記のコマンドを叩いてgccのバージョンが 8.1.0 であればOKです。もしバージョン表示がされなかった場合はパスが正しく通ってないかもしれないので確認してください。
>gcc --version
gcc (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
【備忘録】 筆者が一体どこでどハマりしたのか
Readmeをロクに読もせず(というか存在を知らなかった)で推奨されているバージョンのMINGW-64ではなく、適当にココから最新版のMinGW-64をインストールすると、後段のOpenCVのビルドの段階でものすんごくエラーが出ます。GCC-12.2.0
, GCC-13.2.0
でOpenCVをビルドすると下記のようなエラーが発生してビルドが完了しませんでした。
C:\opencv\opencv-4.8.1\modules\videoio\src\cap_obsensor\obsensor_stream_channel_msmf.hpp:129:7: warning: base class 'struct IMFSourceReaderCallback' has accessible non-virtual destructor [-Wnon-virtual-dtor]
129 | class MSMFStreamChannel : public IUvcStreamChannel, public IMFSourceReaderCallback
| ^~~~~~~~~~~~~~~~~
mingw32-make[2]: *** [modules\videoio\CMakeFiles\opencv_videoio.dir\build.make:241: modules/videoio/CMakeFiles/opencv_videoio.dir/src/cap_obsensor/obsensor_uvc_stream_channel.cpp.obj] Error 1
mingw32-make[1]: *** [CMakeFiles\Makefile2:4574: modules/videoio/CMakeFiles/opencv_videoio.dir/all] Error 2
mingw32-make: *** [Makefile:165: all] Error 2
C:\opencv\build>rmdir c:\opencv\opencv-4.8.1 /s /q
C:\opencv\build>rmdir c:\opencv\opencv_contrib-4.8.1 /s /q
また、これはその後にハマったのですが GoCVの公式ページではMinGW-64のインストールについて下記のような記載があります。ここではGCC-7.3.0
をインストールするように指示があります。
MinGW-W64
Download and run the MinGW-W64 compiler installer from https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/7.3.0/.
The latest version of the MinGW-W64 toolchain is 7.3.0, but any version from 7.X on should work.
Choose the options for “posix” threads, and for “seh” exceptions handling, then install to the default location c:\Program Files\mingw-w64\x86_64-7.3.0-posix-seh-rt_v5-rev2.
Add the C:\Program Files\mingw-w64\x86_64-7.3.0-posix-seh-rt_v5-rev2\mingw64\bin path to your System Path.
しかし私の環境ではこの状態でOpenCVのビルドをするとエラーが発生しました。 上述の手順でダウンロードしたGoCVフォルダにあるReadme.mdでは8.1.0
をインストールするよう指示があったため、おそらく公式ページがメンテされてないのでしょう。具体的には下記のようなエラーです。
In file included from C:\opencv\opencv-4.8.1\3rdparty\protobuf\src\google\protobuf\arena.cc:42:0:
C:/opencv/opencv-4.8.1/3rdparty/protobuf/src/google/protobuf/stubs/mutex.h: In constructor 'constexpr google::protobuf::internal::WrappedMutex::WrappedMutex()':
C:/opencv/opencv-4.8.1/3rdparty/protobuf/src/google/protobuf/stubs/mutex.h:124:29: error: temporary of non-literal type 'google::protobuf::internal::CallOnceInitializedMutex<std::mutex>' in a constant expression
constexpr WrappedMutex() {}
^
C:/opencv/opencv-4.8.1/3rdparty/protobuf/src/google/protobuf/stubs/mutex.h:98:7: note: 'google::protobuf::internal::CallOnceInitializedMutex<std::mutex>' is not literal because:
class CallOnceInitializedMutex {
^~~~~~~~~~~~~~~~~~~~~~~~
C:/opencv/opencv-4.8.1/3rdparty/protobuf/src/google/protobuf/stubs/mutex.h:98:7: note: 'google::protobuf::internal::CallOnceInitializedMutex<std::mutex>' has a non-trivial destructor
mingw32-make[2]: *** [3rdparty\protobuf\CMakeFiles\libprotobuf.dir\build.make:91: 3rdparty/protobuf/CMakeFiles/libprotobuf.dir/src/google/protobuf/arena.cc.obj] Error 1
mingw32-make[1]: *** [CMakeFiles\Makefile2:3567: 3rdparty/protobuf/CMakeFiles/libprotobuf.dir/all] Error 2
mingw32-make[1]: *** Waiting for unfinished jobs....
mingw32-make: *** [Makefile:165: all] Error 2
どうやらこれは既知の不具合らしく、下記の記事によると、インストールしたgccバージョンが7.3以下の場合上記エラーが発生するらしいです、そのためここでも8.1.0
以上を使用することが推奨されています。
OpenCVのソースのビルド
ダウンロードしたGoCVのフォルダ(<GOPATH>\pkg\mod\gocv.io\x\gocv@v0.35.0
)をファイルエクスプローラーで開きwin_build_opencv.cmd
をダブルクリックで実行します。このバッチファイルでは OpenCV-4.8.1 (2024/1/1現在) のソースをダウンロード&解凍し、ソースコードのビルドを実行するように組まれています。ビルドの完了には1時間程度を要します。
ダブルクリックでの実行もできますが、筆者のおすすめはコマンドプロンプトを開いてGoCVフォルダに移動しwin_build_opencv.cmd > log.txt 2>&1
という形で実行することを強く推奨します。ダブルクリックで実行するとビルドがエラーで中断したときにウインドウが勝手に閉じてしまうため、何が原因でビルドが失敗したかの状況証拠が綺麗さっぱり消えてしまういます。更にビルドが完了したときにも勝手にウインドウが閉じるので、ビルドが正常に完了したかも確認しづらいです。
ビルドの完了確認
ビルド中に結構な量のwarningが出ますが、最後までビルドが止まらず完了すればひとまずOKです。もし途中でビルドが失敗していればビルドパーセンテージが100%まで上がらず、mingw32-make: *** [Makefile:165: all] Error 2
のようなエラーが記録されているはずです。下記のような出力がされていれば最後までビルドが通っています。
・
・
・
-- Installing: C:/opencv/build/install/etc/lbpcascades/lbpcascade_frontalface.xml
-- Installing: C:/opencv/build/install/etc/lbpcascades/lbpcascade_frontalface_improved.xml
-- Installing: C:/opencv/build/install/etc/lbpcascades/lbpcascade_profileface.xml
-- Installing: C:/opencv/build/install/etc/lbpcascades/lbpcascade_silverware.xml
-- Installing: C:/opencv/build/install/x64/mingw/bin/opencv_annotation.exe
-- Installing: C:/opencv/build/install/x64/mingw/bin/opencv_visualisation.exe
-- Installing: C:/opencv/build/install/x64/mingw/bin/opencv_interactive-calibration.exe
-- Installing: C:/opencv/build/install/x64/mingw/bin/opencv_version.exe
-- Installing: C:/opencv/build/install/x64/mingw/bin/opencv_version_win32.exe
-- Installing: C:/opencv/build/install/x64/mingw/bin/opencv_model_diagnostics.exe
C:\opencv\build>rmdir c:\opencv\opencv-4.8.1 /s /q
C:\opencv\build>rmdir c:\opencv\opencv_contrib-4.8.1 /s /q
C:\opencv\build>chdir /D C:\Users\hogehoge\go\src\gocv.io\x\gocv
またビルド完了後はC:\opencv\build\
にビルド後の成果物が出力されています。C:\opencv\build\install\x64\mingw\bin
の配下に大量の .dll
ファイルが出力されていればOKです。もしビルドに失敗していればそもそもC:\opencv\build\install\x64\mingw\bin
のフォルダが存在しない状況になっています。
OpenCVへのパスを通す
Windowsのシステム環境変数Path
にC:\opencv\build\install\x64\mingw\bin
を追加してください。
GoCVのサンプルコードの実行
gocvのバージョン表示用サンプル
C:Users\hogehoge\go\src\gocv.io\x\gocv\cmd\version
に移動し、バージョン表示用のサンプルコードを実行する。なぜか初回は不安になるくらい表示までに時間がかかるが、下記のようにバージョンが表示されればOK。
> go run main.go
gocv version: 0.35.0
opencv lib version: 4.8.1
カメラ映像表示用サンプル
C:Users\hogehoge\go\src\gocv.io\x\gocv\cmd\hello
に移動し、サンプルコードを実行する。
> go run main.go
下記の画像のようにHello
というタイトルのダイアログでカメラから取得した映像が表示されていればOK。ちなみに終了するときはコマンドプロンプト上でCtrl+C
を入力する必要がある。
ここまでできれば環境構築は完了です!