视频去除水印、台标和logo
对于图片的水印和logo的去除,网上有很多办法,最直接的办法,打开photoshop,PS就可搞定,还有其他的图像处理软件效果也都不错,但是对视频的的水印、台标和logo处理,网上相关的技术博客比较少,相关的代码和开源项目也很少啊。求人不如求己,看来只能动手自己搞啦。
需要用到opencv,我首先是在VS2013+opencv2.4.10的平台上,实现了视频的读取,图像抽取;然后调用inpaint( InputArray src, InputArray inpaintMask,OutputArray dst, double inpaintRadius, int flags )函数,将当前帧和掩膜图像进行融合,即可消除固定位置的水印或LOGO,不过掩膜图像要自己手动制作,当然也可采用选定参考帧,然后和后面的图像逐帧对应位置像素点相与为一的办法来做,20帧图像过后就可求得掩膜图像,得到的掩膜图像有毛刺,效果不是很好,还是需要进一步羽化修正一下;如果logo位置不固定的话,把logo截取出来,可以用图像模板匹配的办法或sift特征点匹配,找到logo或水印的位置,这个方法比较烦,要划窗检测,要构建图像金字塔,能自动检测到logo,实用效果不是太好,要进一步优化才好。
具体步骤如下:
1、制作掩膜图像
a、PS手工制作,掩膜图像要和视频分辨率大小一致。
b、前景背景求差法,代码如下:(也包括相关的去logo完整算法)
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include "opencv2/photo/photo.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
cv::VideoCapture cap("C:/Users/zyy/Desktop/test_logs/test.mp4");
if (!cap.isOpened())
{
cout << "Failed!" << endl;
return -1;
}
Mat result, mask, dst1;
Mat inpaintMask1;
Mat inpaintMask = imread("C:/Users/zyy/Desktop/test_logs/log5.jpg");
cv::cvtColor(inpaintMask, inpaintMask, CV_BGR2GRAY);
cv::namedWindow("Result", 1);
cv::namedWindow("Frame", 1);
int i = 0;
for (;;)
{
Mat frame;
cap >> frame;
if (!frame.data)
{
cout << "Over!" << endl;
break;
}
if (i <= 2) //看视频,自己调试确定这个值,二十几帧之后左上角那个小图才出来,所以选了30
{
if (i == 2)
{
mask = frame;
cv::cvtColor(mask, mask, CV_BGR2GRAY);
//Mat inpaintMask1(mask.rows, mask.cols, CV_32FC1, 1);
inpaintMask1 = mask;