Como converter um OpenCV IplImage a um SDL_Surface?
Pergunta
Eu estou tentando escrever um programa que leva um SDL_Surface
, o converte em um IplImage
, usa o cvBlobsLib para encontrar blobs, pinta as bolhas como manchas traseira sobre a imagem, em seguida, converte a volta IplImage
saída para um SDL_Surface
.
Eu estou quase pronto: somente converter a volta IplImage
a um SDL_Surface
ainda não foi feito. Este IplImage tem 3 canais de imagem e é de 8 bits por pixel. Acho que tenho duas chamadas posso 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);
Atualmente estou tentando com SDL_CreateRGBsurfaceFrom
. Eu não tenho idéia, no entanto, que os valores corretos de campo, Rmask, Gmask e BMASK são. (Amask é 0, porque não existe nenhum canal alfa.)
Alguém poderia me ajudar, explicando como fazer isso?
Obrigado!
Editar : Por exemplo, este é o código que eu tentei 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;
}
(Documentação SDL escreve: "O passo é a dimensão da linha de varredura da superfície, em bytes, ou seja, widthInPixels * bytesPerPixel.") Este saídas "profundidade 8, nChannels 3, pitch 1920" e exibe uma imagem completamente vermelho. I pensar uma solução seria converter a minha imagem 8-bits para 24 bits (1 byte por canal), mas eu não sei como fazer isso. Alguma idéia?
Solução
Ok, eu tenho que trabalhar!
Eu acho que eu estava confuso com o fato de que uma profundidade OpenCV de 8 meios um pixel tem 8 bits por canal, assim, em uma imagem 3-channel, um pixel tem 24 bits . Então, ao converter isso para o SDL seja, de profundidade, temos pedaços 8 * 3 = 24
.
A imagem era de 24 bits depois de tudo, que SDL suportes. Então converter a imagem para SDL é tão simples 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;
Desculpe pela confusão, eu espero que isso ajude alguém procurando a mesma resposta.
Outros links de interesse:
http://www.libsdl.org/cgi/docwiki.cgi/Pixel_Access
Ea sub-rotina completa em:
http://paster.dazjorz.com/?p=3714
Outras dicas
Primeiro de tudo: Thanks !!
Segundo: Ele funciona perfeitamente com 3 imagens canal, mas eu quero mostrar um Single-Canal-IplImage
então lá vamos nós:
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;
}