0

皆さん、こんにちは。写真を撮り、そのパレットを分析してメイン カラーを取得したいのですが (これが最も簡単な方法だと思います)、どこから始めればよいかわかりません。

4

1 に答える 1

0

生の 24 ビット RGB 画像があり、各色が表示される回数を調べたいとします。

これを行うには、実際には 2 つの簡単な方法があります。

私のお気に入りは、可能な色ごとにintの配列を作成し、その配列にインデックスを付けるだけで、そのメソッドは64メガのメモリを使用します。

別の方法は、リンクされたリストを作成し、新しい色が検出されるたびに追加することです。リストに格納されている構造体には、色と検出された回数が格納されます。各ピクセルのリスト全体ですが、実際に使用された色のみがリストに表示されるため、使用回数でソートする方が高速です(小さな画像にも理想的です)

私は2つの間の妥協点が好きです:

たとえば、リンクされたリストの配列にインデックスを付けるために赤と緑を取ると、配列はわずか 256k (リストへのポインターを格納するだけであると仮定) になり、検索するリストは比較的短くなります。赤、緑の色。SINGLE MOSTの使用色のみに関心がある場合は、これを「最大色」変数に保存し、ピクセルを反復して色をインクリメントするたびに比較します。そのようにする必要はありません構造全体を調べて、最後に最も使用されるものを探します。

struct Pixel
{
   byte R,G,B;
}

const int noPixels = 1024*768; // this is whatever the number of pixels you have is

Pixel pixels[noPixels]; // this is your raw array of pixels

unsinged int mostUsedCount = 0;
Pixel mostUsedColor;

struct ColorNode
{
    ColorNode* next;
    unsigned int count;
    byte B;
} 

ColorNode* RG = new ColorNode[256*256];
memset(RG,0,sizeof(ColorNode)*256*256);

for(int i = 0; i<noPixels; i++)
{
   int idx = pixels[i].R + pixels[i].G*256;
   ColorNode*t;
   for(t=RG[idx]; t; t = t->next)
   {
      if(t->B == pixels[i].B)
      {
          break;
      }
   }
   if(!t)
   {
       t = new ColorNode;
       t->next = RG[idx];
       RG[idx] = t;
       t->B = pixels[i].B;
       t->count = 0;
   }

   t->count++;
   if(t->count > mostUsedCount)
   {
       mostUsedCount = t->count;
       mostUsedColor = pixels[i];
   }
}

そのようなリストを単に検索するのではなく、バイナリツリーまたは何らかの種類のツリーも使用することを検討してください。しかし、私はその種のことについてあまり詳しくありません...

そうそう...メモリ管理を忘れていました。

配列全体を調べて、削除が必要なすべてのノードを削除することもできますが、それは退屈です。

可能であれば、最初に必要になる可能性のあるすべてのメモリを割り当てます。これは、256k + sizeof(ColorNode) *noPixels ~= 256 + 生の画像データのサイズの 2 ~ 3 倍になります。

そうすれば、単純なスタック メソッドを使用してノードを引き出すだけで、すべてを一気に削除できます。

別の方法として、割り当てられたすべてのノードの別のリンク リストにノードを追加することもできます。これにより、反復プロセスが増加し、Color ノードにデータが追加され、削除するリストを見つけるために配列全体を反復処理する必要がなくなります。

于 2010-02-10T02:41:21.503 に答える