Domanda

Devo convertire un IplImage a 8 bit in un IplImage a 32 bit.Utilizzando la documentazione da tutto il Web ho provato le seguenti cose:

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

Come vedi non so davvero cosa sto facendo.Mi piacerebbe scoprirlo, ma mi piacerebbe di più se potessi farlo correttamente.Grazie per tutto l'aiuto che riceverò!

È stato utile?

Soluzione

può aiutare?

Modifica In risposta alla seconda modifica del PO e il commento

Hai provato

float value = 0.5

anziché

float value = 0x0000001;

Ho pensato che il range per un valore di colore galleggiante va da 0.0 a 1.0, dove 1.0 è bianco.

Altri suggerimenti

La funzione che stai cercando è cvConvertScale().Esegue automaticamente qualsiasi conversione di tipo per te.Devi solo specificare che vuoi ridimensionare di un fattore di 1/255 (che mappa l'intervallo da [0...255] a [0...1]).

Esempio:

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

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

Nota il punto dentro 1/255. - forzare una doppia divisione.Senza di esso ottieni una scala pari a 0.

colori virgola mobile vanno da 0,0 a 1,0, e uchars vanno da 0 a 255. Il codice seguente lo fissa:

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

Molte, molte grazie a Stefan Schmidt per avermi aiutato a risolvere questo problema!

Se non inserisci il punto (.), alcuni compilatori lo interpreteranno come una divisione int, fornendo un risultato int (zero in questo caso).

È possibile creare un involucro IplImage utilizzando boost :: shared_ptr e il modello-metaprogrammazione. Ho fatto che, ed ottengo garbage collection automatica, insieme con conversioni automatiche immagine da una profondità ad un altro, o da un canale a immagini multicanale.

Ho chiamato il blImageAPI API e può essere trovato qui: http://www.barbato.us/ 2010/10 / 14 / immagine-dati-struttura-base-shared_ptr-iplimage /

E 'molto veloce, e rendere il codice molto leggibile, (buona per mantenere gli algoritmi)

È anche può essere usato al posto di IplImage in algoritmi OpenCV senza cambiare nulla.

Buona fortuna e buon divertimento !!! algoritmi di scrittura

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

// Per Conferma Controllare i valori dei pixel (tra 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");
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top