【Unity Shaders】抖音变身漫画 2

您所在的位置:网站首页 抖音视频换脸怎么换 【Unity Shaders】抖音变身漫画 2

【Unity Shaders】抖音变身漫画 2

2024-07-16 22:30| 来源: 网络整理| 查看: 265

此篇文章只讨论图像处理部分,AI换脸暂不讨论。上图左边手机拍摄效果,右图是自己通过算法实现。

不同角度和亮度,不同参数的效果对比。

 

提亮图像

由于不同手机或图片的亮度信息不同,这里咱们先加了亮度调整,但是又不能平均加亮,这样会导至图片丢失很多细节,所以选择非线性提亮。

for(int i = 0; i < _Light; i++) { col = pow(col, (1 - col/3.0)); }

非线性提亮方法有很多,大家下载工程后可自行发挥。

减少图像般色级别

提取象素明度信息,以明度为附加参数,减少色阶

fixed4 col = tex2D(_MainTex, i.uv); fixed lum = luminance(col); col.rgb = floor((col.rgb * _quantizationLevels) + lum) / _quantizationLevels;

边缘提取

使用Sobel算子提取信息,拿到当前象素周围9个象素UV,然后采样得到象素信息,卷积拿到边缘信息。最后与边缘阀值比较,当前象素是否为边缘处理。

float bottomLeftIntensity = tex2D(_MainTex, i.bLR.xy).r; float bottomRightIntensity = tex2D(_MainTex, i.bLR.zw).r; ​ float topLeftIntensity = tex2D(_MainTex, i.tLR.xy).r; float topRightIntensity = tex2D(_MainTex, i.tLR.zw).r; ​ float leftIntensity = tex2D(_MainTex, i.leftRight.xy).r; float rightIntensity = tex2D(_MainTex, i.leftRight.zw).r; ​ float topIntensity = tex2D(_MainTex, i.topBottom.xy).r; float bottomIntensity = tex2D(_MainTex, i.topBottom.zw).r; ​ float h = -topLeftIntensity - 2.0 * topIntensity - topRightIntensity + bottomLeftIntensity + 2.0 * bottomIntensity + bottomRightIntensity; float v = -bottomLeftIntensity - 2.0 * leftIntensity - topLeftIntensity + bottomRightIntensity + 2.0 * rightIntensity + topRightIntensity; ​ float mag = length(float2(h, v)); float thresholdTest = 1.0 - step(_threshold, mag);

图像混合

边缘信息后与减色阶后的图像混合得到最终颜色,漫画脸的颜色是固定的偏暖黄色,所以这里还要加一个颜色叠加,让最后的颜色看起来和脸部是相近色。

​float3 finalCol = col * thresholdTest; finalCol = you * finalCol; finalCol = 1 - (1 - finalCol) * (1 - _Color.rgb); return float4(finalCol, 1);

C#代码部分

这个算法共两个Pass,提亮图像为一个Pass,减少色阶+边缘提取+图像混合为一个Pass,所以我们要先生成一个RenderTexture用来存提亮后的图像,然后以在这个图像上做相应处理。

void OnRenderImage(RenderTexture src, RenderTexture dest) { if (material != null) { material.SetFloat("_quantizationLevels", quantizationLevels); material.SetFloat("_threshold", threshold); material.SetColor("_Color", col); material.SetFloat("_radius", radius); material.SetFloat("_Light", lighten); ​ RenderTexture buffer0 = RenderTexture.GetTemporary(src.width, src.height, 0); buffer0.filterMode = FilterMode.Bilinear; Graphics.Blit(src, buffer0, material, 0); ​ ​ Graphics.Blit(buffer0, dest, material, 1); RenderTexture.ReleaseTemporary(buffer0); } else { Graphics.Blit(src, dest); } }

 

工程代码 加 微信号:ITComputerGraph

更多精彩内容,关注公众号《IT木子李》



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3