Mappatura dei colors Opencv con accesso diretto ai pixel

Ho un’immagine in scala di grigi che voglio visualizzare a colors mappando i valori della scala di grigi con una tavolozza di colors (come colormap in Matlab).

Sono riuscito a farlo usando la funzione cvSet2D di OpenCV, ma vorrei accedere direttamente ai pixel per motivi di prestazioni.

Ma quando lo faccio l’immagine ha strani colors. Ho provato a impostare i colors in ordini diversi (RGB, BGR, …) ma non riesco a girarci attorno.

C’è il mio codice:

IplImage* temp = cvCreateImage( cvSize(img->width/scale,img->height/scale), IPL_DEPTH_8U, 3 ); for (int y=0; yheight; y++) { uchar* ptr1 = (uchar*) ( temp->imageData + y * temp->widthStep ); uchar* ptr2 = (uchar*) ( img->imageData + y * img->widthStep ); for (int x=0; xwidth; x++) { CvScalar v1; int intensity = (int)ptr2[x]; int b=0, g=0, r=0; r = colormap[intensity][0]; g = colormap[intensity][1]; b = colormap[intensity][2]; if (true) { ptr1[3*x] = b; ptr1[3*x+1] = g; ptr1[3*x+2] = r; } else { v1.val[0] = r; v1.val[1] = g; v1.val[2] = b; cvSet2D(temp, y, x, v1); } } } 

Cambia if (true) in if (false) per l’accesso ai pixel differenti.

Il risultato corretto è con cvSet2D:

inserire qui il codice

Il risultato sbagliato con l’accesso diretto alla memoria:

inserisci la descrizione dell'immagine qui

grazie per l’aiuto

Ho fatto qualcosa di simile per colorare mappe di profondità da Microsoft Kinect Sensor. Il codice che ho usato per convertire una mappa di profondità in scala di grigio in un’immagine a colors funzionerà per quello che stai cercando di fare. Potresti aver bisogno di leggere modifiche poiché nel mio caso i valori di profondità erano compresi tra 500 e 2000 e dovevo ridimensionarli.

La funzione per colorare un’immagine in scala di grigio in un’immagine a colors è:

 void colorszeDepth( const Mat& gray, Mat& rgb) { double maxDisp= 255; float S=1.f; float V=1.f ; rgb.create( gray.size(), CV_8UC3 ); rgb = Scalar::all(0); if( maxDisp < 1 ) return; for( int y = 0; y < gray.rows; y++ ) { for( int x = 0; x < gray.cols; x++ ) { uchar d = gray.at(y,x); unsigned int H = 255 - ((uchar)maxDisp - d) * 280/ (uchar)maxDisp; unsigned int hi = (H/60) % 6; float f = H/60.f - H/60; float p = V * (1 - S); float q = V * (1 - f * S); float t = V * (1 - (1 - f) * S); Point3f res; if( hi == 0 ) //R = V, G = t, B = p res = Point3f( p, t, V ); if( hi == 1 ) // R = q, G = V, B = p res = Point3f( p, V, q ); if( hi == 2 ) // R = p, G = V, B = t res = Point3f( t, V, p ); if( hi == 3 ) // R = p, G = q, B = V res = Point3f( V, q, p ); if( hi == 4 ) // R = t, G = p, B = V res = Point3f( V, p, t ); if( hi == 5 ) // R = V, G = p, B = q res = Point3f( q, p, V ); uchar b = (uchar)(std::max(0.f, std::min (res.x, 1.f)) * 255.f); uchar g = (uchar)(std::max(0.f, std::min (res.y, 1.f)) * 255.f); uchar r = (uchar)(std::max(0.f, std::min (res.z, 1.f)) * 255.f); rgb.at >(y,x) = Point3_(b, g, r); } } } 

Per un’immagine di input che assomiglia a questo:

inserisci la descrizione dell'immagine qui

L’output di questo codice è:

inserisci la descrizione dell'immagine qui

Sto postando questo per chiudere la domanda come chiesto nei commenti della mia domanda.

La risposta è stata:

Ho scoperto il mio errore … In effetti è RGB ma non era questo il problema, avevo valori di colore a 256 anziché a 255 … Davvero dispiaciuto … Suppongo che la domanda mi abbia aiutato a trovare la risposta

Grazie