Mat dest,srcAlpha
//-1表示读取带有alpha通道的图片
srcAlpha = imread("1.png",-1)
dest= imread("2.png")
//(0,0)设置对srcAlpha的叠加
mapToMat(srcAlpha, dest, 0, 0)
void mapToMat(const cv::Mat &srcAlpha, cv::Mat &dest, int x, int y)
{
int nc = 3
int alpha = 0
for (int j = 0j <srcAlpha.rowsj++)
{
for (int i = 0i <srcAlpha.cols*3i += 3)
{
// 目的图片为三通道,所以是三通道的遍历、四通道的源图
// i/3*4表示第i/3个像素的位置
// i/3*4 + 3表示本像素的alpha通道的值
alpha = srcAlpha.ptr<uchar>(j)[i / 3*4 + 3]
//alpha = 255-alpha
if(alpha != 0) //4通道图像的alpha判断
{
for (int k = 0k <3k++)
{
// if (src1.ptr<uchar>(j)[i / nc*nc + k] != 0)
if( (j+y <dest.rows) &&(j+y>=0) &&
((i+x*3) / 3*3 + k <dest.cols*3) &&((i+x*3) / 3*3 + k >= 0) &&
(i/nc*4 + k <srcAlpha.cols*4) &&(i/nc*4 + k >=0) )
{
dest.ptr<uchar>(j+y)[(i+x*nc) / nc*nc + k] = srcAlpha.ptr<uchar>(j)[(i) / nc*4 + k]
}
}
}
}
}
视频叠加算法-白色素材叠加视频叠加算法-彩色素材叠加
视频叠加算法-彩色加亮融合
视频叠加算法-彩色均值融合
如果想在之上叠加一个静止图片很简单,像ffmpeg的滤镜、opencv等都能实现。但是假如文字拥有动画,而且文字出现比较频繁,全部使用序列的png图像会很大。例如如下的素材:
虽然与白色素材叠加算法中所用素材相同,但目的不同,以下demo将素材以“黑色部分叠加,白色区域透明”的效果叠加到视频之上。
原视频:
这是效果:
注:
选用16作拐点的话,会出现大量泛白区域,所以选用32作为拐点来分离出黑色区域。但是同样会忽视某些细节。当然,很可能这些细节是由于编码的“有损”而产生的。使用200 作为全透明峰值。
y为素材视频对应点的Y值,d(包含uv)为输出帧的数据
if y<32
d设置为黑色
else if y<200
d按比例趋近黑色
else
忽视素材叠加,取原帧对应点数据
具体解释参看 视频叠加算法-白色素材叠加
三 待改进
2 会忽略素材视频中的细节,最终视频中有锯齿。
3 对于半透明处,也就是算法中 d按比例趋近黑色处,该计算方法会使得输出视频透明略显生硬,梯度并不明显,该处计算方法待改进。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)