今天给大家讲解一下,如何实现美颜相机中的高级柔焦效果,首先先看下美颜相机中这个功能的效果图:
图1 原图(图片来自网络,如有侵权敬请告知)
图2 美颜相机高级柔焦模版
图3 马赛克效果
图4,动感模糊效果
以上图3和4是两种柔焦的效果,很不错,今天我将用C来实现这个算法。
这个算法的流程如下:
1,前景抠图(自动抠图或者手动抠图)
美颜相机使用的是先手动涂抹出前景目标区域,然后使用自动抠图将该区域准确抠图;
实际上,目前有很多基于深度学习的抠图算法,效果相当不错,比如最近比较火的实时视频抠图技术等等。这里,本人还是给出一些方法的汇总如下:
《Interactive graph cuts for optimal boundary and region segmentation of objects in N-D images》
《Shared Sampling for Real-Time Alpha Matting》
《A Closed Form Solution to Natural Image Matting》
《A Bayesian Approach to Digital Matting》
《Learning Based Alpha Matting using Support Vector Regression》
《Natural Image Matting using Deep Convolutional Neural Networks》
《Deep Image Matting》
本文主要介绍方法,这里给出白百合测试图前景抠图的效果:
图5 白百合前景MASK
2,背景特效大家可以看到图3和图4的效果区别,主要是背景的区别,一个是马赛克,一个是放射模糊;
因此,我们需要对背景图片进行相应的马赛克和放射模糊处理,本人效果图如下:
图6 马赛克效果
图7 放射模糊效果
这里可以参考本人博客里的各种滤镜特效,实际上都可以用来做背景处理,进而得出各种不同的效果;
3,图像融合
有了前景背景之后,我们可以根据前景的MASK(区域的二值MASK),对前景和背景进行alpha融合,公式如下:
Output = F*Mask+(255-Mask)*B
其中F表示前景,B表示背景,其中MASK中白色表示前景,黑色表示背景;
最后本人的效果图如下:
图8 马赛克柔焦效果图
图9 放射模糊柔焦效果图
以上三点就是柔焦效果的具体算法实现过程,最后,给出代码逻辑(我这里实现了四个柔焦的效果):
int f_Focus(unsigned char* srcData, int width, int height, int stride, unsigned char* mask, int intensity, int mode) { //background effects int ret = 0; int i, j; unsigned char* gaussData = (unsigned char*)malloc(sizeof(unsigned char) * stride * height); int radius = intensity * 20 / 100; switch(mode) { case 0://gauss blur effect ret = f_TFastestGaussFilter(srcData, width, height, stride, gaussData, radius); break; case 1://moscia effect memcpy(gaussData, srcData, sizeof(unsigned char) * stride * height); ret = f_TMosaic(gaussData, width, height, stride, intensity / 2); break; case 2://diffusion effect memcpy(gaussData, srcData, sizeof(unsigned char) * stride * height); ret = f_TDiffusion(gaussData, width, height, stride, intensity / 2); break; case 3://zoom blur effect memcpy(gaussData, srcData, sizeof(unsigned char) * stride * height); ret = f_TZoomBlur(gaussData, width, height, stride, width / 2, height / 2, 10, intensity); break; default: break; } //alpha blend unsigned char* pMask = mask; unsigned char* pSrc = srcData; unsigned char* pGauss = gaussData; int k, nk; for(j = 0; j < height; j++) { for(i = 0; i < width; i++) { k = pMask[0]; nk = 255 - k; pSrc[0] = CLIP3((pSrc[0] * k + pGauss[0] * nk) >> 8, 0, 255); pSrc[1] = CLIP3((pSrc[1] * k + pGauss[1] * nk) >> 8, 0, 255); pSrc[2] = CLIP3((pSrc[2] * k + pGauss[2] * nk) >> 8, 0, 255); pSrc += 4; pGauss += 4; pMask += 4; } } free(gaussData); return ret; }; int f_Test(unsigned char *srcData, int width, int height, int stride, unsigned char* mask, int intensity, int mode) { int ret = 0; //Process ret = f_Focus(srcData, width, height, stride, mask, intensity, mode); return ret; };
这里本人给出自己的DEMO,这个DEMO中包含了四种效果(高斯模糊柔焦特效,马赛克柔焦特效,扩散模糊柔焦特效和放射模糊柔焦特效),下载地址:点击打开链接
本人QQ1358009172,欢迎交流学习!