Как преобразовать OpenCV IplImage в SDL_Surface?
Вопрос
Я пытаюсь написать программу, которая принимает 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 написано: «Шаг — это размер строки сканирования поверхности в байтах, т.е.Ширинпиксель*bytesperpixel. ") Это выводит" глубина 8, NChannels 3, Pitch 1920 "и отображает совершенно красное изображение.я думать решением было бы преобразовать мое 8-битное изображение в 24-битное (1 байт на канал), но я не знаю, как это сделать.Есть идеи?
Решение
Хорошо, у меня все заработало!
Думаю, меня смутил тот факт, что глубина 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
Другие советы
Прежде всего:Спасибо!!
Второй:Он отлично работает с трехканальными изображениями, но я хочу отобразить одноканальное изображение 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;
}