Quantcast
Channel: アイデアタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 113

HSVより計算量の少ない色認識手法のアイデア

$
0
0

HSV

HSVについては以下を参照。
画像処理ソリューション「色相、彩度、明度の計算方法」
http://imagingsolution.blog.fc2.com/blog-entry-247.html

この6角形を見ていてふと思いついた計算法について記載します。

本アイデア(立方体切り出し)

R,G,Bを軸とする立方体を考える。0 <= R <= 255, 0 <= G <= 255, 0 <= B <= 255 とする。
RGB立方体.png

ここでR=Gの場合について考える。
R=Gの場合、以下の図の赤で囲った面上の色になる。

G_Rが0.png

R+n=Gの場合は以下になる。(0 < n <= 255)

G_Rが正.png

R+n=G(0 < n <= 255)
R+m=G(-255 < m < 0)
で囲うと以下のようになる。

G_Rがある範囲.png

2つのは以下のように変形できる。
R - G = n
R - G = m

つまり、上記の囲われた範囲の色は
m < R-G < n

である。
ここで以下図のように、RGBが(0,0,0)から(255,255,255)を結ぶ線上から見た視点に変えると、以下のように6角形に見える。

RGB0255を真上から.png

(0,0,0)と(255,255,255)を結んだ直線と、先ほどの
R - G = n
R - G = m
の平面は平行であるので、先ほどの2つの平面をこの図上に描くと2つの直線に見える。

RGB0255を真上から範囲の線.png

m < R-G < nは以下の斜線の範囲になる。

RGB0255を真上から範囲塗.png

ところで、(0,0,0)と(255,255,255)を1直線に結んだ線上から見た6角形の図というのが
HSVの六角推を上から見た彩度と色相だけの図になるらしい。

これをG-B、B-Rにも同様に適用すると
彩度と色相だけなら、以下の計算で識別できる。

min1 < R-G < max1
min2 < G-B < max2
min3 < B-R < max3

ほんとに????

計算式 HSVとの比較

変換

HSVの場合の彩度と色相算出

//とある画素ループの中

   float max = Math.max(R, G, B);
   float min = Math.min(R, G, B);   
   float H;
   float S;

   if (max == min) {
    continue;
   }
   // S彩度
   S = (max - min) / max;

   //H色相
   if (max == R)
   {
      H = ((60 * (G - B)) / (max-min));
   }
   if (max == G)
   {
      H = ((60 * (B - R)) / (max-min)) + 120;
   }
   if (max == B)
   {
      H = ((60 * (R - G)) / (max-min)) + 240;
   }

//・・・

本手法

//とある画素ループの中

   float R_G = R-G;
   float G_B = G-B;  
   float B_R = B-R;

//・・・

色識別

以下の範囲を識別対象とする。
※これまでの図とRとBが逆になっています。直すの面倒なのでこのままにします。
判定したい色.png

HSVの場合の彩度と色相算出

//とある画素ループの中

  // S彩度、H色相の判定
  if((Smin < S)  && (Smax > S) &&
     ((Hmin < H)  && (Hmax > H))
  {
      //目的の色
  }

//・・・

上記HSVによる判定処理で選択できる範囲のイメージは以下。
HSVによる判定イメージ.png

本手法

//とある画素ループの中


  // 色の判定
  if((R_Gmin < R_G)  && (R_Gmax > R_G) &&
     ((G_Bmin < G_B)  && (G_Bmax > G_B) &&
     ((B_Rmin < B_R)  && (B_Rmax > B_R))
  {
      //目的の色
  }
//・・・

上記本手法による判定処理で選択できる範囲のイメージは以下。
本手法による判定イメージ.png

本手法では、囲いの範囲の色を判定するので、一部上限、下限をなくすこともできる。
例えば以下のような感じ

//とある画素ループの中


  // 色の判定
  if((R_Gmin < R_G)  && (R_Gmax > R_G) &&
     /*((G_Bmin < G_B)  && (G_Bmax > G_B) &&*/
     ((B_Rmin < B_R)/*  && (B_Rmax > B_R)*/)
  {
      //目的の色
  }
//・・・

上記本手法による判定処理で選択できる範囲のイメージは以下。

本手法判定簡略化.png

YUVからの変換

映像ではYUVの値で画像を扱っているらしい。
HSVの場合は、一度RGBに変換してからHSVへ変換する。
しかし、本手法では、直接変換できる。
参考
YUVフォーマット及び YUV<->RGB変換
https://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html

YUVからの変換を含んだHSVの場合の彩度と色相算出

//とある画素ループの中
float R = Y          + 1.402*V;
float G = Y - 0.344*U - 0.714*V;
float B = Y + 1.772*U;

//以下は上記と同じ

   float max = Math.max(R, G, B);
   float min = Math.min(R, G, B);   
   float H;
   float S;

   if (max == min) {
    continue;
   }
   // S彩度
   S = (max - min) / max;

   //H色相
   if (max == R)
   {
      H = ((60 * (G - B)) / (max-min));
   }
   if (max == G)
   {
      H = ((60 * (B - R)) / (max-min)) + 120;
   }
   if (max == B)
   {
      H = ((60 * (R - G)) / (max-min)) + 240;
   }

//・・・

YUVからの変換を含んだ本手法

//とある画素ループの中
//float R = Y          + 1.402*V
//float G = Y - 0.344*U - 0.714*V
//float B = Y + 1.772*U

//R-G = (Y + 1.402*V) - (Y - 0.344*U - 0.714*V)
//G-B = (Y - 0.344*U - 0.714*V) - (Y + 1.772*U)
//B-R = (Y + 1.772*U) - (Y + 1.402*V)

   float R_G = 0.344*U + 2.116*V;
   float G_B = -1.428*U - 0.714*V;  
   float B_R = 1.772*U - 1.402*V;

//・・・

さらに、YUVはY0,Y1,U,V のようにYが2つある場合がある。
HSVの場合は、Y0の時とY1の時を計算しなければならないが、
本手法では、Yは計算上使わない(消える)ので計算は1度で済む。つまりYが2つある場合、HSVよりも計算する画素が半減する。

明度

「彩度と色相だけなら~」と上述したが、YUVからの変換なら、Y値をそのまま明度として使えるかも???

最後に

雑な図やコードですいません。
画像認識についてはそこまで詳しくはないのですが、ふと思いついたこのアイデアが既知か否か、または正誤についてネットで調べてみたのですが、見つかりませんでした。
素人発想なので、そもそもの考え方が間違っていて話にならないのかもしれませんが。

既知 or 間違っているなど、何かお分かりになる方ご教示お願いします。


Viewing all articles
Browse latest Browse all 113

Trending Articles