2011-07-13 4 views
6

グレースケール画像をカラーパレット(Matlabのカラーマップのような)でマッピングすることで、グレースケール画像をカラーで表示したいのですが、直接ピクセルアクセスによるOpenCvカラーマッピング

私はOpenCV cvSet2D機能を使用して管理しましたが、パフォーマンス上の理由から、直接ピクセルにアクセスしたいと思います。

しかし私がそうするとき、イメージには奇妙な色があります。私は異なる色(RGB、BGR、...)で色を設定しようとしましたが、周りを回っているように見えません。

IplImage* temp = cvCreateImage(cvSize(img->width/scale,img->height/scale), IPL_DEPTH_8U, 3); 
for (int y=0; y<temp->height; y++) 
{ 
    uchar* ptr1 = (uchar*) (temp->imageData + y * temp->widthStep); 
    uchar* ptr2 = (uchar*) (img->imageData + y * img->widthStep); 

    for (int x=0; x<temp->width; x++) 
    { 
     CvScalar v1; 

     int intensity = (int)ptr2[x]; 
     int b=0, g=0, r=0; 
     r = colormap[intensity][0]; 
     g = colormap[intensity][1]; 
     b = colormap[intensity][2]; 

     if (true) 
     { 
      ptr1[3*x] = b; 
      ptr1[3*x+1] = g; 
      ptr1[3*x+2] = r; 
     } 
     else 
     { 
      v1.val[0] = r; 
      v1.val[1] = g; 
      v1.val[2] = b; 
      cvSet2D(temp, y, x, v1); 
     } 
    } 
} 

変更した場合は(真の)異なるピクセルアクセス用の場合(偽)へ:

は私のコードがあります。

enter code here

ダイレクトメモリアクセスと間違った結果:

enter image description here

はあなたの助けをありがとう、私が行っている

+0

間違いはありません。正しいバイトオーダは 'imageData'の中のBGRでなければなりません。バイトオーダーを変更した場合、イメージはどのように変化しますか?それは変わるべきです、さもなければあなたは何か間違っています。 1つの色だけをレンダリングしてみてください(他のチャンネルは0 /黒のままにしておきます)。それらが合うかどうかを確認してください。アラインメントは正しいようですが、私はコーナーの周りの硬いコントラストについて少し混乱しています。 – Mario

+2

私のエラーを見つけました...実際にはRGBですが、それは問題ではありませんでした.255の代わりに256の色値を持っていました...本当に申し訳ありません...私は質問をして答えを見つけました。 – david

+0

ああ...大丈夫。それはハードコントラスト(オーバーフローなどによる)を説明しています。:) – Mario

答えて

0

私は私の質問のコメントで質問されたような質問を閉じるためにこれを投稿しています。

答えた:

私は私の誤りを見つけた...実際には、それはRGBのですが、それは問題ではなかった、私は256の代わりに255のカラー値を持っていた...本当に申し訳ありません...私はあなたの質問を推測すると、私は答えが見つかりました。

ありがとう

4

正しい結果がcvSet2DでありますマイクロソフトのKinectセンサーの彩度マップと同様のものです。グレースケールの奥行きマップをカラー画像に変換するために私が使用したコードは、あなたがしようとしているもののために機能します。私の場合、深さの値が500から2000の範囲にあるように少し修正が必要な場合があり、それらを再スケーリングしなければならなかった。

カラー画像にグレースケール画像を着色するための関数である:このようになり、入力画像に対して

void colorizeDepth(const Mat& gray, Mat& rgb) 
{ 
     double maxDisp= 255; 
     float S=1.f; 
     float V=1.f ; 

     rgb.create(gray.size(), CV_8UC3); 
     rgb = Scalar::all(0); 

    if(maxDisp < 1) 
      return; 

    for(int y = 0; y < gray.rows; y++) 
     { 
      for(int x = 0; x < gray.cols; x++) 
      { 
       uchar d = gray.at<uchar>(y,x); 
       unsigned int H = 255 - ((uchar)maxDisp - d) * 280/ (uchar)maxDisp;  
      unsigned int hi = (H/60) % 6; 

      float f = H/60.f - H/60; 
       float p = V * (1 - S); 
       float q = V * (1 - f * S); 
       float t = V * (1 - (1 - f) * S); 

      Point3f res; 

       if(hi == 0) //R = V, G = t, B = p 
        res = Point3f(p, t, V); 
       if(hi == 1) // R = q, G = V, B = p 
        res = Point3f(p, V, q); 
       if(hi == 2) // R = p, G = V, B = t 
        res = Point3f(t, V, p); 
       if(hi == 3) // R = p, G = q, B = V 
        res = Point3f(V, q, p); 
       if(hi == 4) // R = t, G = p, B = V 
        res = Point3f(V, p, t); 
       if(hi == 5) // R = V, G = p, B = q 
        res = Point3f(q, p, V); 

       uchar b = (uchar)(std::max(0.f, std::min (res.x, 1.f)) * 255.f); 
       uchar g = (uchar)(std::max(0.f, std::min (res.y, 1.f)) * 255.f); 
       uchar r = (uchar)(std::max(0.f, std::min (res.z, 1.f)) * 255.f); 

       rgb.at<Point3_<uchar> >(y,x) = Point3_<uchar>(b, g, r);  

     } 
     } 
} 

:このコードの

enter image description here

出力は:

enter image description here