ツクツクボウシが鳴く時節になりました.あのひとたちの鳴き声を聴くとどうしても「天空の城ラピュタ」に出てくる飛行船を思い出してまうたかたかです.
6月末に標記のような問題を見つけて7月はじめに自分の周りのんについては対処したんですが,「そのうちパッチが反映されたんが(たかたかが使ってる)MacPorts でインストールできるようになるやろ」と放置してたら,いまだに未対応なので,記事に書いとくことにしました.ほんまは,MacPortsのメンテナさんに連絡して対応してもらうとかするのがええんでしょうが….
件の問題が発生する環境は,こんなんです:
- OS X Yosemite な MacBook Air/Pro で内蔵カメラを使用
- OpenCV は,MacPorts でいれた 3.1
$ port installed opencv opencv @3.1.0_3+eigen+opencl+python27+tbb (active)
この環境で,python で cv2.VideoCapture(3.1でのpython版のドキュメントが見つからないので,3.0の旧版にリンクしてます)使ったプログラム書いて動かすと,最初は問題なく動作しますが,100秒後に
libc++abi.dylib: terminating with uncaught exception of type NSException
というエラーを吐いてプログラムが異常終了します.
で,いろいろ探しまわった結果,対応策はこちらで見つけました:
MacOSX / QTKit capture: trying to fix invalid timer call · opencv/opencv@a2bda99 · GitHub
cap_qtkit.mm
にパッチを当てればよい,と.2月に master に merge されてるので,開発版をおっかけてる人は反映されてるんでしょう.リリース版使ってる人は,次の版のリリースを待ちましょう…というわけにもいかへんので,手動でパッチあてることにしました.
まず,OpenCV をいったんアンインストールします.
$ sudo port uninstall opencv@3.1.0_3+eigen+opencl+python27+tbb
そして,ソースアーカイブを集めてきて(fetch),展開し(extract),(MacPortsで用意してる)パッチを当てます(patch)
$ sudo port fetch opencv +eigen+opencl+python27+tbb $ sudo port extract opencv +eigen+opencl+python27+tbb $ sudo port patch opencv +eigen+opencl+python27+tbb
ちなみに,portコマンドが依存関係を自動で解消するので,port patch
だけ実行すれば上2つを勝手に先に実行してくれます.
展開されたソースファイルたちの中から目的のものを探してパッチを当てます.目的のファイルmodules/videoio/src/cap_qtkit.mm
は,次のどちらかから下っていった所にあると思います(7月に作業したときは前者だったけど,さきほど試したら後者でした.この話がなんか関係あるのかな? [MacPorts-announce] New build system).
/opt/local/var/macports/sources/rsync.macports.org/release/tarballs/ports/graphics/opencv /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_graphics_opencv/opencv/work
上記のディレクトリは,それぞれport dir
およびport work
の出力です.
では,パッチを当てましょう.こんなん.
--- modules/videoio/src/cap_qtkit.mm 2015-12-19 00:02:16.000000000 +0900 +++ modules/videoio/src/cap_qtkit.mm 2016-07-13 14:19:35.000000000 +0900 @@ -93,6 +93,8 @@ didDropVideoFrameWithSampleBuffer:(QTSam - (int)updateImage; - (IplImage*)getOutput; +- (void)doFireTimer:(NSTimer *)timer; + @end /***************************************************************************** @@ -622,6 +624,11 @@ didDropVideoFrameWithSampleBuffer:(QTSam return 1; } +- (void)doFireTimer:(NSTimer *)timer { + (void)timer; + // dummy +} + @end
上記の内容を ~/patch.txt
というファイルとして保存してたとすると,次のようにしてパッチを当てることができます.
$ cd `port work` $ cd opencv-3.1.0/modules/videoio/src $ sudo patch < ~/patch.txt
仕上げは,パッチを当てたソースからのビルドとインストール.
$ sudo port build opencv +eigen+opencl+python27+tbb $ sudo port -s install opencv +eigen+opencl+python27+tbb
install の際に -s を忘れると,せっかくのソースを無視してバイナリパッケージをインストールしてくれちゃう(当然パッチは反映されない)ので気をつけましょう.
後は,VideoCapture 使ったプログラムで動作確認.100秒経っても落ちなければおけ.