我需要将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.
如你所见,我真的不知道自己在做什么。我很想知道,但如果我能正确完成这项工作,我会更加喜欢它。 谢谢你的帮助!
答案 0 :(得分:29)
您正在寻找的功能是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的分数。
答案 1 :(得分:6)
也许这个link可以帮到你?
编辑响应OP的第二次编辑和评论
你试过吗
float value = 0.5
而不是
float value = 0x0000001;
我认为浮色值的范围从0.0到1.0,其中1.0是白色。
答案 2 :(得分:2)
浮点颜色从0.0到1.0,uchars从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 帮助我解决这个问题!
答案 3 :(得分:1)
如果你没有放点(。),一些编译器会理解为int分区,给你一个int结果(在这种情况下为零)。
答案 4 :(得分:1)
您可以使用boost :: shared_ptr和template-metaprogramming创建IplImage包装器。我已经做到了,我得到了自动垃圾收集,以及从一个深度到另一个深度的自动图像转换,或从单通道到多通道图像的转换。
我已经调用了API blImageAPI,它可以在这里找到: http://www.barbato.us/2010/10/14/image-data-structure-based-shared_ptr-iplimage/
它非常快,并且使代码非常易读(适用于维护算法)
也可以在opencv算法中使用它代替IplImage而不改变任何东西。
祝你好运,并有乐趣写作算法!!!
答案 5 :(得分: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");