Как преобразовать OpenCV IplImage в SDL_Surface? - PullRequest
6 голосов
/ 26 декабря 2008

Я пытаюсь написать программу, которая принимает SDL_Surface, преобразует ее в IplImage, использует cvBlobsLib для поиска капель, рисует капли как пятна на изображении, а затем преобразует вывод IplImage вернуться к SDL_Surface.

Я почти закончил: только преобразование IplImage обратно в SDL_Surface еще не завершено. Этот IplImage имеет 3 канала изображения и составляет 8 бит на пиксель. Я думаю, что у меня есть два звонка, которые я могу использовать:

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

Я сейчас пытаюсь с SDL_CreateRGBsurfaceFrom. Однако я понятия не имею, каковы правильные значения высоты тона, Rmask, Gmask и Bmask. (Amask = 0, потому что нет альфа-канала.)

Может ли кто-нибудь помочь мне, объяснив, как это сделать?

Спасибо!

Редактировать : Например, это код, который я пытался использовать:

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

(Документация SDL пишет: «Шаг - это размер линии сканирования поверхности в байтах, т.е. widthInPixels * bytesPerPixel.») Это выводит «Depth 8, nChannels 3, pitch 1920» и отображает полностью красное изображение. Я думаю решение было бы преобразовать мое 8-битное изображение в 24-битное (1 байт на канал), но я не знаю, как это сделать. Есть идеи?

Ответы [ 2 ]

11 голосов
/ 28 декабря 2008

Хорошо, у меня все получилось!

Я думаю, что меня смутил тот факт, что глубина OpenCV 8 означает пиксель имеет 8 бит на канал, поэтому в 3-канальном изображении пиксель имеет 24 бита . Таким образом, при преобразовании значения SDL в значение глубины мы получаем 8 * 3 = 24 бит.

В конце концов, изображение было 24 бита, которое поддерживает SDL. Таким образом, преобразование изображения в SDL так же просто, как:

SDL_Surface *surface = SDL_CreateRGBSurfaceFrom((void*)opencvimg->imageData,
                opencvimg->width,
                opencvimg->height,
                opencvimg->depth*opencvimg->nChannels,
                opencvimg->widthStep,
                0xff0000, 0x00ff00, 0x0000ff, 0
                );
return surface;

Извините за путаницу, надеюсь, это поможет любому, кто ищет тот же ответ.

Другие интересные ссылки: http://www.libsdl.org/cgi/docwiki.cgi/Pixel_Access
И полная подпрограмма на: http://paster.dazjorz.com/?p=3714

3 голосов
/ 21 сентября 2009

Прежде всего: спасибо !!

Второй: он отлично работает с 3-канальными изображениями, но я хочу отобразить Single-Channel-IplImage

Итак, мы идем:

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;
}
...