影视后期个性化抠像插件的开发
2015-07-02王楠
王 楠
(安徽电子信息职业技术学院 软件学院,安徽 蚌埠 233030)
影视后期个性化抠像插件的开发
王 楠
(安徽电子信息职业技术学院 软件学院,安徽 蚌埠 233030)
在分析影视后期抠像插件系统设计及工作原理的基础上,设计了影视后期的个性化抠像定制插件“Basic Key”,给出了此抠像插件的实现方法及此插件的蓝屏抠像方法、插件各选项的实现算法,并介绍了此抠像插件的应用平台及使用方法。
影视制作;抠像插件;色度键;个性化
抠像[1]是影视后期制作中的一种常用技术,简言之就是将画面中一种或多种颜色变成透明,从而去除画面中不需要的部分,保留用户需要的部分。在影视后期制作中,抠像技术是重点之一,这里所讨论的软件是Adobe After Effects CS4。After Effects是使用范围最广的合成软件之一,并且深受专业人士、业余爱好者、学生的喜爱[2]。但是,After Effects中的内置抠像特效设置过于专业,不适于初级制作。由于影视后期领域在国内起步晚,After Effects目前在国内主要处于应用阶段,其插件的开发处于起步阶段。因此,对软件功能进行优化、开发适合国内影视后期教学及应用的插件很有必要。故本文以扩展After Effects抠像特效、方便使用为出发点,定制了一款个性化抠像插件,以改善After Effects抠像特效,使其更利于普及推广。
1 影视后期抠像插件系统设计及工作原理
1.1 教学抠像插件工作原理
在After Effects中,对需要抠像的图层(Layer)添加了此抠像插件后,就同时启动了插件,通过After Effects SDK调用和启动After Effects的内部参数,掌握了系统操作权,同时为用户和After Effects各个模块之间提供信息传递和响应,实现抠像插件和用户之间的交互。抠像插件与After Effects内部的通信通过After Effects SDK实现,SDK将系统控制模块的信息与命令传递给After Effects内对应的模块,以便模块的控制与调用[3],抠像系统工作原理如图1所示[4]。
1.2 插件选项设计
将After Effects抠像特效的特点进行分析、比较,结合丰富的抠像教学与实践经验,设计抠像插件的属性选项,如图2所示。
1.3 界面设计
本课题开发的插件命名为“基础抠像”(Basic Key),按照前文对插件原理、插件选项的设计与描述,插件在After Effects中的参数控制界面位于特效控制(Effect Controls)面板中。用户对图层添加了此插件后,After Effects就会自动启动此插件,并打开Effect Controls面板,展示其参数控制界面。此插件的参数控制界面设计如图3所示。
1.4 工作流程
根据After Effects插件的工作原理,结合此插件的功能模型,分析得出此抠像插件的工作流程如图4所示。
2 系统开发工具
本课题所研究的抠像插件适用于After Effects CS4软件。此抠像插件以工作站或配置比较高的个人计算机为硬件开发平台,操作系统采用Windows XP / Windows 7系列,开发工具采用面向对象的可视化编程软件Microsoft Visual C++6.0及Adobe After Effects CS4 SDK。
3 抠像插件主功能具体实现
结合After Effects CS4 SDK工具,在Visual C++6.0中编写程序,制作“基础抠像”(Basic Key)插件。抠像插件系统中主要功能的实现算法和代码如下所示。
3.1 提取颜色
使用吸管工具在背景提取颜色,是使用“基础抠像”(Basic Key)插件进行抠像的第一步,即读取画面中某一点(x,y)的像素值,返回BYTE*。对于计算机图像而言,颜色表示方法通常有两种:RGB(R:红色,G:绿色,B:蓝色,取值范围均为0~255)和HSB(H:色相,取值范围是0°~360°;S:饱和度,取值范围是0~100%;B:亮度,取值范围是0~100%),所以分别编写了两种颜色模型下的取色部分代码。此功能对应的VC++编程代码:
//读取(x,y)点的RGB像素值,返回BYTE*,顺序是R,G,B
BYTE*BasicKeyDoc::cvGetpixel(IplImage* img, int x, int y)
{BYTE cvpixel[3];
cvpixel[2]=BYTE((img->imageData + img->widthStep*y)[x*3]);
cvpixel[1]=BYTE((img->imageData + img->widthStep*y)[x*3+1]);
cvpixel[0]=BYTE((img->imageData + img->widthStep*y)[x*3+2]);
return cvpixel;
}
//读取(x,y)点的HSB像素值,返回BYTE* 顺序是H,S,B(设为8 bit位深度时)
uchar* BasicKeyDoc::
cvGetpixelHSV(IplImage* img,int x,int y)
{
return &((uchar*)(img->imageData + img->widthStep*y))[x*3];
BYTE cvpixel[3];
cvpixel[0]=BYTE((img->imageData + img->widthStep*y)[x*3]);
cvpixel[1]=BYTE((img->imageData + img->widthStep*y)[x*3+1]);
cvpixel[2]=BYTE((img->imageData + img->widthStep*y)[x*3+2]);
return cvpixel;
}
//写入(x,y)点的RGB像素值,返回BOOL,对应代码为
BOOL BasicKeyDoc::cvSetPixel(
IplImage* img, int x, int y, int R, int G, int B)
{
(img->imageData + img->widthStep*y)[x*3]=B;
(img->imageData + img->widthStep*y)[x*3+1]=G;
(img->imageData + img->widthStep*y)[x*3+2]=R;
return true;
}
//写入(x,y)点的HSB像素值,返回BOOL 顺序是H,S,B(设为8 bit位深度时)
BOOL BasicKeyDoc::
cvSetPixelHSB(IplImage* img, int x, int y, int H, int S, int B)
{
(img->imageData + img->widthStep*y)[x*3]=int(H/2);
(img->imageData + img->widthStep*y)[x*3+1]=S;
(img->imageData + img->widthStep*y)[x*3+2]=B;
return true;
}
3.2 蓝屏抠像过程
本抠像系统采用颜色抠像的方法,利用背景与前景的颜色差别,把单色的背景去除,原理类似于通常所说的色度键(Chroma Keying)。由于抠像背景大多数选择蓝色,所以色度键通常也称为蓝屏抠像(Blue Screen)。“基础抠像”(Basic Key)插件主要运用的就是蓝屏抠像技术。
蓝屏抠像编程原理:设画面中取色点像素的RGB颜色值用sRGB表示,周围其他像素的RGB颜色值用bRGB表示;设不透明度Alpha用A表示,取值范围为[0,1];设置一个取色的容差值,以T表示。取色点与其他像素之间的颜色距离用|sRGB-bRGB|表示。
蓝屏抠像过程,即选择吸管工具在画面中某一点像素拾取颜色后,将该像素的A值设置为0;计算画面中其他像素与该点的颜色距离,若|sRGB-bRGB|∈[0,T],则相应像素的A值也设为0;若颜色距离不属于此范围,则将其作为混合像素,区分其前景颜色和背景颜色(吸取颜色)的混合比例,计算该像素的A值。
3.3 Alpha通道调整
前文已描述,高级抠像功能是此抠像插件的核心模块,也是优于After Effects内置抠像特效的关键部分。在“基础抠像”(Basic Key)插件中,高级抠像功能对应的选项包括:“屏幕蒙版”(Screen Matte)选项组中的“修剪黑场”(Clip Black),“修剪白场”(Clip White),“屏幕柔化”(Screen Softness)及“屏幕增益”(Screen Gain)等,其中又以“修剪黑场”、“修剪白场”、“屏幕柔化”最为关键,因为对于用户而言,要通过抠像插件得到一个比较完美的Alpha通道,进而获得干净、准确的抠像效果,这3个参数通常都要涉及[6]。下面就对其算法设计和编程代码进行详细描述。
3.3.1 “修剪黑场”和“修剪白场”
修剪黑场(Clip Black),调整Alpha通道中的暗部区域,其初始值为0,取值范围在0~100。增大此选项值可以去除更多背景,但参数过大可能会导致前景也一起消失。
修剪白场(Clip White),调整Alpha通道中的亮部区域,其初始值为100,取值范围在0~100。减小此选项值可以使前景尽量完整,但参数过小则可能导致部分背景无法去除。
选项功能实现的算法设计及代码编写如下:
(1)读取图像,获取所有像素点的位置(坐标)值和颜色(RGB)值。在程序中,将RGB保存在二维数组pixel_RGB[sum][3]中,sum表示像素的个数,同时像素按照先行后列的顺序存储,通过行数、列数可以映射到对应的坐标,颜色的保存顺序为R,G,B。
(2)用户通过使用“屏幕颜色”选项的吸管指定一点颜色,获取该点的RGB值。此步骤的实现代码在前文已描述。
(3)遍历2维数组,计算各个像素点颜色值与所选点RGB值的差距color_distance。这里采用的是欧氏距离[7]计算方法。
//这里以欧式距离计算方法为例,因为R,G,B值的范围均为[0.0,255.0],则max_color_distance 参数取计算得到的最大颜色间距值。
//clip black 和clip white取值范围为[0.0,100.0]
float dist_RGB(float r0, float g0, float b0, float r1, float g1, float b1)
{
float color_distance;
color_distance=sqrt(pow(r1-r0, 2) + pow(g1-g0, 2) + pow(b1-b0, 2));
return color_distance;
}
(4)将用户输入的“输入黑场”(Clip Black)和“输入白场”(Clip White)数值转化为对应的距离值。
float clip_to_distance(float clip, float max_color_distance, int t)
//将Clip值转化为对应的距离值
{ float ClipValue = 0.0;
if (t == 0) //t = 0 时,计算将Clip Black转化为距离值
{ float originClipBlack=
0.2*max_color_distance;
ClipValue = ( (max_color_distance - originClipBlack)*clip )/100.0 +
originClipBlack;
}
else if (t == 1)
//t = 1时, 计算将Clip White转化为距离值
{
float originClipWhite=
0.8*max_color_distance;
ClipValue = ( originClipWhite*clip ) / 100.0;
}
return ClipValue;
}
此为举例说明,如将clip_black=0.0转化为对应的backClipValue=0.2*max_color_distance(表示color_distance的最大颜色差距值);
clip_white=100.0转化为frontClipValue=0.8*max_color_distance。
(5)通过backClipValue和frontClipValue以及color_distance计算各个像素点的不透明度值opacity,代码如下:
bool pixel_opacity(float r, float g, float b, float *pixelOpacity, float clip_black, float clip_white)
{
float color_distance[sum];
//sum指总像素点,像素按先行后列
float max_color_distance = 0.0;
for (int i = 0; i < sum; ++ i)
{
float r1 = pixel_RGB[i][0];
float g1 = pixel_RGB[i][1];
float b1 = pixel_RGB[i][2];
color_distance[i] = dist_RGB(r, g, b, r1, g1, b1);
if (max_color_distance < color_distance)
{ max_color_distance = color_distance; }
}
float backClipValue=clip_to_distance
(clip_black, max_color_distance, 0);
//将clip back 转化为颜色的距离判定点
float frontClipValue=clip_to_distance
(clip_whilte, max_color_distance,1);
//将clip white 转化为颜色的距离判定点
for (int i = 0; i < sum; ++ i)
{ if (color_distance <= backClipValue)
//小于等于backClipValue值,取完全透明
{ pixelOpacity[i] = 0.0; }
else if(color_distance>backClip
Value&&color_distance //在backClipValue与frontClipValue之间,取半透明 { pixelOpacity[i]=(color_distance- backClipValue)/(frontClipValue- backClipValue); } else //大于等于frontClipValue值,取完全不透明 { pixelOpacity[i] = 1.0; } } return true; } 通过增加backClipValue与frontClipValue的值,得到Color_distance与Opacity的关系如图5所示。 (6)依据各像素点的不透明度生成抠像结果。 3.3.2 屏幕柔化 屏幕柔化(Screen Softness),用于对初步抠像得到的Alpha通道进行柔化处理[8]。该选项默认值为0,最大值由抠像的具体画面大小决定。“屏幕柔化”选项的原理是通过调整Alpha通道的模糊度,进而调整整个画面,可以去除抠像可能产生的杂点、生成边缘羽化等效果。本文中,对此功能的实现采用高斯模糊算法。 从数学的角度来看,图像的高斯模糊过程就是图像与正态分布做卷积。由于正态分布又叫作高斯分布,所以这项技术就叫作高斯模糊。高斯模糊是一种图像模糊滤波器,它用正态分布计算图像中每个像素的变换。在2维空间定义为 (1)高斯模糊矩阵计算: //计算高斯模糊矩阵,n表示n×n矩阵,rho表示标准方差 bool Gaussian_matrix(float *matrix_n, int n, float rho) { for (int i = 0; i < n; ++ i) { for (int j = 0; j < n; ++ j) { matrix_n[i*n+j] = 1 / (2 * pi * rho * rho); matrix_n[i*n+j] *= exp((- (pow(i - 2, 2) + pow(j - 2, 2))) / (2 * rho * rho)); } } return true; } (2)模糊处理后的颜色计算: //对于Alpha通道,计算该像素点经过高斯模糊后的颜色值 float Gausssian_compute(float *pixel_Alpha, float *matrix_n, int n, int m); { float changeAlpha = 0.0; int t = floor(n/2); m = m - width - t; for (int i = 0; i < n; ++ i) { for (int j = 0; j < n; ++ j) { changeAlpha += pixel_Alpha[m] * matrix_n[i*n+j]; m ++; } m = m + width - n + 1; } return changeAlpha; } (3)进行高斯模糊处理: //对Alpha通道进行高斯模糊处理 bool Gaussian_Blur(float *pixel_Alpha, float softness, int n) { if (0 == softness) { return false; } float rho = softness/100.0 + 0.5; if (rho > 10.0) { rho = 10.0; } float *matrix_n = (float*)malloc(n*n*sizeof(float)); bool find = Gaussian_matrix(matrix_n, n, rho); for (int i = 0; i < width; ++ i) { for (int j = 0; j < height; ++ j) { if (2*(i +1) < n || 2*i + n > 2 * width || 2*(j +1) < n || 2*j + n > 2 * width) { continue; } int m = i * width + j; pixel_Alpha[m] = Gausssian_compute(pixel_Alpha, matrix_n, n, m); } } return true; } 3.3.3 边缘收缩/扩展 此选项功能的实现算法:以边缘扩展为例,在抠像前景的边缘上取一点,作为圆心,以边缘扩展值为半径(单位为像素),以边缘上某一点为起点,圆心沿着边缘移动,当用户输入值为正值时,将圆移动经过的背景像素区域重新赋予原背景颜色值;当用户输入值为负值时,将圆移动覆盖的前景像素区域的不透明度设置为0,在视觉效果上体现为像素不可见,即边缘向内收缩。 图6 边缘收缩/扩展算法 研究开发的个性化抠像插件虽然取得了良好的应用成效,但对于After Effects功能的研究和插件的开发还需要更进一步深入系统研究,逐步完善。本文为影视后期制作中的抠像应用提出了一种新的思路并实现了其解决的方法。在后续研究中,可以将此Basic Key插件进行升级,使其能适用于After Effects CS5、CS6……;还可以将Basic Key插件的功能进行进一步的扩展,使其功能更加强大,如增加一些专业抠像插件中特有的属性选项,让使用者能了解到专业抠像插件的功能;还可以优化算法,编写效率更高的代码,使抠像系统在容量上更精简、尽量少占用计算机资源,以提高运行速率。 [1]Adobe公司. Adobe After Effects CS4经典教程[M]. 北京: 人民邮电出版社,2009: 202. [2] Lee Lanier. 专业数字合成:必备的工具和技术[M]. 北京: 人民邮电出版社,2012: 1. [3] 胡垂立. 基于After Effects SDK的粒子系统在高职教学中的应用[D]. 上海: 华东师范大学,2011. [4] 赵刚,唐慧佳. Adobe After Effects插件原理及其实现[J]. 计算机应用研究,2000,17(11): 99-100,103. [5] 求是科技. Visual C++数字图像处理典型算法及实现[M]. 北京: 人民邮电出版社,2006: 6. [6] L.Lanier. 专业数字合成:必备的工具和技术[M]. 北京: 人民邮电出版社,2012: 86. [7] 约翰逊. 近代欧式几何学[M]. 哈尔滨: 哈尔滨工业大学出版社,2012: 56 [8] M.Christiansen. After Effects CS4完全剖析[M]. 北京: 人民邮电出版社,2009: 72 Development of Movie Keying Individuational Plug-in WANG Nan ( School of Software, Anhui Vocational College of Electronics and Information Technology, Bengbu 233030, China) We analyze the system design, working principle of movie keying plug-in and customizes, and developes a individuational keying plug-in, “Basic Key”. We discuss the realization method of this keying plug-in, and introduce the algorithm of blue-key method of it, the algorithm of all options. It introduces the application platform and usage method of this keying plug-in. film and television production, keying plug-in, chroma keying, individuation 2015-05-14 王楠,女,安徽蚌埠人,硕士,安徽电子信息职业技术学院讲师,研究方向为影视后期制作、平面设计、三维设计等。 时间:2016-1-5 13:01 网络出版地址:http://www.cnki.net/kcms/detail/34.1150.N.20160105.1301.013.html TP311 A 1007-4260(2015)04-0052-06 10.13757/j.cnki.cn34-1150/n.2015.04.0134 结束语