How to convert an 8-bit OpenCV IplImage* to a 32-bit IplImage*?

*爱你&永不变心* 提交于 2019-11-26 23:14:49

问题


I need to convert an 8-bit IplImage to a 32-bits IplImage. Using documentation from all over the web I've tried the following things:

// 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.

As you see I don't really know what I'm doing. I'd love to find out, but I'd love it more if I could get this done correctly. Thanks for any help I get!


回答1:


Perhaps this link can help you?

Edit In response to the second edit of the OP and the comment

Have you tried

float value = 0.5

instead of

float value = 0x0000001;

I thought the range for a float color value goes from 0.0 to 1.0, where 1.0 is white.




回答2:


The function you are looking for is cvConvertScale(). It automagically does any type conversion for you. You just have to specify that you want to scale by a factor of 1/255 (which maps the range [0...255] to [0...1]).

Example:

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

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

Note the dot in 1/255. - to force a double division. Without it you get a scale of 0.




回答3:


Floating point colors go from 0.0 to 1.0, and uchars go from 0 to 255. The following code fixes it:

// 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;

Many, many thanks to Stefan Schmidt for helping me fix this!




回答4:


If you do not put the dot (.), some compilers will understand is as an int division, giving you a int result (zero in this case).




回答5:


You can create an IplImage wrapper using boost::shared_ptr and template-metaprogramming. I have done that, and I get automatic garbage collection, together with automatic image conversions from one depth to another, or from one-channel to multi-channel images.

I have called the API blImageAPI and it can be found here: http://www.barbato.us/2010/10/14/image-data-structure-based-shared_ptr-iplimage/

It is very fast, and make code very readable, (good for maintaining algorithms)

It is also can be used instead of IplImage in opencv algorithms without changing anything.

Good luck and have fun writing algorithms!!!




回答6:


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);

//For Confirmation Check the pixel values (between 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");


来源:https://stackoverflow.com/questions/394488/how-to-convert-an-8-bit-opencv-iplimage-to-a-32-bit-iplimage

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!