使用Opencv在另一个视频上嵌入一个视频



我希望在主视频窗口中运行另一个视频。下面是它的尝试代码:

#include <cv.h>
#include <highgui.h>
#include <iostream>
using namespace std;
void OverlayImage(IplImage* src, IplImage* overlay, CvScalar S, CvScalar D) {
CvPoint location;
//location.x = (0.5*(src->width))-50;
//location.y = src->height-110;
//cout << location.x << " " << location.y << endl;
location.x = 100;
location.y = 100;
for (int i = location.y; i < (location.y + overlay->height); i++) {
    for (int j = location.x; j < (location.x + overlay->width); j++) {
        CvScalar source = cvGet2D(src, i, j);
        CvScalar over   = cvGet2D(overlay, i-location.y, j-location.x);
        CvScalar merged;
        for(int i = 0; i < 4; i++)
            merged.val[i] = (S.val[i] * source.val[i] + D.val[i] * over.val[i]);
        cvSet2D(src, i + location.y, j + location.x, merged);
    }
}
}
int main (int argc, char* argv[]) {
CvCapture* capture = NULL;
CvCapture* ad      = NULL;
capture = cvCaptureFromAVI("Cricketc11.avi");
ad      = cvCaptureFromAVI("Cricketc1.avi");
assert(ad);
assert(capture);
cvNamedWindow("Video", 0);
int fps          = ( int )cvGetCaptureProperty( capture, CV_CAP_PROP_FPS );
int noOfFrames   = ( int )cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_COUNT );
int height       = ( int )cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT );
int width        = ( int )cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH );
cout << height << " " << width << endl;
int fpsad        = ( int )cvGetCaptureProperty( ad, CV_CAP_PROP_FPS );
int noOfFramesad = ( int )cvGetCaptureProperty( ad, CV_CAP_PROP_FRAME_COUNT );
int heightad     = ( int )cvGetCaptureProperty( ad, CV_CAP_PROP_FRAME_HEIGHT );
int widthad      = ( int )cvGetCaptureProperty( ad, CV_CAP_PROP_FRAME_WIDTH );
IplImage* tempimg = NULL;
IplImage* tempad  = NULL;
while(capture) {
    tempimg = cvQueryFrame(capture);
    assert(tempimg);
    if (ad) {
        tempad  = cvQueryFrame(ad);
        assert(tempad);
        IplImage* newimg = cvCreateImage(cvSize(100,100), IPL_DEPTH_8U, tempad->nChannels);
        cvResize(tempad, newimg, 1);
        OverlayImage(tempimg, newimg, cvScalar(0,0,0,0), cvScalar(1,1,1,1));
    }
    else
        cvReleaseCapture(&ad);
    cvWaitKey(1000/fps);
    cvShowImage("Video", tempimg);
}
cvReleaseCapture(&capture);
cvDestroyAllWindows();
return 0;
}

这段代码只有在输入视频相同的情况下才能正常运行。如果视频的长度或帧数不同,则在嵌入视频结束后给出错误。

如何纠正?

发生

每次调用cvQueryFrame(source)时,源的内部帧计数器增加。这就是为什么你的第二部电影应该和主电影一样长(以帧计)。

作为一个解决办法,我建议你使用一个广告电影,它的帧数(长度* fps)等于主电影的整数比率,并使用临时图像缓冲区来保存你需要的数据。

一个理想的解决方案是首先将最短的(帧内)电影插值到最长的大小,然后合并它们,但是如果你不愿意使用最近邻或线性插值,则时间上采样可能具有挑战性。

如果广告视频比较小

您可以在以下几个解决方案中选择:

  • 检测到您已到达终点并停止发送图像
  • 检测到您已到达结尾,并从开头重新打开广告影片
  • 使用一个临时图像来始终在内存中保存广告影片的最后一帧有效帧,如果没有新的,则发送此图像
  • 等。

相关内容

  • 没有找到相关文章