Cómo convertir un IplImage OpenCV a un SDL_Surface?
Pregunta
Estoy tratando de escribir un programa que toma un SDL_Surface
, lo convierte en un IplImage
, utiliza el cvBlobsLib para encontrar manchas, pinta las manchas como manchas de nuevo sobre la imagen, a continuación, convierte la IplImage
de salida de nuevo a un SDL_Surface
.
Ya casi termino: solamente la conversión de la IplImage
de nuevo a un SDL_Surface
no se ha hecho todavía. Este IplImage tiene 3 canales de imagen y es de 8 bits por píxel. Creo que tengo dos llamadas que puedo usar:
SDL_Surface *SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
SDL_Surface *SDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
Actualmente estoy tratando con SDL_CreateRGBsurfaceFrom
. No tengo ni idea, sin embargo, lo que los valores correctos de tono, Rmask, GMask y BMASK son. (AMASK es 0, porque no hay un canal alfa.)
Podría alguien ayudarme explicando cómo hacer esto?
Gracias!
Editar : Por ejemplo, este es el código Probé a usar:
SDL_Surface *ipl_to_surface (IplImage *opencvimg)
{
int pitch = opencvimg->nChannels*opencvimg->width;
printf("Depth %d, nChannels %d, pitch %d\n", opencvimg->depth,
opencvimg->nChannels, pitch);
SDL_Surface *surface = SDL_CreateRGBSurfaceFrom((void*)opencvimg->imageData,
opencvimg->width,
opencvimg->height,
opencvimg->depth,
pitch,
0x0000ff, 0x00ff00, 0xff0000, 0
);
return surface;
}
(Documentación SDL escribe "Pitch es el tamaño de la línea de exploración de la superficie, en bytes, es decir widthInPixels * bytesPerPixel"). Este salidas "Profundidad 8, nChannels 3, campo de 1920" y muestra una imagen completamente rojo. I pensar una solución sería la de convertir mi imagen de 8 bits a 24 bits (1 byte por canal), pero no sé cómo hacerlo. ¿Alguna idea?
Solución
Ok, lo tengo trabajo!
Creo que estaba confundido por el hecho de que una profundidad OpenCV de 8 medios un píxel tiene 8 bits por canal, por lo que en una imagen de 3 canales, un píxel tiene 24 bits . Así que cuando la conversión de dicha al sentido de la profundidad de SDL, obtenemos bits de 8 * 3 = 24
.
La imagen era 24 bits después de todo, que apoya SDL. Así que convertir la imagen a SDL es tan simple como:
SDL_Surface *surface = SDL_CreateRGBSurfaceFrom((void*)opencvimg->imageData,
opencvimg->width,
opencvimg->height,
opencvimg->depth*opencvimg->nChannels,
opencvimg->widthStep,
0xff0000, 0x00ff00, 0x0000ff, 0
);
return surface;
Lo siento por la confusión, espero que esto ayude a nadie en busca de la misma respuesta.
Otros enlaces de interés:
http://www.libsdl.org/cgi/docwiki.cgi/Pixel_Access
Y la subrutina completa en:
http://paster.dazjorz.com/?p=3714
Otros consejos
En primer lugar: Gracias !!
En segundo lugar: Funciona perfectamente con 3 imágenes de canal pero quiero mostrar un solo canal-IplImage
por lo que vamos:
SDL_Surface *single_channel_ipl_to_surface (IplImage *opencvimg)
{
SDL_Surface *surface = SDL_CreateRGBSurfaceFrom((void*)opencvimg->imageData,
opencvimg->width,
opencvimg->height,
opencvimg->depth*opencvimg->nChannels,
opencvimg->widthStep,
0xffffff, 0xffffff, 0xffffff,0);
return surface;
}