Question

Je dois convertir un 8 bits IplImage à un 32 bits IplImage. En utilisant la documentation de partout dans le web que j'ai essayé les choses suivantes:

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

Comme vous le voyez, je ne sais pas vraiment ce que je fais. J'aimerais savoir, mais j'aimerais plus si je pouvais obtenir ce fait correctement. Merci pour toute aide que je reçois!

Était-ce utile?

La solution

Peut-être peut vous aider?

Modifier En réponse à la deuxième édition de l'OP et le commentaire

Avez-vous essayé

float value = 0.5

au lieu de

float value = 0x0000001;

Je pensais que la plage pour une valeur de couleur de flotteur va de 0,0 à 1,0, où 1,0 est blanc.

Autres conseils

La fonction que vous recherchez est cvConvertScale (). Il fait automagiquement une conversion de type pour vous. Il suffit de spécifier que vous voulez à l'échelle par un facteur de 1/255 (qui associe la gamme [0 ... 255] à [0 ... 1]).

Exemple:

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

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

Notez le point dans 1/255. - pour forcer une double division. Sans elle, vous obtenez une échelle de 0.

couleurs à virgule flottante vont de 0,0 à 1,0, et uchars vont de 0 à 255. Le code suivant le fixe:

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

Un grand merci à Stefan Schmidt pour me aider à résoudre ce problème!

Si vous ne mettez pas le point (.), Certains compilateurs comprendront est comme une division int, vous donnant un résultat int (zéro dans ce cas).

Vous pouvez créer une enveloppe IplImage en utilisant boost :: shared_ptr et modèle-métaprogrammation. Je l'ai fait, et je reçois la collecte des ordures automatique, ainsi que des conversions d'image automatique d'une profondeur à l'autre, ou d'un canal aux images à plusieurs canaux.

Je l'ai appelé le blImageAPI API et il est disponible ici: http://www.barbato.us/ 2010/10/14 / données d'image à base de structure-shared_ptr-iplimage /

Il est très rapide, et rendre le code très lisible, (bon pour le maintien des algorithmes)

Il est peut également être utilisé au lieu de IplImage dans les algorithmes de OpenCV sans changer quoi que ce soit.

Bonne chance et des algorithmes d'écriture fun !!!

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

// Pour confirmation Vérifiez les valeurs de pixels (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");
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top