抠图技术初探

图像抠图英文名叫 image matting,顾名思义就是将目标图像从背景中分离出来的一种图像处理技术。根据图像背景的复杂程度,一般分为纯色背景抠图(“绿幕”或者“蓝幕”)和自然图像抠图。

“绿幕”抠图

这项技术主要被用在电影工业中。比如有时看到电影拍摄的场景中周围全是绿色的背景,甚至里面的工作人员也穿着绿色的衣服。这些绿色的背景在后期的处理中会用抠图技术去除,替换上电影中的背景,制作出各种宏大的场景或者特效,比如:

看了这些对比图是不是再也不敢相信自己的眼睛了,同时也要佩服这些演员丰富的想象力。 上面说的就是抠图中最原始的“绿幕”或者“蓝幕”抠图技术,之所以选择绿色和蓝色,是因为这两种颜色和肤色相差最远,同时做为rgb三原色之一也更容易处理。欧美多用绿色,是因为他们有人是蓝眼睛。理论上用其他的纯色背景也是可以的,只是要确保背景和前景不要有重叠的颜色,否则前景中相同颜色的部分也会被扣掉。 下面的代码就用opencv实现了一个最简单的绿幕抠图:  

        mat src = imread("d:\\samplepic\\g1.png");

        mat hsvsrc;

        mat result(src.size(), cv_8uc3, scalar(0,0,0));

        cvtcolor(src, hsvsrc, cv_bgr2hsv);//转换到hsv颜色空间

        for(int i = 0; i < src.rows; i++)

        {

            for (int j = 0; j < src.cols; j++)

            {

                uchar b = src.at<vec3b>(i,j)[0];  

                uchar g = src.at<vec3b>(i,j)[1];  

                uchar r = src.at<vec3b>(i,j)[2];  

             

                uchar h = hsvsrc.at<vec3b>(i,j)[0];  

                uchar s = hsvsrc.at<vec3b>(i,j)[1];  

                uchar v = hsvsrc.at<vec3b>(i,j)[2]; 

                

                if (h > 60 && h <= 130 && s > 100) //判断绿色像素点

                {

                    b = 0;

                    g = 0;

                    r = 0;

                }

                result.at<vec3b>(i,j)[0] = b;  

                result.at<vec3b>(i,j)[1] = g;  

                result.at<vec3b>(i,j)[2] = r;  

            }

        }</vec3b></vec3b></vec3b></vec3b></vec3b></vec3b></vec3b></vec3b></vec3b>

原理是首先将图像的颜色从rgb转换到hsv空间,hsv分别表示:色调(h),饱和度(s),明度(v),通过h来判断大致的绿色的范围,然后将原图中判断为绿色背景的像素点rgb都置为0。

网上找的一张绿色背景图试验的效果:

当然这个只是最简单的处理,当背景不均匀时有可能会有一些残留,或者把前景图像中的某些像素扣掉,同时边缘也还有一些残留的绿色像素和锯齿,要达到理想的效果需要做进一步的处理。

自然图像抠图 绿幕抠图对图像背景有苛刻的要求,现实中蓝绿纯色背景的图片太少,更多的是平时用手机或者相机拍摄的复杂背景的图片,这时候要想分离前景,就需要用到自然图像抠图技术。

自然图像抠图基本都基于这样一种模型: c = αf + (1-α)b 这个模型把原始的图像看成了由前景和背景叠加合成所组成的图,其中:

  • c 为图像当前可观察到的颜色,是已知的
  • f 是前景色,
  • b 背景色,
  • α 不透明度([0,1]区间变化,1为不透明,0为完全透明)。

这个模型表示图像像素的颜色是已经叠加合成过的颜色了也就是c,至于α、f、b都是未知的。而抠图算法就是要把三个变量给解出来。而要解出这些变量需要引入额外的约束信息,这通常需要用户的交互,由用户来指定一些初始的背景和前景的信息。

指定约束信息通常有两种方式: 1. trimap 一般用白色部分表示前景,黑色表示背景,灰色表示待识别的部分

                      原图                                                trimap图 2. scribbles 在前景和背景画几笔的草图。

               原图                             前景scribble                     背景scribble

各种抠图算法做的事情,就是如何更准确更快速地通过用户指定的约束信息估计出未知区域的α、b、f来。抠图算法解出每个像素的α值后就可以生成一张α图,这张图前景是白色的,其余都是黑色的蒙板图,它和原图结合后就完成了抠图。

alphamatting 网站中对历年出现的45种抠图算法进行了评测和排名。评测方法是使用8张不同类型图片做标准,测试每种算法在不同的trimap下对这些图片的抠图效果。从排名来看,2017年新出现的两种算法,抠图的效果相对最好。当然也可以看到没有一种算法是在所有的评测图片中都表现最好,从这里也可以看到自然图像抠图的复杂性。

看下排名靠前的几种算法抠图的效果: information-flow matting 算法

deep matting 算法

看抠图效果是不是很惊叹,头发的细节都能扣出来,然而这些算法运算速度普遍的很慢,要想在实时性要求比较高的场景中使用,需要大量的工程化改进和优化工作。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏跟着阿笨一起玩NET

从sql server 中读取二进制图片

431
来自专栏跟着阿笨一起玩NET

treeview 绑定文件夹和文件

521
来自专栏自由而无用的灵魂的碎碎念

小项目分享---混色器

编写代码的同志们一般懂美术的就少了,偶也是,什么色轮、三维加色等等。虽然看过一些书籍(如内田广由纪的《配色基础原理》),不过还是一知半解的。

1013
来自专栏张善友的专栏

弹出式模态窗体选择文本控件

2006年就要到来了,最近比较忙,很少更新blog,今天发一个模态窗体选择文本控件辞旧迎新.新年在发几个asp.net2.0 webPart控件同各位分享: ...

1977
来自专栏木宛城主

曾今的代码系列——自己的分页控件+存储过程实现分页

项目里面的测试代码,仅供参考 LoginByAjax <title>Ajax登陆</title> <script src="Scripts/c...

1915
来自专栏互联网开发者交流社区

STC-单片机控制系统

1163
来自专栏hbbliyong

socket 通信 多线程调用窗体(委托)的几个知识点,记录在案,以备查阅

1.socket 通信传输汉字的方法:Encoding.GetEncoding("GB2312").GetString(Receivebyte) 发送接收都这样...

2767
来自专栏菩提树下的杨过

基于sliverlight + wcf的web 文字版IM 示例

演示地址: http://task.24city.com/default.html 预览界面: ? 一、布局 采用Grid布局,5行2列 第一行:为登录/注册信...

3266
来自专栏逍遥剑客的游戏开发

实现一个同步的RenderApplication

1414
来自专栏王磊的博客

MySQL数据库工具类之——DataTable批量加入MySQL数据库(Net版)

MySQL数据库工具类之——DataTable批量加入数据库(Net版),MySqlDbHelper通用类希望能对大家有用,代码如下: using MySql....

3689

扫码关注云+社区