teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

5

typo修正

2017/11/15 09:32

投稿

toris-birds
toris-birds

スコア122

answer CHANGED
@@ -1,4 +1,4 @@
1
- 質問内容に2つの質問が同居していすが、エラーの対処部分の回答です。
1
+ 質問内容に2つ以上の質問が同居しているようですが、エラーの対処部分の回答です。
2
2
 
3
3
  エラーの原因:
4
4
  各画素に24 bit必要なHSVを格納するためのdst の型として、CV_8U (CV_8UC1)を指定したため。

4

コメントの内容を回答に反映

2017/11/15 09:32

投稿

toris-birds
toris-birds

スコア122

answer CHANGED
@@ -1,3 +1,31 @@
1
+ 質問内容に2つの質問が同居していますが、エラーの対処部分の回答です。
2
+
3
+ エラーの原因:
4
+ 各画素に24 bit必要なHSVを格納するためのdst の型として、CV_8U (CV_8UC1)を指定したため。
5
+
6
+ 対処法: 型をCV_8UC3に変更する。
7
+ `Mat dst = Mat.zeros(inputFrame.width(), inputFrame.height(), CV_8UC3);`
8
+
9
+ ----
10
+ この部分は必要なければ読み飛ばして下さい。
11
+
12
+ 「白と黒」について、少し混乱されているように思います。
13
+ RGBでは(255, 255, 255)、HSVでは(0, 0, 255)、8bitのグレースケールでは(255)などが「白」、
14
+ RGBでは(0, 0, 0)、HSVでは(0, 0, 0)、8bitのグレースケールでは(0)などが「黒」
15
+ として扱われると思いますが、これらは(1)を「白」、(0)を「黒」として扱う事と実質的に変わりありません。
16
+
17
+ また、`inRange()` の出力に含まれるのは、0xff (255) あるいは 0 のみです。
18
+
19
+ なので、`inRange()`で得られたdst2 を、「白黒」画像として扱えばよいかと思います。
20
+
21
+ 参考:
22
+ InRange
23
+ http://opencv.jp/opencv-2svn/py/core_operations_on_arrays.html#inrange
24
+ > src(I) が範囲内にあれば dst(I) に 0xff(すべてのビットが 1 )がセットされ,そうでなければ 0 がセットされます
25
+
26
+ ----
27
+ これ以降、旧内容です。消してしまうとコメントの流れが分からなくなるかと思いますので、参考に残しておきます。
28
+
1
29
  OpenCV を触っていないので、的外れかもしれませんが・・
2
30
 
3
31
  ・HSVで赤色のみを抽出

3

コメントの補足用にコードを追加

2017/11/15 09:30

投稿

toris-birds
toris-birds

スコア122

answer CHANGED
@@ -23,4 +23,71 @@
23
23
  LouiS0616さんが
24
24
  > 空のMatをcvtColorに放り込むと同様のエラーが出ます。
25
25
 
26
- と書かれていますので、同様の現象かと思います。
26
+ と書かれていますので、同様の現象かと思います。
27
+
28
+ ----
29
+ イメージをつかむために、一応、コードを置いておきます。
30
+ OpenCV を触っていないので、参考程度に(コンパイルが通らないかもしれません)
31
+
32
+ [RGB をそのまま使う版]
33
+
34
+ ```
35
+ public Mat onCameraFrame(Mat inputFrame) {
36
+ Mat src = inputFrame;
37
+
38
+ Mat src2 = src; // ここに入っているのはRGB値(の配列)
39
+ Mat dst2 = Mat.zeros(inputFrame.width(), inputFrame.height(), CV_8UC3); // changed
40
+
41
+ Scalar low = new Scalar(165, 20, 30); // 下限 (これはRGB値としての範囲のように思います)
42
+ Scalar high = new Scalar(179, 255, 255); // 上限 (これはRGB値としての範囲のように思います)
43
+
44
+ Core.inRange(src2, low, high, dst2); // 色抽出
45
+ return dst2;
46
+ }
47
+ ```
48
+
49
+ ----
50
+ [RGB to HSV 版]
51
+
52
+ ```
53
+ public Mat onCameraFrame(Mat inputFrame) {
54
+ Mat src = inputFrame;
55
+ Mat dst = Mat.zeros(inputFrame.width(), inputFrame.height(), CV_8UC3); // changed
56
+ Imgproc.cvtColor(src, dst, Imgproc.COLOR_RGB2HSV); // RGB to HSV (24 bit)
57
+
58
+ Mat src2 = dst; // ここに入っているのはHSV値(の配列)
59
+ Mat dst2 = Mat.zeros(inputFrame.width(), inputFrame.height(), CV_8UC3); // changed
60
+
61
+ // Scalar low = new Scalar(165, 20, 30); // 下限 (これはRGB値としての範囲のように思います)
62
+ // Scalar high = new Scalar(179, 255, 255); // 上限 (これはRGB値としての範囲のように思います)
63
+
64
+ // 範囲はサンプルです。H成分のみ制限。(実際は、赤は360度の方にもつながっているので、範囲等を考慮する必要があります)
65
+ Scalar low = new Scalar(0, 0, 0); // 下限
66
+ Scalar high = new Scalar(10, 255, 255); // 上限
67
+
68
+ Core.inRange(src2, low, high, dst2); // 色抽出
69
+ return dst2;
70
+ }
71
+ ```
72
+
73
+ ----
74
+ [RGB から 赤色成分を抽出して、「白と黒」として表現して、判定に使う版]
75
+
76
+ ```
77
+ public Mat onCameraFrame(Mat inputFrame) {
78
+ Mat src = inputFrame; // (24bitの配列)
79
+ Mat dst = Mat.zeros(inputFrame.width(), inputFrame.height(), CV_8UC1); // CV_8U と同じ(8bitの配列)
80
+
81
+ // ここで、srcから 赤色成分を抽出する (長くなるので省略)
82
+ //
83
+ // 「cv::Matの行列要素を,イテレータを介して扱う」
84
+ // http://opencv.jp/cookbook/opencv_mat.html#id40 などを参照
85
+ //
86
+ // 必要なのは、 srcの各画素 [R, G, B] から 赤色を表す何らかの値(8bitで表現) を計算する処理 と、
87
+ // 計算した値を dst に格納する処理
88
+ //
89
+ // 計算するついでに、色抽出 (一定の値を超えたら1、それ以外は0など)まで処理した方が楽です。
90
+
91
+ return dst;
92
+ }
93
+ ```

2

エラーの原因を追記しました

2017/11/12 09:26

投稿

toris-birds
toris-birds

スコア122

answer CHANGED
@@ -8,7 +8,19 @@
8
8
 
9
9
  ・HSV → RGBの変換でエラー
10
10
 
11
+ -- 削除 ここから --
11
12
  > error: (-215) ・・・
12
13
 
13
14
  RGB値が0~255に収まっていない等の現象が発生したのではないかと推測します。
14
- どこかでfloatが紛れ込んでいませんか?
15
+ どこかでfloatが紛れ込んでいませんか?
16
+ -- 削除 ここまで --
17
+
18
+ 追記1:
19
+ > Mat.zeros(inputFrame.width(), inputFrame.height(), CV_8U);
20
+
21
+ これで確保されるのは、width * height * (8bit) かと思いますので、HSVやRGB用に使用した場合、要素数が不足すると思います。
22
+
23
+ LouiS0616さんが
24
+ > 空のMatをcvtColorに放り込むと同様のエラーが出ます。
25
+
26
+ と書かれていますので、同様の現象かと思います。

1

考慮すべき条件を補足しました

2017/11/12 07:38

投稿

toris-birds
toris-birds

スコア122

answer CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ・HSVで赤色のみを抽出
4
4
 
5
- 理論上は、H値のレンジで判定可能かと思います。
5
+ 理論上は、(どのような赤かを気にしない場合は) H値のレンジで判定可能かと思います。
6
6
  ただし、赤は両サイドにある(0度側、360度側)ので、inRange等での判定に工夫が必要かもしれません。
7
7
  (例えば赤以外を抽出して反転など)
8
8