12

8 ビットの IplImage を 32 ビットの IplImage に変換する必要があります。ウェブ全体のドキュメントを使用して、次のことを試しました。

// general code
img2 = cvCreateImage(cvSize(img->width, img->height), 32, 3);
int height    = img->height;
int width     = img->width;
int channels  = img->nChannels;
int step1     = img->widthStep;
int step2     = img2->widthStep;
int depth1    = img->depth;
int depth2    = img2->depth;
uchar *data1   = (uchar *)img->imageData;
uchar *data2   = (uchar *)img2->imageData;

for(h=0;h<height;h++) for(w=0;w<width;w++) for(c=0;c<channels;c++) {
   // attempt code...
}

// attempt one
// result: white image, two red spots which appear in the original image too.
// this is the closest result, what's going wrong?!
// see: http://files.dazjorz.com/cache/conversion.png
((float*)data2+h*step2+w*channels+c)[0] = data1[h*step1+w*channels+c];

// attempt two
// when I change float to unsigned long in both previous examples, I get a black screen.

// attempt three
// result: seemingly random data to the top of the screen.
data2[h*step2+w*channels*3+c] = data1[h*step1+w*channels+c];
data2[h*step2+w*channels*3+c+1] = 0x00;
data2[h*step2+w*channels*3+c+2] = 0x00;

// and then some other things. Nothing did what I wanted. I couldn't get an output
// image which looked the same as the input image.

ご覧のとおり、私は自分が何をしているのかよくわかりません。知りたいのですが、これを正しく行うことができれば、もっとうれしいです。助けてくれてありがとう!

4

6 に答える 6

30

探している関数は cvConvertScale() です。型変換は自動的に行われます。1/255 の係数でスケーリングすることを指定するだけです (範囲 [0...255] を [0...1] にマップします)。

例:

IplImage *im8 = cvLoadImage(argv[1]);
IplImage *im32 = cvCreateImage(cvSize(im8->width, im8->height), 32, 3);

cvConvertScale(im8, im32, 1/255.);

-内のドットに注意して1/255.、二重除算を強制します。それがなければ、スケールは 0 になります。

于 2009-01-20T16:24:32.110 に答える
6

おそらく、このリンクはあなたを助けることができますか?

編集OPとコメントの2回目の編集を受けて

やってみました

float value = 0.5

それ以外の

float value = 0x0000001;

float の色の値の範囲は 0.0 から 1.0 で、1.0 は白だと思いました。

于 2008-12-27T14:37:41.840 に答える
2

浮動小数点の色は 0.0 から 1.0 になり、uchar は 0 から 255 になります。次のコードで修正されます。

// h is height, w is width, c is current channel (0 to 2)
int b = ((uchar *)(img->imageData + h*img->widthStep))[w*img->nChannels + c];
((float *)(img2->imageData + h*img2->widthStep))[w*img2->nChannels + c] = ((float)b) / 255.0;

これを修正するのを手伝ってくれたStefan Schmidtに本当に感謝します!

于 2008-12-27T21:04:30.840 に答える
1

boost::shared_ptr と template-metaprogramming を使用して IplImage ラッパーを作成できます。私はそれを行い、自動的なガベージ コレクションと、ある深さから別の深さへの自動画像変換、または 1 チャンネルからマルチチャンネル画像への自動画像変換を取得しました。

API blImageAPI を呼び出しました。ここで見つけることができます: http://www.barbato.us/2010/10/14/image-data-structure-based-shared_ptr-iplimage/

非常に高速で、コードが非常に読みやすくなります (アルゴリズムの保守に適しています)。

何も変更せずに、opencv アルゴリズムで IplImage の代わりに使用することもできます。

がんばって、アルゴリズムを書いて楽しんでください!!!

于 2010-10-18T16:44:02.530 に答える
1

ドット (.) を配置しない場合、一部のコンパイラは int 除算として理解し、int 結果 (この場合はゼロ) を返します。

于 2009-04-15T05:07:06.873 に答える
0

IplImage *img8,*img32;
img8 =cvLoadImage("a.jpg",1);

    cvNamedWindow("Convert",1);
    img32 = cvCreateImage(cvGetSize(img8),IPL_DEPTH_32F,3);
    cvConvertScale(img8,img32,1.0/255.0,0.0);

//確認用 ピクセル値(0~1)を確認

    for(int row = 0; row < img32->height; row++ ){
                float* pt = (float*) (img32->imageData + row * img32->widthStep);
                for ( int col = 0; col < width; col++ )
                            printf("\n %3.3f , %3.3f , %3.3f ",pt[3*col],pt[3*col+1],pt[3*col+2]);                  
            }

    cvShowImage("Convert",img32);
    cvWaitKey(0);
    cvReleaseImage(&img8);
    cvReleaseImage(&img32);
    cvDestroyWindow("Convert");
于 2011-11-06T20:53:56.767 に答える