在opencv中将透明图像覆盖在相机的输出上

发布于 2024-12-13 23:11:16 字数 1539 浏览 0 评论 0原文

我有透明图像[如下所示],我试图用 aishack 覆盖它.in cvOverlayImage() 函数将其覆盖在相机源上

cvOverlayImage()

    void cvOverlayImage(IplImage* src, IplImage* overlay, CvPoint location, CvScalar S, CvScalar D)
    {
     int x,y,i;

      for(x=0;x < overlay->width -10;x++)
        {
            if(x+location.x>=src->width) continue;
            for(y=0;y < overlay->height -10;y++)
            {
                if(y+location.y>=src->height) continue;
                CvScalar source = cvGet2D(src, y+location.y, x+location.x);
                CvScalar over = cvGet2D(overlay, y, x);
                CvScalar merged;
                for(i=0;i<4;i++)
                merged.val[i] = (S.val[i]*source.val[i]+D.val[i]*over.val[i]);
                cvSet2D(src, y+location.y, x+location.x, merged);
            }
        }
    }

调用 cvOverlayImage()

cvOverlayImage(image_n, neg_img, cvPoint(0, 0), cvScalar(1.0,1.0,1.0,1.0), cvScalar(0.1,0.1,0.1,0.1));

输入cvOverlayImage()

  1. 相机捕获

相机捕获

  1. 负像

负像

cvOverlayImage() 的输出

Output

正如你所看到的,我没有得到我需要的东西。请帮助我。

I have transparent images [shown below] and I am trying to overlay it with aishack.in cvOverlayImage() function to overlay it on camera source

cvOverlayImage()

    void cvOverlayImage(IplImage* src, IplImage* overlay, CvPoint location, CvScalar S, CvScalar D)
    {
     int x,y,i;

      for(x=0;x < overlay->width -10;x++)
        {
            if(x+location.x>=src->width) continue;
            for(y=0;y < overlay->height -10;y++)
            {
                if(y+location.y>=src->height) continue;
                CvScalar source = cvGet2D(src, y+location.y, x+location.x);
                CvScalar over = cvGet2D(overlay, y, x);
                CvScalar merged;
                for(i=0;i<4;i++)
                merged.val[i] = (S.val[i]*source.val[i]+D.val[i]*over.val[i]);
                cvSet2D(src, y+location.y, x+location.x, merged);
            }
        }
    }

calling cvOverlayImage()

cvOverlayImage(image_n, neg_img, cvPoint(0, 0), cvScalar(1.0,1.0,1.0,1.0), cvScalar(0.1,0.1,0.1,0.1));

Inputs to cvOverlayImage()

  1. Camera Capture

Camera Capture

  1. Negative Image

Negative Image

Output from cvOverlayImage()

Output

As you can see I am not getting what I need.Please help me.

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

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

发布评论

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

评论(3

南汐寒笙箫 2024-12-20 23:11:17

这没有经过测试,但不应该 S[i]+D[i] = 1 来保持总强度吗?

This isn't tested, but shouldn't S[i]+D[i] = 1 to preserve the total intensity ?

渔村楼浪 2024-12-20 23:11:17

我认为您想要实现的不是加法而是乘法:

int multiplicator = over.val[i] / 255 // 0 for black, 1 for white
merged.val[i] = source.val[i] * multiplicator;

这样,像素值将是白色覆盖像素的原始值,黑色覆盖像素的原始值。

I think what you want to achieve is not addition but multiplication:

int multiplicator = over.val[i] / 255 // 0 for black, 1 for white
merged.val[i] = source.val[i] * multiplicator;

This way the pixel value will be the original value for a white overlay pixel and black for a black overlay pixel.

浮光之海 2024-12-20 23:11:16

我使用的一种解决方案是简单地检测白色存在的位置,在这些情况下只需使用源图片中的像素。否则使用覆盖图片的像素。对于类似的情况,对我来说效果很好。另外,如果您加载的图片具有 Alpha 通道并且可以用作遮罩,那就更好了。

void cvOverlayImage(IplImage* src, IplImage* overlay, CvPoint location, 
CvScalar S, CvScalar D)
{
 int x,y,i;

  for(x=0;x < overlay->width;x++)
    {
        if(x+location.x>=src->width) continue;
        for(y=0;y < overlay->height;y++)
        {
            if(y+location.y>=src->height) continue;
            CvScalar source = cvGet2D(src, y+location.y, x+location.x);
            CvScalar over = cvGet2D(overlay, y, x);
            CvScalar merged;
            if(over.val[0] == 255 && over.val[1] == 255 && over.val[2] == 255 && over.val[3] == 255)
            {
                // White pixel so don't overlay
                for(i=0;i<4;i++)
                    merged.val[i] = (source.val[i]);
            }
            else
            {
                for(i=0;i<4;i++)
                    merged.val[i] = (over.val[i]);

            }

            cvSet2D(src, y+location.y, x+location.x, merged);
        }
    }
}

One solution I used is to simply detect where the white is present and in those cases simply use the pixel from the source picture. Otherwise use the overlay picture's pixel. Worked well for me for a similar situation. Also, if the picture you load has the alpha channel and can be used as a mask, that's even better.

void cvOverlayImage(IplImage* src, IplImage* overlay, CvPoint location, 
CvScalar S, CvScalar D)
{
 int x,y,i;

  for(x=0;x < overlay->width;x++)
    {
        if(x+location.x>=src->width) continue;
        for(y=0;y < overlay->height;y++)
        {
            if(y+location.y>=src->height) continue;
            CvScalar source = cvGet2D(src, y+location.y, x+location.x);
            CvScalar over = cvGet2D(overlay, y, x);
            CvScalar merged;
            if(over.val[0] == 255 && over.val[1] == 255 && over.val[2] == 255 && over.val[3] == 255)
            {
                // White pixel so don't overlay
                for(i=0;i<4;i++)
                    merged.val[i] = (source.val[i]);
            }
            else
            {
                for(i=0;i<4;i++)
                    merged.val[i] = (over.val[i]);

            }

            cvSet2D(src, y+location.y, x+location.x, merged);
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文