2011-07-13 13 views
6

Tengo una imagen de escala de grises que quiero mostrar en color mapeando los valores de escala de grises con una paleta de colores (como el mapa de colores en Matlab).Asignación de color de Opencv con acceso directo de píxeles

Logré hacerlo utilizando la función OpenCV cvSet2D, pero me gustaría acceder a los píxeles directamente por motivos de rendimiento.

Pero cuando hago eso la imagen tiene colores extraños. Traté de configurar los colores en diferentes órdenes (RGB, BGR, ...) pero parece que no puedo evitarlo.

No es mi código:

IplImage* temp = cvCreateImage(cvSize(img->width/scale,img->height/scale), IPL_DEPTH_8U, 3); 
for (int y=0; y<temp->height; y++) 
{ 
    uchar* ptr1 = (uchar*) (temp->imageData + y * temp->widthStep); 
    uchar* ptr2 = (uchar*) (img->imageData + y * img->widthStep); 

    for (int x=0; x<temp->width; 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); 
     } 
    } 
} 

Cambiar el caso de (verdadero) si al (falso) para un acceso diferente de píxeles.

El resultado correcto es con cvSet2D:

enter code here

El resultado malo con el acceso directo a memoria:

enter image description here

Gracias por su ayuda

+0

No se puede ver ningún error en este momento. El orden correcto de bytes debe ser BGR dentro de 'imageData'. ¿Cómo cambia la imagen si cambia el orden de bytes? Debería cambiar, de lo contrario estás haciendo algo mal. Intente hacer un solo color (deje otros canales en 0/negro). Y mira si encajan. La alineación parece ser correcta, pero estoy un poco confundido sobre el duro contraste alrededor de las esquinas. – Mario

+2

Descubrí mi error ... De hecho, es RGB, pero ese no era el problema, tenía valores de color en 256 en lugar de 255 ... Realmente lo siento ... Creo que hacer la pregunta me ayudó a encontrar la respuesta. – david

+0

Ahh ... está bien. Eso explica el fuerte contraste (debido a los desbordamientos y tal).:) – Mario

Respuesta

0

Estoy publicando esto para cerrar la pregunta como se me pidió en los comentarios de mi pregunta.

La respuesta fue:

descubrí mi error ... De hecho, es RGB pero que no era el problema, que tenía valores de color a 256 en lugar de 255 ... Realmente lo siento ... Supongo que hacer la pregunta me ayudó a encontrar la respuesta

Gracias

4

que he hecho algo similar para colorear mapas de profundidad de Microsoft Kinect Sensor. El código que utilicé para convertir un mapa de profundidad en escala de grises en una imagen en color funcionará para lo que estás tratando de hacer. Es posible que requiera pequeñas modificaciones ya que en mi caso los valores de profundidad estaban en el rango de 500 a 2000, y tuve que reescalarlos.

La función para colorear una imagen en escala de grises de imágenes en color en es:

void colorizeDepth(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<uchar>(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<Point3_<uchar> >(y,x) = Point3_<uchar>(b, g, r);  

     } 
     } 
} 

Para una imagen de entrada que se parece a esto:

enter image description here

salida de este código es:

enter image description here

Cuestiones relacionadas