在图片上放置另一张图片

7
我希望在我确定的坐标上将图像放置在捕获的视频帧上。
我之前询问过,被告知使用cvCopycvSetImageROI,但我不想在这些坐标上裁剪,而是要添加另一张图片。也许这是正确的方法,但我没明白(如果是正确的,请解释一下)。
4个回答

7

我之前用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);

这就是全部了。

1
为什么要使用cvAddWeighted()?我认为需要的是cvCopy()。 - Gaurav Kalra

6
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.

谢谢George。我真的不知道如何使用这里的编辑工具。我可以编写复杂的代码,但不能做这些简单的事情:)。你用什么来突出显示我的代码?我尝试过<pre>和<code>。 - enthusiasticgeek
嘿,使用这个解决方案,如果覆盖图像具有非常大的宽度和高度,则无法正确裁剪图像!您能否建议一些方法,其中覆盖图像被重新缩放并适合固定区域。 - Pavan K
@PavanK 如果要缩放整个图像,可以考虑使用cvResize()。如果您想使用图像的一部分并调整该部分的大小,则需要设置ROI、复制、缩放、重置ROI。在这里查看一个示例http://nashruddin.com/OpenCV_Region_of_Interest_(ROI) [复制并粘贴链接-包括括号,否则无法工作]。 - enthusiasticgeek
@enthusiasticgeek 是的,我尝试过这种方法,只适用于矩形。有没有办法将其放入带有4个顶点的多边形中?我尝试使用warp_matrix,但效果不太好。我的问题在这里 http://stackoverflow.com/questions/9997544/overlay-smaller-image-in-a-larger-image-in-opencv/10016356 - Pavan K
@PavanK 你能不能像下面的例子一样应用一个掩码?http://nashruddin.com/OpenCV_Circular_ROI - enthusiasticgeek
更新的链接:https://dev59.com/i2PVa4cB1Zd3GeqP-fBj - enthusiasticgeek

0

你需要逐像素地从源图像复制到目标图像。下面的代码正是这样做的,使用坐标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像素中。 我认为我必须在你的代码中添加两个for循环。 你的代码中的for循环将获取源的r、g、b值,而我添加的另外两个for循环将更改目标的rgb。 这正确吗? - eomer
以上代码将循环遍历源图像的所有像素,并将它们逐一复制到目标图像的偏移位置。除非您打算将多个 IplImage 复制到目标上,否则不需要任何额外的循环。 - Paul Lammertsma
好的,我理解了你的代码,谢谢。 我已经有一个循环来处理多张图片了。 我觉得你没有理解我的意思。 我想要做的正好与你的代码相反。 我想要用另一张图片替换源图片的一部分。 - eomer
只需交换参数中的IplImage即可实现。本质上,您需要做的是将捕获的视频作为“目标”,要叠加的图像作为“源”,并指定您想要在视频上放置图像的“x”和“y”偏移量。由于目标视频是通过指针传递的,因此在调用drawImage()后,您可以继续处理捕获的视频帧。 - Paul Lammertsma
@eomer,我已经收到了你的电子邮件,但是如果我在这里回复的话,请不要介意。有一种更简单的逐像素复制图像的方法。之前的代码只适用于三通道图像。我已经相应地更新了我的代码。试一下看看是否有效,然后告诉我。 - Paul Lammertsma
显示剩余2条评论

0

很不幸,“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);
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接