كيفية تحويل 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 "الملعب هو حجم SCANLINE من السطح، في البايتات، أي WideThinpixels * bytesperpixel.") هذا المخرجات "العمق 8، Nchannels 3، الملعب 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.
نصائح أخرى
بادئ ذي بدء: شكرا !!
ثانيا: إنه يعمل بشكل مثالي مع 3 صور قناة ولكن أريد عرض 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;
}