opencv iplimage bpp bits-per-pixel

¿Cómo convertir una IplImage*OpenCV de 8 bits a una IplImage*de 32 bits?



bpp bits-per-pixel (6)

Necesito convertir una IplImage de 8 bits en una imagen Ipl de 32 bits. Usando documentación de toda la web, probé las siguientes cosas:

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

Como ves, realmente no sé lo que estoy haciendo. Me encantaría saberlo, pero me gustaría más si pudiera hacer esto correctamente. Gracias por cualquier ayuda que recibo!


Los colores de punto flotante van de 0.0 a 1.0, y las uchar van de 0 a 255. El siguiente código lo corrige:

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

¡Muchas, muchas gracias a Stefan Schmidt por ayudarme a solucionar esto!


Tal vez este enlace puede ayudarte?

Editar En respuesta a la segunda edición de OP y el comentario

Has probado

float value = 0.5

en lugar de

float value = 0x0000001;

Pensé que el rango para un valor de color flotante va de 0.0 a 1.0, donde 1.0 es blanco.


Si no coloca el punto (.), Algunos compiladores lo entenderán como una división int, que le da un resultado int (cero en este caso).


Puede crear un contenedor IplImage usando boost :: shared_ptr y template-metaprogramming. Lo he hecho y obtengo recolección de basura automática, junto con conversiones de imagen automáticas de una profundidad a otra, o de imágenes de un canal a multicanal.

He llamado a API blImageAPI y se puede encontrar aquí: http://www.barbato.us/2010/10/14/image-data-structure-based-shared_ptr-iplimage/

Es muy rápido y hace que el código sea muy legible (bueno para mantener los algoritmos)

También se puede usar en lugar de IplImage en algoritmos opencv sin cambiar nada.

¡Buena suerte y diviértete escribiendo algoritmos!


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

// Para la confirmación Compruebe los valores de píxeles (entre 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");


La función que está buscando es cvConvertScale (). Automáticamente hace cualquier tipo de conversión para usted. Solo tiene que especificar que desea escalar por un factor de 1/255 (que mapea el rango [0 ... 255] a [0 ... 1]).

Ejemplo:

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

Tenga en cuenta el punto en 1/255. - forzar una doble división. Sin él, obtienes una escala de 0.