Pregunta

Necesito convertir un 8-bit IplImage a un 32-bits IplImage. Utilizando la documentación de toda la web He intentado lo siguiente:

// 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 se ve que no se sabe muy bien lo que estoy haciendo. Me gustaría saber, pero me gustaría más si pudiera hacer esto correctamente. Gracias por cualquier ayuda que recibo!

¿Fue útil?

Solución

Tal vez esto puede ayudarle?

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

¿Ha tratado

float value = 0.5

en lugar de

float value = 0x0000001;

pensé que el intervalo para un valor de color flotador va de 0,0 a 1,0, en donde 1,0 es blanco.

Otros consejos

La función que busca es cvConvertScale (). Automágicamente hace ningún tipo de conversión para usted. Sólo hay que especificar que desea escalar por un factor de 1/255 (que se asigna 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. - para forzar una doble división. Sin ella se obtiene una escala de 0.

colores de punto flotante van de 0,0 a 1,0, y uchars van de 0 a 255. El siguiente código lo fija:

// 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 para ayudar a solucionar este!

Si usted no pone el punto (.), Algunos compiladores se entiende es como una división entre valores enteros, que le da resultado int (cero en este caso).

Puede crear una envoltura IplImage utilizando impulso :: shared_ptr y la plantilla-metaprogramming. Yo lo he hecho, y me sale recolección de basura automática, junto con las conversiones de imagen automáticas de una profundidad a otra, o de un canal a imágenes de varios canales.

he llamado el blImageAPI activos y de productos que se pueden encontrar aquí: http://www.barbato.us/ 2010/10 / 14 / imagen-data-estructura basada en shared_ptr-iplimage /

Es muy rápido, y hacer que el código muy legible, (bueno para el mantenimiento de los algoritmos)

Es también puede ser utilizado en lugar de IplImage en algoritmos OpenCV sin cambiar nada.

Buena suerte y algoritmos de escritura diversión !!!

* 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 el 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");
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top