6

私は数日間C++で実装されたopencv2で遊んでいて、ルックアップテーブルが画像に変更を適用する最も速い方法であることに気づきました。しかし、私は自分の目的のためにそれらを使用するのにいくつかの問題を抱えています。

以下のコードは、ピクセルの値を反転する例を示しています。

bool apply(Image& img) {
   int dim(256);
   Mat lut(1, &dim, CV_8U);
   for (int i=0; i<256; i++)
      lut.at<uchar>(i)= 255-i;
   LUT(img.final,lut,img.final);
   return true;
}

class Image {
public:
   const Mat& original;
   Mat final;
...
};

非常に効率的で、各ピクセルを1つずつ変更するよりもはるかに効率的であるため(私自身のテストで確認済み)、この方法を他の操作に使用したいと思います。ただし、これを行うには、各レイヤー(各色、画像はBGR)に個別にアクセスする必要があります。たとえば、青を255-iに、緑を255-i / 2に、赤を255-i/3に変更したいと思います。

私はしばらくの間ネットを検索してきましたが、正しい解決策を思い付くことができませんでした。私の知る限り、それは可能です(ドキュメント)が、それを実装する方法を見つけることができません。

4

1 に答える 1

6

重要なのは、ドキュメントの次の段落です。

テーブルには、単一のチャネル(この場合はすべてのチャネルに同じテーブルが使用されます)またはソース配列と同じ数のチャネルが必要です。

したがって、マルチチャネルLUTを作成する必要があります。

bool apply(Image& img) {
   int dim(256);

   Mat lut(1, &dim, CV_8UC(img.final.channels()));

   if( img.final.channels() == 1)
   {
      for (int i=0; i<256; i++)
         lut.at<uchar>(i)= 255-i;
   }
   else // stupid idea that all the images are either mono either multichannel
   {
      for (int i=0; i<256; i++)
      {
         lut.at<Vec3b>(i)[0]= 255-i;   // first channel  (B)
         lut.at<Vec3b>(i)[1]= 255-i/2; // second channel (G)
         lut.at<Vec3b>(i)[2]= 255-i/3; // ...            (R)
      }
   }

   LUT(img.final,lut,img.final); // are you sure you are doing final->final? 
   // if yes, correct the LUT allocation part

   return true;
}
于 2012-07-16T11:37:22.370 に答える