トップ回答者
Xbox One Kinect ピクセル単位でのHSV情報取得方法について

質問
-
現在,Kinectを用いてカラー映像上で色検出を行い,その点までの距離をだしたいと思っています
環境はWindows10, Visual Studio 2017, OpenCV 3.2です.
問題になっているのは,各ピクセルのHSVの情報を得る場合のデータ型がわからないことです.
以下にプログラムの流れを書かせていただきます.
Kinectを検出.cvtColorでrgbをhsvに変換.splitでhsvのマルチチャンネルをシングルチャンネル(channelsとしました)に分離.depthのx,yで画面上を走査しつつ,16bitで距離情報を取得,depth座標とrgb座標をdp・cpで定義,MapDepthPointToColorSpace(dp, d, &cp)で座標変換,cp.Xとcp.Yをint型にキャストしたものをax,ayとする.
ここまでは問題ありません.次に,走査している各ピクセルでHSV値を得るために
channels[0].at<uchar>(ay, ax)
を用いています.コンパイルは通るのですが,
OpenCV Error: Assertion failed ((unsigned)i0 < (unsigned)size.p[0]) in cv::Mat::at, file c:\opencv3.2.0\build\include\opencv2\core\mat.inl.hpp, line 955
c:\opencv3.2.0\build\include\opencv2\core\mat.inl.hpp:955: error: (-215) (unsigned)i0 < (unsigned)size.p[0] in function cv::Mat::atがコンソールに出ます.調べると<uchar>の部分が間違えているとわかりました.この部分をintやdoubleなど考えうるデータ型を試したのですが,同じエラーが出てしまいます.試したデータ型を下に書いておきます.
”int" "float " "double" "uchar " "char" "ushort" "short" "unsigned short" "UNIT16"
axとayの部分を単にx,yとすると正常に動きます.ただ,x,yとするとrgb座標では無いので見当違いな部分を検出します.
次に,rgb映像とdepth映像のピクセル比から
ax = x * 1920 / 512,ay = y * 1090 / 424
としてみましたが,画面の端になるほど誤差が増大してしまいした.
解決方法のわかる方がいらっしゃればどうぞよろしくお願いいたします.また,追加で書かなければならないことがありましたら書きますのでよろしくお願いいたします.
回答
-
i0、第 1 引数、今回のケースでは ay が範囲外だと指摘する assert です。
型の誤りではありません。Kinnect の SDK にはその座標の対応を取るためのインターフェースがあるようです。
http://unanancyowen.com/kinect-v2-coordinate-system-mapping/
https://social.msdn.microsoft.com/Forums/ja-JP/978c5723-d553-47ee-884e-b54b6dbc3b4f/kinect-v2colordepth?forum=windowsgeneraldevelopmentissuesja- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年6月26日 2:11
- 回答としてマーク 立花楓Microsoft employee, Moderator 2017年7月4日 0:57
すべての返信
-
i0、第 1 引数、今回のケースでは ay が範囲外だと指摘する assert です。
型の誤りではありません。Kinnect の SDK にはその座標の対応を取るためのインターフェースがあるようです。
http://unanancyowen.com/kinect-v2-coordinate-system-mapping/
https://social.msdn.microsoft.com/Forums/ja-JP/978c5723-d553-47ee-884e-b54b6dbc3b4f/kinect-v2colordepth?forum=windowsgeneraldevelopmentissuesja- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年6月26日 2:11
- 回答としてマーク 立花楓Microsoft employee, Moderator 2017年7月4日 0:57
-
Azuleanさんがご指摘されているように、
cv::Mat
の範囲外アクセスのassertです。
ピクセルへアクセスする前にKinect SDKのCoordinateMapperで変換した座標が画像データの幅と高さの範囲に含まれているか確認してください。サンプルコードで示すならばapp.cpp#L200やapp.cpp#L237のif文で確認しています。これは回答ではありませんが、質問を読んだ限りでは目的と実装が少し異なるように思います。
はじめにColor画像をフレーム単位でDepth座標系に(またはDepth画像をフレーム単位でColor座標系に)位置合わせしたデータを準備しておくと実装が簡単になると思います。
また、チャンネルごとに可視化したいなどの目的以外ではHSVの各チャンネルをあらかじめ分離しておく意味はあまりないと思います。
- 編集済み Tsukasa SugiuraMVP 2017年6月27日 17:06