はじめにのはじめに
本記事は超絶マニアックな誰得な作業ログです。読者を置いていくことが目標と言っても過言ではありません。記事のクオリティの低さたるや、格別です。
さて、pythonからOpenCVを使うというのは大分一般的になってきたと思います。ここで、多くの人は配布されているバイナリを使っていますが、contribや動画処理など、デフォルトでは入っていない機能を使おうとすると、ビルドが必要になります。
すると、大抵python bindingでコケて沼にはまります。コケた際に、OpenCVのcmakeファイルを読んで自力で解決している人は、非常に少ないのでしょうか。でも、人生、cmakeファイルを読まなくてはいけない時があるんです。本記事は、そんな時に、俺はこうやって解決した!という作業ログです。人それぞれエラーは違うので、そのまま適用できるケースは無いと思いますが、気合だけでも伝わればと思います。
ちなみにマニュアルを読めば早(ry
はじめに
よくこんな質問が寄せられます。
Q: OpenCVをビルドしたいのに、python bindingで失敗する
答えは、
A: cmake fileを読む
です。
失敗ケースとしては、condaを使ったら動かない、Macだと動かない・・・など色々ありますが、今回は各ケースに対する優しいケーススタディではなく、cmakeをガチムチで読むという話です。
最初のビルド
まずは成功画面、cmakeするとこんな感じでpython-bindingに成功します。
$ mkdir build
$ cd build
$ cmake ..
という事で、めでたし!・・という感じで記事を締めたいところですが、多くの場合はこんな感じで失敗します。
よくある原因は、conda内のpythonを使っていると、OpenCVがリンクを見つけられない事に起因します。こんな時の調査手順を載せます。なお、今回は、ワザと失敗させているため、色々未インストールのものとかも準備しておき、ログに出ても気づかなかった事にします。
失敗表示されている場所
エラーメッセージでひとまずgitリポジトリ内を検索するとroot dierectory直下のCMakeLists.txtの最後の方にこんな記述が見られます。
if(BUILD_opencv_python3)
status("")
status(" Python 3:")
status(" Interpreter:" PYTHON3INTERP_FOUND THEN "${PYTHON3_EXECUTABLE} (ver ${PYTHON3_VERSION_STRING})" ELSE NO)
if(PYTHON3LIBS_VERSION_STRING)
status(" Libraries:" HAVE_opencv_python3 THEN "${PYTHON3_LIBRARIES} (ver ${PYTHON3LIBS_VERSION_STRING})" ELSE NO)
else()
status(" Libraries:" HAVE_opencv_python3 THEN "${PYTHON3_LIBRARIES}" ELSE NO)
endif()
status(" numpy:" PYTHON3_NUMPY_INCLUDE_DIRS THEN "${PYTHON3_NUMPY_INCLUDE_DIRS} (ver ${PYTHON3_NUMPY_VERSION})" ELSE "NO (Python3 wrappers can not be generated)")
status(" packages path:" PYTHON3_EXECUTABLE THEN "${PYTHON3_PACKAGES_PATH}" ELSE "-")
endif()
ふむふむ、Librariesとnumpyが見つからないと言われているということは、HAVE_opencv_python3
とPYTHON3_NUMPY_INCLUDE_DIRS
が空か、OFFになっているっぽいな、となります。
念のため、この付近で、上記2変数を表示させて見ましょう。
if(BUILD_opencv_python3)
status("HAVE_open_CV3????? ${HAVE_opencv_python3}")
status("NUMPY dir????? ${PYTHON3_NUMPY_INCLUDE_DIRS}")
status("")
```
とすると、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146529/18626005-06a9-642b-4ec7-72144342558f.png)
と表示されました。というわけで、```HAVE_opencv_python3```をONにするのと、```PYTHON3_NUMPY_INCLUDE_DIRS```にディレクトリ名を設定する旅に出ましょう。
注意点として、今回はcmakeファイルをいじりながらログを確認していきますが、**前回時のcmakeのログが残ってしまうため、チェックの際はbuildディレクトリ以下は毎回全部消した方が確実です。**
# HAVE_opencv_python3をONにする旅
さて、また同じように、gitリポジトリ内を検索してみましょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146529/d5fd0907-f9a6-8ff2-90c6-403ef3de4004.png)
無い・・・・だと・・・・?
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146529/317e9d6a-dc80-b8e6-a1cf-f40cf546209a.png)
冗談です。頑張ります。手がかりを探すため、まずはCMakeLists.txtの中からpythonを検出している入り口を探しに行きます。すると、こんな記述が・・・!
```CMakeList.txt
# --- Python Support ---
if(NOT IOS)
include(cmake/OpenCVDetectPython.cmake)
endif()
```
さて、ここでPythonを探しているかを確認するため、この前後で、変数```HAVE_opencv_python3```と```PYTHON3_EXECUTABLE```がどのように変化しているかを見てみましょう。
```CMakeList.txt
if(NOT IOS)
status("HAVE_open_CV3????? ${HAVE_opencv_python3}") <- HAVE_opencv_python3を表示
status("exec????? ${PYTHON3_EXECUTABLE}") <- PYTHON3_EXECUTABLEを表示
include(cmake/OpenCVDetectPython.cmake)
status("HAVE_open_CV3????? ${HAVE_opencv_python3}")
status("exec????? ${PYTHON3_EXECUTABLE}")
endif()
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146529/367d1bc5-87fe-edff-2181-0337a10d20b8.png)
上の????とあるところでは、exec側が何も設定されていませんが、下では```/opt/conda/bin/python3/```が設定されています。というわけで、ここで何かが起きていることは確認できます。なお、```HAVE_opencv_python3```はこの段階ではまだ何も入っておらず、この行より下で、何かのフラグに従ってON/OFFが決まる模様です。どこで```HAVE_opencv_python3```が生成されたかを引き続き探りましょう。と言ってもpythonの文字も特になく手がかりがありません。
**各行に、messageを入れてログを確認しまくります。**
```
message("1: HAVE_open_CV3????? ${HAVE_opencv_python3}")
```
こんな感じのコードを入れまくって、OFFに切り替わる瞬間を探します。・・・すると、以下の所でOFFフラグが生成されることがわかります。
```CMakeList.txt
# OpenCV modules
message("321: HAVE_open_CV3????? ${HAVE_opencv_python3}")
add_subdirectory(modules)
message("322: HAVE_open_CV3????? ${HAVE_opencv_python3}")
```
一番上では、HAVE_open_CV3にはフラグが入っていませんが、一番下では```OFF```が入力されています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146529/56da6df3-02ab-c667-bc27-6e2d3cc28f50.png)
ということで、
```
add_subdirectory(modules)
```
がキーであることが分かります。まずはここを深掘って、```HAVE_opencv_python3```が切り替わる瞬間を探しましょう。modulesディレクトリ内のCMakeファイルを確認すると、内容はとてもシンプルで、
```opencv/modules/CMakeLists.txt
add_definitions(-D__OPENCV_BUILD=1)
if(NOT OPENCV_MODULES_PATH)
set(OPENCV_MODULES_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
endif()
ocv_glob_modules(${OPENCV_MODULES_PATH} EXTRA ${OPENCV_EXTRA_MODULES_PATH})
```
となっています。```ocv_glob_modules```が具体的に何かを処理しているようですね・・・ということで検索。・・・すると、```cmake/OpenCVModule.cmake```の中で定義されているようです。中を軽く読んでみましょう。
長いけど、今回はHAVE_を探す旅なので、細かいところは飛ばしつつ、ファイル全体を見て行きましょう。とりあえず、ざっくりと```HAVE```の文字を探すと、たくさんヒットする。ここのどこかで```HAVE_opencv_python3```がON/OFFされる予感がします。さて、ocv_glob_modules関数を見てみると、大まかに、collect modules, ```__ocv_resolve_dependencies```, create modulesから成っています。最初と最後は、add_subdirectoryで飛ばしているだけ、```__ocv_resolve_dependencies```が怪しそうなので中を見てみましょう。
すると、すぐ見つかりました。
```cmake/OpenCVModule.cmake
foreach(m ${OPENCV_MODULES_DISABLED_USER})
set(HAVE_${m} OFF CACHE INTERNAL "Module ${m} will not be built in current configuration")
endforeach()
foreach(m ${OPENCV_MODULES_BUILD})
set(HAVE_${m} ON CACHE INTERNAL "Module ${m} will be built in current configuration")
endforeach()
```
ここが、怪しい。ということで、お決まりのmessageチェックをしてみましょう。前後をさっきのmessageコマンドで挟む。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146529/e0d81e99-39e3-df2d-df86-e514b15b2793.png)
...人生は厳しい
ここに来た時点で、既にOFFが入っていた。もう少し前に戻ってみよう。最初のブロックのどこかがターゲットなので、ひたすらmessageを入れる。結果として、ここがターゲットであることが分かりました。
```cmake/OpenCVModule.cmake
message("4 HAVE_open_CV3 in ocv_resolve_dependencies ????? ${HAVE_opencv_python3}")
message("${__modpath} ${CMAKE_CURRENT_BINARY_DIR}/${mod}/.${mod}")
add_subdirectory("${__modpath}" "${CMAKE_CURRENT_BINARY_DIR}/${mod}/.${mod}")
message("5 HAVE_open_CV3 in ocv_resolve_dependencies ????? ${HAVE_opencv_python3}")
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146529/54c40751-63cd-5a23-0f7a-d243de04a4c5.png)
何をやっているか見てみましょう。
```
message("${__modpath} ${CMAKE_CURRENT_BINARY_DIR}/${mod}/.${mod}")
```
とすると・・・
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146529/f71250ad-365b-a1fb-1d46-8cd280541681.png)
みたいな感じで、```/opencv/modules/python```というディレクトリをaddすると、目的のフラグがON/OFFになるらしい。なお、後者の```.python```はadd_subdirectoryの定義上ここでは不要。というわけで、```/opencv/modules/python```を覗きましょう。
まず、```/opencv/modules/python```を見ると、CMakeLists.txtがいますので、ここの中に入って見ましょう。念のため、入り口と出口で目的のフラグが変化するかを確認するため、messageデバッグしましょう。ファイルの先頭と、最後でメッセージを表示させる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146529/9a1e7ac5-aaa3-d8f7-fa29-ffd0ae8557bf.png)
というわけで、このどこかで目的のフラグがON/OFFされているらしいことが分かる。いつものようにmessageを出しまくって確認すると、
```
add_subdirectory(python3)
```
でフラグが変わることが分かる。さて、```/opencv/modules/python/python3```ディレクトリを漁って行きましょう。
```/modules/python/python3/CMakeLists.txt
message("in /modules/python/python3/CMakeLists.txt 1 ????? ${HAVE_opencv_python3}")
if(NOT PYTHON3_INCLUDE_PATH OR NOT PYTHON3_NUMPY_INCLUDE_DIRS)
ocv_module_disable(python3)
endif()
message("in /modules/python/python3/CMakeLists.txt 2 ????? ${HAVE_opencv_python3}")
set(the_description "The python3 bindings")
set(MODULE_NAME python3)
set(MODULE_INSTALL_SUBDIR python3)
set(PYTHON PYTHON3)
message("in /modules/python/python3/CMakeLists.txt 3 ????? ${HAVE_opencv_python3}")
include(../common.cmake)
message("in /modules/python/python3/CMakeLists.txt 4 ????? ${HAVE_opencv_python3}")
unset(MODULE_NAME)
unset(MODULE_INSTALL_SUBDIR)
message("in /modules/python/python3/CMakeLists.txt head ????? ${HAVE_opencv_python3}")
if(MSVC)
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4996)
else()
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wdeprecated-declarations)
endif()
message("in /modules/python/python3/CMakeLists.txt head ????? ${HAVE_opencv_python3}")
```
こんな感じで、ところどころmessageを入れて、cmakeすると最初のmessageの時点で
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146529/3a633973-a644-93d6-16a9-5385cf5d63e6.png)
と、一行表示されただけで他の行まで行きませんでした。なので、```PYTHON3_INCLUDE_PATH```か```PYTHON3_NUMPY_INCLUDE_DIRS```が定義されていないと、ここで終了となるようです。
```/modules/python/python3/CMakeLists.txt
if(NOT PYTHON3_INCLUDE_PATH OR NOT PYTHON3_NUMPY_INCLUDE_DIRS)
ocv_module_disable(python3)
endif()
```
さて、フラグがセットされて、終了する様子を確認しましょう。```ocv_module_disable```を探して見てみると・・・
```opencv/cmake/OpenCVModule.cmake
set(HAVE_${__modname} OFF CACHE INTERNAL "Module ${__modname} can not be built in current configuration")
```
という感じで```HAVE_opencv_python3```がOFFにされるのを確認できました。
さて、ここで目的は、```PYTHON3_INCLUDE_PATH```の設定と、```PYTHON3_NUMPY_INCLUDE_DIRS```の設定に変わります。これらの変数に何が入っているか、```/modules/python/python3/CMakeLists.txt```の先頭に以下を追加して確認すると・・・
```/modules/python/python3/CMakeLists.txt
message("PYTHON3_INCLUDE_PATH ${PYTHON3_INCLUDE_PATH}")
message("PYTHON3_NUMPY_INCLUDE_DIRS ${PYTHON3_NUMPY_INCLUDE_DIR}")
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146529/767ecb5b-8a11-beba-3c76-4365dd3a8e9b.png)
てな感じで、NUMPYが未設定となっています。つまり**Numpyを先に入れないと、```HAVE_opencv_python3```のチェックまで進めない**ことが分かります。
ちなみに、PYTHON3_INCLUDE_PATHが入っていない場合、apt-getなどでpythonを入れている場合は、python-devを入れれば、ここに値が入るはず。入らなければ、頑張って探しましょう!
# 進路変更、PYTHON3_NUMPY_INCLUDE_DIRを入れる旅に出る
さて、これについては、最初から最後まで何も設定されないので手掛かりがありません。とりあえず検索してみましょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146529/5400ec59-e41d-591a-43e2-b2b136ad91d4.png)
なお、rootなのはDockerで作業しているからです。この中で、今まで通ってきた経路を選びましょう。怪しいのは、
```
cmake/OpenCVDetectPython.cmake
modules/python/common.cmake
```
でしょう。他のファイルは、これまでに確認済みで、NUMPYに設定するような記述はなかったはず。また、後者は、実は```opencv/modules/python/python3/CMakeLists.txt```の真ん中でincludeされており、まだ通っていない。という訳で、```cmake/OpenCVDetectPython.cmake```を読みましょう。
さて、ザーッと読んでみると、こんな構成です。
```opencv/cmake/OpenCVDetectPython.cmake
function(find_python preferred_version min_version library_env include_dir_env
found executable version_string version_major version_minor
libs_found libs_version_string libraries library debug_libraries
debug_library include_path include_dir include_dir2 packages_path
numpy_include_dirs numpy_version)
.
.
.
endfunction(find_python)
find_python(2.7 "${MIN_VER_PYTHON2}" PYTHON2_LIBRARY PYTHON2_INCLUDE_DIR
PYTHON2INTERP_FOUND PYTHON2_EXECUTABLE PYTHON2_VERSION_STRING
PYTHON2_VERSION_MAJOR PYTHON2_VERSION_MINOR PYTHON2LIBS_FOUND
PYTHON2LIBS_VERSION_STRING PYTHON2_LIBRARIES PYTHON2_LIBRARY
PYTHON2_DEBUG_LIBRARIES PYTHON2_LIBRARY_DEBUG PYTHON2_INCLUDE_PATH
PYTHON2_INCLUDE_DIR PYTHON2_INCLUDE_DIR2 PYTHON2_PACKAGES_PATH
PYTHON2_NUMPY_INCLUDE_DIRS PYTHON2_NUMPY_VERSION)
find_python(3.4 "${MIN_VER_PYTHON3}" PYTHON3_LIBRARY PYTHON3_INCLUDE_DIR
PYTHON3INTERP_FOUND PYTHON3_EXECUTABLE PYTHON3_VERSION_STRING
PYTHON3_VERSION_MAJOR PYTHON3_VERSION_MINOR PYTHON3LIBS_FOUND
PYTHON3LIBS_VERSION_STRING PYTHON3_LIBRARIES PYTHON3_LIBRARY
PYTHON3_DEBUG_LIBRARIES PYTHON3_LIBRARY_DEBUG PYTHON3_INCLUDE_PATH
PYTHON3_INCLUDE_DIR PYTHON3_INCLUDE_DIR2 PYTHON3_PACKAGES_PATH
PYTHON3_NUMPY_INCLUDE_DIRS PYTHON3_NUMPY_VERSION)
```
ここで、pythonを探してるらしいことはわかります。```find_python```の定義をよんでみると、
```opencv/cmake/OpenCVDetectPython.cmake
# numpy_include_dirs (variable): Output of found Python Numpy include dirs
# numpy_version (variable): Output of found Python Numpy version
```
という記述が。という訳で、numpy_include_dirsに値がセットされているタイミング、条件を確認してみます。
まず、明らかに中間にある
```opencv/cmake/OpenCVDetectPython.cmake
set(_numpy_include_dirs ${${numpy_include_dirs}})
```
が怪しいですね。```_numpy_include_dirs```を追っかけると、すぐ下に、
```opencv/cmake/OpenCVDetectPython.cmake
execute_process(COMMAND "${_executable}" -c "import os; os.environ['DISTUTILS_USE_SDK']='1'; import numpy.distutils; print(os.pathsep.join(numpy.distutils.misc_util.get_numpy_include_dirs()))"
RESULT_VARIABLE _numpy_process
OUTPUT_VARIABLE _numpy_include_dirs
OUTPUT_STRIP_TRAILING_WHITESPACE)
```
という表記が!という訳で、ここにデバッグコードを入れて何をやっているか確認してみましょう。
```
message("${_executable} -c import os; os.environ['DISTUTILS_USE_SDK']='1'; import numpy.distutils; print(os.pathsep.join(numpy.distutils.misc_util.get_numpy_include_dirs()))")
```
というのを直前に入れると、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146529/8afd0ad1-4751-bebc-c559-f581f591b4a7.png)
と出ました。ということで、numpyを呼び出そうとしたら、import errorが出ていることが確認できました。そこで、ようやくnumpyをインストールしてみます!(**そんくらい先にやっとけというツッコミは、今回はそういう記事なので・・・**ということで)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146529/25b4eb49-a1c3-e4b7-9026-371619afd3f6.png)
無事、エラーが消えました!さて、PYTHON3_NUMPY_INCLUDE_DIRがセットされたかを確認しましょう。一番最初のCMakeの画面に戻ると・・・・
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146529/bf88ab13-0a64-9bd4-3b47-677ea4902d70.png)
numpyに値がセットされていました!!めでたし!さて、困ったことに、実はこれだけが原因だったらしく、pythonが認識されてしまいました。これだけだとnumpyインストールするだけかよ!となってしまいます。
ちなみに、結局```HAVE_opencv_python3```がどこでON/OFFになるか見つける前に動いてしまった。
**が、ここまでは初心者コース、macに鞍替えしてもう一回やってみましょう**。
# Macでやってみる。
めちゃめちゃ汚い環境と化している手元のMacでもう一度確認してみますと、この有様。何も見つからない、素晴らしいですね。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146529/10197a10-f5c1-4941-8448-0782161ca42e.png)
pythonはどこに行ったレベル。ちなみにnumpyもpythonも入っています。さて、もう一度同じ手順を踏む訳ですが、**正直全部書くのが面倒になってきたので、message命令を入れまくって見つかった事にします**。
さて、先ほどの```OpenCVDetectPython.cmake```で色々とチェックしているのがわかりましたので、ここを見ていきましょう。全部認識されていないので、頭から確認します。
```cmake/OpenCVDetectPython.cmake
if(NOT ${found})
message(WARNING, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ${executable}")
message(WARNING, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ${${executable}}")
ocv_check_environment_variables(${executable})
```
とすると
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146529/98331ec9-f9da-3cd3-1f70-b400cb98c9ac.png)
と表示されます。これは、```executable```には、```PYTHON3_EXECUTABLE```が入っており、ここに、何か値をセットすると、```${${executable}}```とすると、その値が実施されます。さて、PYTHON3_EXECUTABLEはどこでセットされるか。検索するとマニュアルがヒットし、
```
-# [optional] Building python. Set the following python parameters:
- PYTHON2(3)_EXECUTABLE = <path to python>
- PYTHON_INCLUDE_DIR = /usr/include/python<version>
- PYTHON_INCLUDE_DIR2 = /usr/include/x86_64-linux-gnu/python<version> - PYTHON_LIBRARY = /usr/lib/x86_64-linux-gnu/libpython<version>.so
- PYTHON2(3)_NUMPY_INCLUDE_DIRS = /usr/lib/python<version>/dist-packages/numpy/core/include/
```
と、cmakeコマンドを使う際に自分で入れろ、と書いてあります。
```sh
$ which python
/Users/peisuke/*************/python
```
として、自分のpythonのパスを調べて、cmake実施時に、コマンドに追加しましょう。
```sh
-D PYTHON3_EXECUTABLE=/Users/peisuke/*************/python
```
みたいに。すると・・・
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146529/042902b1-a3dd-5ce4-9cb7-d10783dc6e81.png)
として、実行スクリプトが認識されました!Summaryの所も、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146529/631e1e8c-13ab-082e-5ca0-16200f650061.png)
ちょっと情報が増えました。次にいきましょう。SummaryからはInterpreterが発見されているけど、それ以外がないと言われているので下の方を見ていきましょう。すると、
```cmake/OpenCVDetectPython.cmake
find_package(PythonLibs...)
```
みたいな記述があるので、その後ろに
```
message(WARNING, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ${PYTHON_LIBRARY}")
message(WARNING, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ${PYTHON_INCLUDE_DIR}")
```
を仕込んで見ると、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146529/eac7fc1b-f5ac-f901-3279-834f5192c068.png)
として、Includeディレクトリ、とLibが見つかっているのは確認できます。Libraryが見つかっているのに、Summaryに表示されないということは、先ほどと同様Numpyが原因と考えられます。先ほどはNumpyのインストールだけで認識されましたが、今回は既にNumpyは入っているのに見つからない。Mac+Conda+pyenvとかゴチャゴチャ入っていて、うまくincludeパスが見つかっていない模様です。なので、手動でnumpyのディレクトリを設定しましょう。
```
python -c "import numpy;print(numpy.get_include())"
```
とすると、ディレクトリが表示されるので、cmakeのパスに加えてみましょう。
```
-D PYTHON3_NUMPY_INCLUDE_DIRS=XXXXXXXXXX
```
結果は・・・
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146529/19b95b6f-b0c6-98c0-c8df-5cb60ba873ec.png)
認識されました!
他にうまくいかないケースとしては、```PYTHON_LIBRARY```と```PYTHON_INCLUDE_DIR```が見つからないケースです。無理やり設定してもいいですし、```find_package(PythonLibs)```が見つけられるように、**cmakeがデフォルトで持っているFindPythonLib.cmakeに潜るのも一興ですね。少し大変ですが僕もたまにやります。**問題を難しくしているのは、Numpyが見つからないだけなのに、```PYTHON_LIBRARY```が見つからないと怒られたりと、問題を分けられないことがしばしばある点です。その場合にも、この辺のコードを見て、どこが問題なのかをチェックすれば、いつでも解決できますね。
# その他のケース
condaだと、PythonLibsが見つからない場合もよくある。python3.6を入れてるのであれば、例えば、
```
-D PYTHON_LIBRARY=/opt/conda/lib/libpython3.6m.so
-D PYTHON_INCLUDE_DIR=/opt/conda/include/python3.6m/
```
をビルドオプションに入れると良かったりする。
# おわりに
長くてダラダラした記事になってしまいましたが、個人的にpython bindingで失敗することは結構あるので、作業ログは取っておきたいなぁと思っており、ちょうど良い機会でした。多分ここまで読む人は世の中にいないと思いますが、これを機にpython bindingの達人を目指してみるのは如何でしょうか。
なお、この上級編として、OpenCV内のpython bindingのコードを切り貼りして、C++とpythonを繋げる[マニアックな技を昨年のAdvent Calenderで公開しています](https://qiita.com/peisuke/items/f648375c8fa8f9a08541)(一年前はPython2.7を使っていたので、3系では動きませんが)。そちらも併せて読んでいただければと思います。では、よいお年を〜。