【问题标题】:Place an image on an image在图像上放置图像
【发布时间】:2010-12-06 23:59:51
【问题描述】:

我想将图像放置在我确定的坐标处捕获的视频帧上。

我之前问过,有人告诉我使用cvCopycvSetImageROI,但我不想裁剪那些坐标,我想添加另一个图像。 也许这是正确的方式,但我不明白(如果正确,请解释)。

【问题讨论】:

    标签: c++ image-processing opencv


    【解决方案1】:

    我不久前使用 SetRoi 做了这个,它是这样的。我有两张图片,一张是名为 thumb_frame 的缩略图,它是我将包含在大图片 show_frame 中的小图片

    //I set the ROI to the same size as the thumb_frame
    cvSetImageROI(show_frame.image, cvRect(thumbnail_x_pos,
                        thumbnail_y_pos, thumb_frame->width, thumb_frame->height));
    
    //I add the image to the designated ROI
    cvAddWeighted(thumb_frame, alpha, show_frame, beta, 0, show_frame);
    

    就是这样。

    【讨论】:

    • 为什么选择 cvAddWeighted() ?我认为 cvCopy() 是必需的。
    【解决方案2】:
    void cvOverlayImage(IplImage* src, IplImage* overlay, CvPoint location, CvScalar S, CvScalar D)
    {
     int x,y,i;
    
      for(x=0;x < overlay->width -10;x++)     
    //replace '-10' by whatever x position you want your overlay image to begin. 
    //say '-varX'
        {
            if(x+location.x>=src->width) continue;
            for(y=0;y < overlay->height -10;y++)  
    //replace '-10' by whatever y position you want your overlay image to begin.
    //say '-varY'
            {
                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(largerimage, overlayimage, cvPoint(10, 10), cvScalar(0.5,0.5,0.5,0.5), cvScalar(0.5,0.5,0.5,0.5)); 
    //The cvPoint(10,10) can be the cvPoint(varX,varY) depending on how you write the function 
    //and how you want to use it. 
    //You cannot choose values less than 'varX' and 'varY' in this case
    //else you would see a runtime error.
    

    【讨论】:

    • 谢谢乔治。我真的不知道如何使用这里的编辑工具。我可以编写复杂的代码,但不能做这些简单的事情:)。你用什么来突出我的代码。我试过
    • 嘿,如果覆盖图像的宽度和高度非常大,它不会正确裁剪图像!您能否建议一些方法来重新调整覆盖图像并适合固定区域。
    • @PavanK 如果重新缩放整个图像,使用 cvResize() 怎么样? ,如果您想使用图像的一部分并调整该部分的大小,则必须设置 ROI、复制、缩放、重置 ROI。看看这里的一个例子nashruddin.com/OpenCV_Region_of_Interest_(ROI) [复制和粘贴链接 - 包括括号,否则将不起作用]
    • @modalgeek 是的,我尝试过这种方法,它只适用于矩形。有什么方法可以将它放入具有 4 个顶点的多边形中?我尝试使用 warp_matrix 但效果不佳。我的问题在这里stackoverflow.com/questions/9997544/…
    • @PavanK 你不能像下面的例子那样应用掩码吗? nashruddin.com/OpenCV_Circular_ROI
    【解决方案3】:

    您必须逐个像素地从源复制到目标。下面的代码正是这样做的,偏移坐标xy。我实际上并没有尝试过,但我相当肯定它应该或多或少地像你期望的那样工作。

    只要确保目标图像至少是源图像的大小加上偏移量!

    void drawImage(IplImage* target, IplImage* source, int x, int y) {
        for (int ix=0; x<source->width; x++) {
            for (int iy=0; y<source->height; y++) {
                int r = cvGet2D(source, iy, ix).val[2];
                int g = cvGet2D(source, iy, ix).val[1];
                int b = cvGet2D(source, iy, ix).val[0];
                CvScalar bgr = cvScalar(b, g, r);
                cvSet2D(target, iy+y, ix+x, bgr);
            }
        }
    }
    

    【讨论】:

    • 谢谢,但我想将所有源合并到目标的 x、y 像素,我认为我必须在代码中添加 2 个 for 循环,代码中的 for 循环将获得 r、g、源的 b 值和我将添加的其他 2 个值将更改目标 rgb 是否正确
    • 上面的代码会循环遍历源图像的所有像素点,并将它们一个一个地复制到目标图像上的一个偏移位置。除非您打算将多个 IplImages 复制到目标上,否则不需要任何额外的循环。
    • 好的,我理解你的代码,谢谢我已经有一个多图像循环我想你不明白我我想做与你的代码完全相反的事情我想做的是替换我的源图像的一部分与另一张图片
    • 只需交换参数中的IplImages 即可完成此操作。本质上,您需要做的是将捕获的视频作为target,您要覆盖的图像作为source,并指定您希望将图像放置在视频上的xy 偏移量。由于目标视频是通过指针传递的,因此您可以在调用drawImage()之后继续处理捕获的视频帧。
    • paul 我只是在你最后一条评论之前使用你的代码我在代码中相互替换目标和源但是我想要放置的图像是放在另一个坐标上并且我想放宽在我的眼睛检测程序中,我在眼睛上放了一个黑色图像,但如果你愿意,它会出现在额头上而不是眼睛,我可以给你发送代码
    【解决方案4】:

    不幸的是,“Paul Lammertsma”代码在这里混淆了索引,你有固定的代码:

    void drawImage(IplImage* target, IplImage* source, int x, int y) {
    
        for (int ix=0; ix<source->width; ix++) {
            for (int iy=0; iy<source->height; iy++) {
                int r = cvGet2D(source, iy, ix).val[2];
                int g = cvGet2D(source, iy, ix).val[1];
                int b = cvGet2D(source, iy, ix).val[0];
                CvScalar bgr = cvScalar(b, g, r);
                cvSet2D(target, iy+y, ix+x, bgr);
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-27
      • 2014-09-24
      • 2018-02-04
      相关资源
      最近更新 更多