使用OpenCV可以实现画中画吗?

时间:2011-06-16 21:01:07

标签: opencv pip roi emgucv

我想在较大的图像上添加较小的图像(最终用于视频输入上的PiP)。我可以通过迭代大图像中的相关数据属性并添加小图像中的像素来实现。但是有更简单和更简洁的方式吗?我正在使用EMGU。

我的想法是在与小图像相同大小的大图像中定义ROI。将大图像设置为等于小图像,然后只需删除ROI。即伪代码:

Large.ROI = rectangle defined by small image;

Large = Small;

Large.ROI = Rectangle.Empty;

然而,这不起作用,大图像不会改变。任何建议都会非常感激。

大图:
Large Image

小图片:
Small Image

期望的结果:
Desired Result

4 个答案:

答案 0 :(得分:4)

如果您使用C ++ API,则以下代码段应该可以使用:

cv::Mat big;
cv::Mat small;

// Define roi area (it has small image dimensions). 
cv::Rect roi = cv::Rect(50,50, small.cols, small.rows);

// Take a sub-view of the large image
cv::Mat subView = big(roi); 

// Copy contents of the small image to large
small.copyTo(subView); 

注意不要超出大图像的尺寸。

答案 1 :(得分:1)

我不知道这是否会有所帮助,我还没有使用过emgu。然而,这就是我能用opencv在图像中做图像的方式。

drawIntoArea(Mat &src, Mat &dst, int x, int y, int width, int height)
{
    Mat scaledSrc;
    // Destination image for the converted src image.
    Mat convertedSrc(src.rows,src.cols,CV_8UC3, Scalar(0,0,255));

    // Convert the src image into the correct destination image type
    // Could also use MixChannels here.
    // Expand to support range of image source types.
    if (src.type() != dst.type())
    {
        cvtColor(src, convertedSrc, CV_GRAY2RGB);
    }else{
        src.copyTo(convertedSrc);
    }

    // Resize the converted source image to the desired target width.
    resize(convertedSrc, scaledSrc,Size(width,height),1,1,INTER_AREA);

    // create a region of interest in the destination image to copy the newly sized and converted source image into.
    Mat ROI = dst(Rect(x, y, scaledSrc.cols, scaledSrc.rows));
    scaledSrc.copyTo(ROI);
}

答案 2 :(得分:0)

我对EMGU有很多经验。据我所知,您采用的方法是在大图像中显示子图像数据的唯一直接方式。您可能需要刷新较大的图像,这会影响擦除传输的数据并将较小的图像复制回来。

虽然解决方案是可行的,但我认为该方法存在缺陷。所需的处理时间将影响较大的观看帧中的任何图像的显示速率。

改进的方法是添加另一个控件。实际上,您的视频输入窗口会在背景中显示较大的图像,而较小的控件则会显示较小的图像。实际上,您可以根据需要使用这些较小的控件。实际上,您将在两个不同的控件(例如图像框)中显示两个图像或视频输入。由于您有代码,所以您需要做的就是确保控件的显示顺序。

我假设您没有将输出编程到控制台窗口。如果您需要更多帮助,请随时提出。

至于评论,EMGU是用C#编写的,虽然欣赏你对不调用EMGU OpenCV的看法,但为什么它不能被标记为OpenCV导向的问题。毕竟EMGU只是带有c#包装器的OpenCV库。我发现OpenCV上有很多资源对EMGU很有用,反之亦然。

干杯 克里斯

答案 3 :(得分:0)

基于@BloodAxe的回答,使用EMGU 3.4,可完成以下工作:

// Define roi area (it has small image dimensions). 
var ROI = new System.Drawing.Rectangle(100, 500, 200, 200)

// Take a sub-view of the large image
Mat subView = new Mat(bigImage, ROI);

// Copy contents of the small image to large
small.CopyTo(subView);