usagi / virtual-keyboard-prototype-1

仮想キーボード試作1型
3 stars 0 forks source link

relwithdebinfo版を実行したらエラーが出た #66

Closed arisin closed 10 years ago

arisin commented 10 years ago
<< ./etupirka 2>log
zsh: abort      ./etupirka 2> log
  << tail log                                                                                                [master]
I0127 11:29:30.979910 2086286096 etupirka.cxx:99] run main mode main loop
I0127 11:29:30.979945 2086286096 etupirka.cxx:107] to camera_capture()
I0127 11:29:30.987565 2086286096 camera-capture.cxx:79] top-cam captured
I0127 11:29:36.592944 2086286096 camera-capture.cxx:83] front-cam captured
I0127 11:29:36.593024 2086286096 etupirka.cxx:111] to finger_detector_top()
I0127 11:29:36.594524 2086286096 etupirka.cxx:115] to finger_detector_front()
OpenCV Error: Assertion failed ((src.type() == CV_8UC1 || src.type() == CV_8UC3) && src.type() == dst.type() && src.size() == dst.size() && src.data != dst.data) in bilateralFilter_8u, file /opt/local/var/macports/build/_opt_mports_dports_graphics_opencv/opencv/work/opencv-2.4.7/modules/imgproc/src/smooth.cpp, line 1925
I0127 11:29:37.033519 84414464 finger-detector.cxx:210] circle x, y, r: 0, 0, 0
libc++abi.dylib: terminating with uncaught exception of type cv::Exception: /opt/local/var/macports/build/_opt_mports_dports_graphics_opencv/opencv/work/opencv-2.4.7/modules/imgproc/src/smooth.cpp:1925: error: (-215) (src.type() == CV_8UC1 || src.type() == CV_8UC3) && src.type() == dst.type() && src.size() == dst.size() && src.data != dst.data in function bilateralFilter_8u

MacOSXに入っているPhoto Boothというソフトでカメラがそもそも認識されているかを確認したところ

内蔵 iSight
UCAM-DLE300T_series(デフォルト)
UCAM-DLE300T_series #2

となっているので、認識はしているらしい。 etupirka.confのカメラIDは下記のように設定した。

top_camera_id=1
front_camera_id=2
arisin commented 10 years ago

etupirka.confを下記のように書き換えてみたところ、

top_camera_id=0
front_camera_id=2

エラー内容が変わった。

  << ./etupirka 2>log                                                                                        [master]
zsh: segmentation fault  ./etupirka 2> log
usagi commented 10 years ago

abortとかSEGVとか出た時にこそ、ログのtailとかの情報が必要です。そんだけじゃなんもわかんない・w・

arisin commented 10 years ago

etupirka.confを更に書き換えてみた。

top_camera_id=0
front_camera_id=1
  << ./etupirka 2>log                                                                                        [master]
Camera dropped frame!
Camera dropped frame!
・
・
・
Cleaned up camera.
Cleaned up camera.
  << tail log                                                                                                [master]
I0127 12:04:45.101711 2086286096 etupirka.cxx:122] circles_front.size(): 1
I0127 12:04:45.101722 2086286096 etupirka.cxx:124] to virtual_keyboard->reset()
I0127 12:04:45.101732 2086286096 etupirka.cxx:128] to for(circles_top)
I0127 12:04:45.101742 2086286096 etupirka.cxx:147] x-distance(ct, cf): 247.5
I0127 12:04:45.101753 2086286096 etupirka.cxx:161] to virtual_keyboard->pressing_keys()
I0127 12:04:45.101799 2086286096 etupirka.cxx:178] to send key-down without before downed
I0127 12:04:45.101810 2086286096 etupirka.cxx:190] to send key-up
I0127 12:04:45.101989 2086286096 etupirka.cxx:16] time_delta [ms]: 576.587
I0127 12:04:45.102076 2086286096 etupirka.cxx:89] exit main loop
I0127 12:04:45.102108 2086286096 main.cxx:12] to exit
arisin commented 10 years ago

MintLinux(Mac)でもやってみた。が、うまくいかない

  << ./etupirka 2>log
zsh: abort      ./etupirka 2> log
  << tail log                                                                                                         [master]
VIDIOC_STREAMON: No space left on device
I0127 12:45:43.266124  3616 camera-capture.cxx:83] front-cam captured
I0127 12:45:43.266160  3616 etupirka.cxx:109] to finger_detector_top()
I0127 12:45:43.540436  3616 finger-detector.cxx:261] circle x, y, r: 0, 0, 0
I0127 12:45:43.540509  3616 etupirka.cxx:112] circles_top.size(): 1
I0127 12:45:43.540518  3616 etupirka.cxx:114] to finger_detector_front()
OpenCV Error: Assertion failed ((src.type() == CV_8UC1 || src.type() == CV_8UC3) && src.type() == dst.type() && src.size() == dst.size() && src.data != dst.data) in bilateralFilter_8u, file /build/buildd/opencv-2.4.5+dfsg/modules/imgproc/src/smooth.cpp, line 1874
terminate called after throwing an instance of 'cv::Exception'
  what():  /build/buildd/opencv-2.4.5+dfsg/modules/imgproc/src/smooth.cpp:1874: error: (-215) (src.type() == CV_8UC1 || src.type() == CV_8UC3) && src.type() == dst.type() && src.size() == dst.size() && src.data != dst.data in function bilateralFilter_8u
>>etupirka.conf
top_camera_id=1
front_camera_id=2
arisin commented 10 years ago

MacのUSBポートに直に指すとLinuxMint(Mac)でも動作する模様。

top_camera_id=0
front_camera_id=1
  << tail log                                                                                                         [master]
I0127 15:09:44.184146  2669 etupirka.cxx:146] estimated real_position: (-122.725,161.287,18.4992)
I0127 15:09:44.184156  2669 etupirka.cxx:147] to virtual_keyboard->add_test()
I0127 15:09:44.184162  2669 virtual-keyboard.cxx:39] x(-122.725) y(161.287) stroke(18.4992)
I0127 15:09:44.184171  2669 virtual-keyboard.cxx:42] x_shifted: -341.8
I0127 15:09:44.184315  2669 etupirka.cxx:153] to virtual_keyboard->pressing_keys()
I0127 15:09:44.184329  2669 etupirka.cxx:170] to send key-down without before downed
I0127 15:09:44.184335  2669 etupirka.cxx:182] to send key-up
I0127 15:09:44.184351  2669 etupirka.cxx:14] time_delta [ns]508846258
I0127 15:09:44.184372  2669 etupirka.cxx:87] exit main loop
I0127 15:09:44.184381  2669 main.cxx:12] to exit
<< grep 'time_delta' log | awk 'BEGIN{s=999999999} {a+=$7; if(s>$7)s=$7; if(b<$7)b=$7} END{print a/NR, NR, s, b}'   [master]
0 1638  

何故か数値が2つしか出てこない。 おまけにカメラID0はMacのカメラではないかと思われる(ランプが点灯してた)

top_camera_id=0
front_camera_id=1

を指定すると

  << ./etupirka 2>log                                                                                                 [master]
zsh: abort      ./etupirka 2> log

となる。

VIDIOC_STREAMON: No space left on device
I0127 15:16:00.479943  2995 camera-capture.cxx:83] front-cam captured
I0127 15:16:00.479990  2995 etupirka.cxx:109] to finger_detector_top()
I0127 15:16:00.730785  2995 finger-detector.cxx:261] circle x, y, r: 0, 0, 0
I0127 15:16:00.730861  2995 etupirka.cxx:112] circles_top.size(): 1
I0127 15:16:00.730870  2995 etupirka.cxx:114] to finger_detector_front()
OpenCV Error: Assertion failed ((src.type() == CV_8UC1 || src.type() == CV_8UC3) && src.type() == dst.type() && src.size() == dst.size() && src.data != dst.data) in bilateralFilter_8u, file /build/buildd/opencv-2.4.5+dfsg/modules/imgproc/src/smooth.cpp, line 1874
terminate called after throwing an instance of 'cv::Exception'
  what():  /build/buildd/opencv-2.4.5+dfsg/modules/imgproc/src/smooth.cpp:1874: error: (-215) (src.type() == CV_8UC1 || src.type() == CV_8UC3) && src.type() == dst.type() && src.size() == dst.size() && src.data != dst.data in function bilateralFilter_8u

おそらく電力不足ではないだろうか。

arisin commented 10 years ago

MacOSXにて、USBハブに2台のカメラをつなぎ、ID1と2を指定してgdbした結果です。 よろしくお願いします。

(lldb) n
I0127 17:37:11.256295 1989731088 etupirka.cxx:115] to finger_detector_front()
Process 1084 stopped
* thread #1: tid = 0x4040, 0x000000010000f280 etupirka`arisin::etupirka::etupirka_t::run_main(this=0x00007fff5fbfee88)::$_1::operator()() const + 1312 at etupirka.cxx:117, queue = 'com.apple.main-thread, stop reason = step over
    frame #0: 0x000000010000f280 etupirka`arisin::etupirka::etupirka_t::run_main(this=0x00007fff5fbfee88)::$_1::operator()() const + 1312 at etupirka.cxx:117
   114            
   115            DLOG(INFO) << "to finger_detector_front()";
   116            // frontから指先群を検出する。
-> 117            auto finger_detector_future_front = std::async([&](){ return (*finger_detector_front)(captured_frames.front); });
   118            
   119            const auto circles_top   = finger_detector_future_top.get();
   120            const auto circles_front = finger_detector_future_front.get();
(lldb) n
Camera dropped frame!
Camera dropped frame!
Camera dropped frame!
Camera dropped frame!
Camera dropped frame!
Camera dropped frame!
Camera dropped frame!
OpenCV Error: Assertion failed ((src.type() == CV_8UC1 || src.type() == CV_8UC3) && src.type() == dst.type() && src.size() == dst.size() && src.data != dst.data) in bilateralFilter_8u, file /opt/local/var/macports/build/_opt_mports_dports_graphics_opencv/opencv/work/opencv-2.4.7/modules/imgproc/src/smooth.cpp, line 1925
Process 1084 stopped
* thread #1: tid = 0x4040, 0x000000010000f65f etupirka`arisin::etupirka::etupirka_t::run_main(this=0x00007fff5fbfee88)::$_1::operator()() const + 2303 at etupirka.cxx:119, queue = 'com.apple.main-thread, stop reason = step over
    frame #0: 0x000000010000f65f etupirka`arisin::etupirka::etupirka_t::run_main(this=0x00007fff5fbfee88)::$_1::operator()() const + 2303 at etupirka.cxx:119
   116            // frontから指先群を検出する。
   117            auto finger_detector_future_front = std::async([&](){ return (*finger_detector_front)(captured_frames.front); });
   118            
-> 119            const auto circles_top   = finger_detector_future_top.get();
   120            const auto circles_front = finger_detector_future_front.get();
   121            DLOG(INFO) << "circles_top.size(): "   << circles_top.size();
   122            DLOG(INFO) << "circles_front.size(): " << circles_front.size();
(lldb) n
Camera dropped frame!
Camera dropped frame!
Camera dropped frame!
Process 1084 stopped
* thread #13: tid = 0x425f, 0x00000001000359f0 etupirka`arisin::etupirka::finger_detector_t::operator(this=<unavailable>, frame=<unavailable>)(cv::Mat const&) + 3232 at finger-detector.cxx:210, stop reason = breakpoint 2.1
    frame #0: 0x00000001000359f0 etupirka`arisin::etupirka::finger_detector_t::operator(this=<unavailable>, frame=<unavailable>)(cv::Mat const&) + 3232 at finger-detector.cxx:210
   207        }
   208  #ifndef NDEBUG
   209        for(const auto& circle: circles)
-> 210          DLOG(INFO) << "circle x, y, r: " << circle[0] << ", " << circle[1] << ", " << circle[2];
   211  #endif
   212        return circles;
   213      }
arisin commented 10 years ago

MacのUSBポートにハブをつないで、そこにWebカメラを2台つなぐと、片方は認識できないようだ。 ただ、Macのポート2つにWebカメラを挿すと電力不足になる。

仕方ないので、Webカメラ1台はMacのUSBポートに直接挿し、もう1台はAC給電しているUSBハブにつなぐと ID1,2で動作するようだ。

usagi commented 10 years ago

理由は2つあって、

  1. USBハブを挟む事で使用する機器が本来持っているUSBの実効転送速度(CPUやチップやノイズ対策によって変化)に到達できないほどの負荷になってしまう。
  2. しかしPC本体だけのセルフパワーでは給電能力も不足してしまう。

このコンボによる問題発生と考えるのが良いかもしれません。試しに2x320x240(≈ 105 [Mbits/sec])にしてみたらUSBハブに2台とも接続でも大丈夫となれば、確証も少しアップ。

USBカメラからの画像転送モードにはBGRのほか、YUYやMJPEGがあるので、これらをOpenCVで使用できないか調査検討してみます。特にMJPEGが使える場合は全てのフレームをJPEGにするのと同じですから転送量は1/10以下にできる可能性があります。V4L2レベルでは余裕で対応できるのですが、OpenCV2レベルからどうにかできるものなのか調査検討が必要です。

usagi commented 10 years ago

メインボードH87PERFORMANCEにi7-4770を挿したPCでUSB3.0ポートへの直結ならばUSB3.0全体での帯域には余裕があるため2台同時でも問題無い。

そこで、その問題無いポートの1つにUSB2.0ハブを接続して、その先に2台同時に接続したところ、同様の実行時エラーを観測しました。

usagi commented 10 years ago

68 ← ハードウェアの制約はソフトウェア側から超える方法は無さそうです。

そういうわけなので、せめて実行時にエラー原因がわかりやすい表示を行ってから死ねないか検討します。

usagi commented 10 years ago

69 の修正で起動時に既におかしい場合にはエラーメッセージを吐いてFATALする様にしたのと同時に、そのテストのために各カメラの最初の3フレームのうち2フレーム分を取得だけして使わずに廃棄する様にしてみました。

この最初の2フレーム(1フレームで十分かもしれないけど念の為)を廃棄する処理により、最初の1フレームが妙に過負荷になっている現象も実際問題回避できる様になったかもしれません。

また、 #70 の修正により動作中にキャプチャーに異常が発生した場合もWARNINGを発しつつも、そのフレームの処理は諦めてスキップし、次のフレームの正常な動作を期待して動作し続ける様に修正しました。

これにより、動作中に突然落ちる現象が減ると思います。

@arisin 少し動作テストしてみて下さい。また、このIssueはハードウェアの制約をソフトウェアで少なくとも現在は超えられない( #68 の試みなど)ので、動作テストののち、状況に納得できればCloseもおねがいします。

usagi commented 10 years ago

閉じます。何か問題があればre-open或いは新たにIssue立てて下さい。