如何将 OpenCV IplImage 转换为 SDL_Surface?

发布于 2024-07-11 23:15:34 字数 1575 浏览 12 评论 0原文

我正在尝试编写一个程序,它采用 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,因为没有 alpha 通道。)

有人可以帮我解释一下如何做到这一点吗?

谢谢!

编辑:例如,这是我尝试使用的代码:

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文档写道“Pitch是表面扫描线的大小,以字节为单位,即widthInPixels*bytesPerPixel。”) 输出“深度 8,n通道 3,间距 1920”并显示全红色图像。 我认为解决方案是将 8 位图像转换为 24 位(每个通道 1 个字节),但我不知道该怎么做。 有任何想法吗?

I'm trying to write a program which takes an SDL_Surface, converts it to an IplImage, uses the cvBlobsLib to find blobs, paints the blobs as spots back over the image, then converts the output IplImage back to an SDL_Surface.

I'm almost done: only converting the IplImage back to an SDL_Surface hasn't been done yet. This IplImage has 3 image channels and is 8 bits per pixel. I think I have two calls I can use:

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

I'm currently trying with SDL_CreateRGBsurfaceFrom. I have no idea, however, what the correct values of pitch, Rmask, Gmask and Bmask are. (Amask is 0, because there is no alpha channel.)

Could anybody help me out by explaining how to do this?

Thanks!

Edit: For example, this is code I tried to use:

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 Documentation writes "Pitch is the size of the scanline of the surface, in bytes, i.e. widthInPixels*bytesPerPixel.")
This outputs "Depth 8, nChannels 3, pitch 1920" and displays a completely red image.
I think a solution would be to convert my 8-bits image to 24-bits (1 byte per channel), but I don't know how to do that. Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

顾冷 2024-07-18 23:15:34

好的,我成功了!

我认为我对以下事实感到困惑: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

Ok, I got it working!

I think I was confused by the fact that an OpenCV depth of 8 means a pixel has 8 bits per channel, so in a 3-channel image, a pixel has 24 bits. So when converting that to the SDL meaning of depth, we get 8 * 3 = 24 bits.

The image was 24 bits after all, which SDL supports. So converting the image to SDL is as simple as:

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

Sorry for the confusion, I hope this helps anybody searching for the same answer.

Other links of interest:
http://www.libsdl.org/cgi/docwiki.cgi/Pixel_Access
And the complete subroutine at:
http://paster.dazjorz.com/?p=3714

白馒头 2024-07-18 23:15:34

首先:谢谢!!

第二:它与 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;
}

First of all: Thanks!!

Second: It works perfectly with 3 Channel images but I want to display a Single-Channel-IplImage

so there we go:

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文