影楼精修-肤色统一算法解析

注意:本文样例图片为了避免侵权,均使用AIGC生成;

本文介绍影楼精修中肤色统一算法的实现方案,并以像素蛋糕为例,进行分析说明。

肤色统一就是将人像照片中皮肤区域的颜色进行统一,看起来颜色均匀一致,不会出现颜色不均匀问题。我们以像素蛋糕软件为例,示例图如下:

可以看到,在对人脸和身体进行肤色统一之后,皮肤的颜色一致性变好了不少,给人主观感受更佳。

像素蛋糕的肤色统一功能历经了多个版本的迭代,目前包含AI肤色统一和肤色统一两个版本,同时又将人脸和身体区域做了区分,得到了脸部区域肤色统一和身体区域肤色统一功能调节,从用户或者设计师角度来讲,可控性更强,同时支持了单人和多人的处理。

肤色统一和AI肤色统一功能的差异:可能是AI肤色统一使用了基于深度学习的模型方案,直接自动对皮肤颜色和亮度进行调节,而肤色统一则是基于传统图像处理方案构建的;

我们这里以传统肤色统一为例进行说明。通过效果上的测试,将像素蛋糕的肤色统一特点总结如下:

1.皮肤区域颜色一致性提高,颜色向某个颜色靠拢,而且,这个颜色并非皮肤区域的颜色均值,而是亮度较高的颜色;

2.皮肤暗部区域的亮度会自动调整变亮;

3.人脸和皮肤区域可分开处理;

我们将按照这三个特点来进行实现;

算法方案

假设原图为S,最终效果图为D;

1.对S进行皮肤分割,获得皮肤区域Mask图Mask_skin,这一步需要较高的准确性,皮肤区域为1-255的灰度值,非皮肤区域为0;目前皮肤分割相对比较准确的图片API,如:美图皮肤分割API > 阿里云皮肤分割API;

美图API:https://ai.meitu.com/index?t=1747366168417

阿里云API:https://vision.aliyun.com/experience/detail?tagName=imageseg&children=SegmentSkin

2.对S进行人脸点位检测,根据人脸关键点,计算人脸区域Mask图Mask_face;

3.将肤色统一划分为皮肤区域亮度统一和颜色统一两个模块;

3.1亮度统一,以身体皮肤区域处理为例,对皮肤区域进行基于直方图信息的暗部区域自动亮度矫正;

思路:统计皮肤区域亮度直方图,计算亮度中值,统计亮度低于中值的暗部区域皮肤像素数量,用于动态计算亮度增强程度,根据亮度增强程度,对暗部区域亮度进行矫正,非暗部区域保持不变;

这里给出亮度统一的核心代码:

void SkinBrightenWithHistogram(unsigned char* bgraData, int width, int height, int stride, unsigned char* skinMask) {int size = width * height;float* luminance = (float*)malloc(sizeof(float) * size);int histBins[256] = { 0 };int skinCount = 0;// 1. 提取亮度信息并构建直方图for (int y = 0; y < height; ++y) {unsigned char* row = bgraData + y * stride;for (int x = 0; x < width; ++x, row += 4) {int idx = y * width + x;float r = row[2], g = row[1], b = row[0];float yVal = 0.299f * r + 0.587f * g + 0.114f * b;luminance[idx] = yVal;if (skinMask[idx] > 20) {int bin = (int)CLIP3(yVal, 0, 255);histBins[bin]++;skinCount++;}}}if (skinCount == 0) {free(luminance);return;}// 2. 使用直方图累加计算中值亮度int medianIndex = skinCount / 2;int cumulative = 0;int medianBin = 0;for (int i = 0; i < 256; ++i) {cumulative += histBins[i];if (cumulative >= medianIndex) {medianBin = i;break;}}float medianY = (float)medianBin;// 3. 统计暗部像素数量(亮度 < 中值)int darkCount = 0;for (int i = 0; i < medianBin; ++i) {darkCount += histBins[i];}float darkRatio = (float)darkCount / skinCount;4. 根据暗部比例动态计算增强强度 alpha//float alpha = CLAMP(0.3f + darkRatio * 0.7f, 0.3f, 1.0f);//if (medianY < 80.0f) {//        alpha *= 1.2f;//}//float gamma = 1.2f;// 5. 根据暗部比例动态计算增强强度 alpha(提高提亮效果)float alpha = CLIP3(0.4f + darkRatio * 1.0f, 0.4f, 1.2f);  // 强化基础 alphaif (medianY < 80.0f) {alpha *= 1.4f;  // 放大提亮倍数}else if (medianY < 100.0f) {alpha *= 1.2f;  // 中等放大}float gamma = 1.4f;  // 增加 gamma(让暗部提亮更明显)// 6. 提亮暗部区域for (int y = 0; y < height; ++y) {unsigned char* row = bgraData + y * stride;for (int x = 0; x < width; ++x, row += 4) {int idx = y * width + x;if (skinMask[idx] < 5) continue;float Y = luminance[idx];if (Y < medianY) {float norm = CLIP3(1.0f - (Y / (medianY + 1e-5f)), 0.0f, 1.0f);float boost = alpha * powf(norm, gamma);float newY = CLIP3(Y + boost * medianY, 0, 255);float scale = newY / (Y + 1e-5f);int gray = row[1] * skinMask[idx] / 255;  // 用绿色通道估算灰度用于保色插值for (int c = 0; c < 3; ++c) {float val = row[2 - c] * scale;val = (unsigned char)CLIP3(val, 0, 255);row[2 - c] = (val * gray + row[2 - c] * (255 - gray)) / 255;}}}}free(luminance);
}

3.2颜色统一,基于HSV或Lab颜色空间,计算皮肤区域颜色亮度直方图统计的中值以上的皮肤像素RGB均值,映射到HSV或Lab颜色空间,得到对应H或ab的均值(也可直接统计H或ab的均值);以HSV为例,根据原图皮肤像素的HSV和目标均值HSV,重新映射得到颜色统一为均值颜色后的HSV,然后映射到RGB;

HSV_result=(H_mean, S_src,V_src)

RGB_result=HSV_result---->RGB

4.使用3的方式,分别对人脸区域和身体皮肤区域进行肤色统一,分别得到效果图D_face和D_body;

5.设置人脸区域肤色统一参数k_face,身体肤色统一参数k_body,范围[0,100],将原图S和D_face,D_body进行alpha blend,得到最终效果图D;

上述算法流程就是本人基于传统数字图像处理算法构建的肤色统一算法,效果测试和对比如下:

通过测试效果对比,可以看到,对比原图S,本文算法在脖子等暗部区域亮度有一定的自动校正,同时,人脸和身体皮肤区域的肤色区域一致,基本实现了像素蛋糕类似的功能;

对于AI肤色统一,效果上会比传统方法更自然,同时,对于暗部的亮度矫正也会更准确,后续将陆续进行分析;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/905869.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络:什么是计算机网络?它的定义和组成是什么?

计算机网络是指通过通信设备和传输介质&#xff0c;将分布在不同地理位置的计算机、终端设备及其他网络设备连接起来&#xff0c;实现资源共享、数据传输和协同工作的系统。其核心目标是使设备之间能够高效、可靠地交换信息。 关键组成部分 硬件设备 终端设备&#xff1a;如计算…

深度学习---获取模型中间层输出的意义

一、什么是 Hook&#xff08;钩子函数&#xff09;&#xff1f; 在 PyTorch 中&#xff0c;Hook 是一种机制&#xff0c;允许我们在模型的前向传播或反向传播过程中&#xff0c;插入自定义的函数&#xff0c;用来观察或修改中间数据。 最常用的 hook 是 forward hook&#xf…

存储器上如何存储1和0

在计算机存储器中&#xff0c;数据最终以**二进制形式&#xff08;0和1&#xff09;**存储&#xff0c;这是由硬件特性和电子电路的物理特性决定的。以下是具体存储方式的详细解析&#xff1a; 一、存储的物理基础&#xff1a;半导体电路与电平信号 计算机存储器&#xff08;…

Qt中的RCC

Qt资源系统(Qt resource system)是一种独立于平台的机制&#xff0c;用于在应用程序中传输资源文件。如果你的应用程序始终需要一组特定的文件(例如图标、翻译文件和图片)&#xff0c;并且你不想使用特定于系统的方式来打包和定位这些资源&#xff0c;则可以使用Qt资源系统。 最…

2918. 数组的最小相等和

2918. 数组的最小相等和 题目链接&#xff1a;2918. 数组的最小相等和 代码如下&#xff1a; class Solution { public:long long minSum(vector<int>& nums1, vector<int>& nums2) {auto [sum1, zero1] calc(nums1);auto [sum2, zero2] calc(nums2);i…

使用 Docker 部署 OnlyOffice

使用 Docker 部署 OnlyOffice 在如今容器化技术盛行的时代&#xff0c;Docker 已成为应用快速部署和隔离的最佳选择。OnlyOffice 作为一款功能强大的在线办公套件&#xff0c;通过 Docker 部署不仅能够简化安装和维护流程&#xff0c;还能在不同环境中保持一致性&#xff0c;极…

DDD领域驱动介绍

&#x1f4d5;我是廖志伟&#xff0c;一名Java开发工程师、《Java项目实战——深入理解大型互联网企业通用技术》&#xff08;基础篇&#xff09;、&#xff08;进阶篇&#xff09;、&#xff08;架构篇&#xff09;清华大学出版社签约作家、Java领域优质创作者、CSDN博客专家、…

前端 CSS 样式书写与选择器 基础知识

1.CSS介绍 CSS是Cascading Style Sheet的缩写&#xff0c;中文意思为"层叠样式表"&#xff0c;它是网页的装饰者&#xff0c;用来修饰各标签 排版(大小、边距、背景、位置等)、改变字体的样式(字体大小、字体颜色、对齐方式等)。 2.CSS书写位置 2.1 样式表特征 层…

鸿蒙 从打开一个新窗口到Stage模型的UIAbility组件

打开一个新的窗口 我们首先来实现如何在一个应用中打开一个新窗口&#xff0c;使用的模型是 Stage 模型 在项目文件里&#xff0c;新建一个 newWindow.ets 新文件 src/main/ets/pages/newWindow.ets newWindow.ets文件里面随便写点什么都行&#xff0c;这里是第一步创建的文件…

Linux的日志管理

日志管理服务rsyslogd 配置文件 | 日志类型 | 说明 | | -------------------- | ----------------------------------- | | auth | pam产生的日志 | | authpriv | ssh、ftp等…

【PhysUnits】4.1 类型级比特位实现解释(boolean.rs)

一、源码 该代码实现了一个类型级(type-level)的布尔系统&#xff0c;允许在编译时进行布尔运算。 //! 类型级比特位实现 //! //! 这些是基础的比特位类型&#xff0c;作为本库中其他数值类型的构建基础 //! //! 已实现的**类型运算符**&#xff1a; //! //! - 来自 core::op…

【docker】--数据卷挂载

文章目录 存储卷管理创建存储卷查看存储卷详细信息查看存储卷删除存储卷 存储卷管理 # 目录挂载 docker run -v 本机目录&#xff1a;容器目录#1&#xff09; # 将容器内部的 “/usr/share/nginx/html” 进行持久化挂载 会在宿主机生成一个随机的存储卷 docker run -v /usr/sh…

双重差分模型学习笔记2(理论)

【DID最全总结】90分钟带你速通双重差分&#xff01;_哔哩哔哩_bilibili 目录 一、staggered DID 交错双重差分 二、动态双重差分 动态双重差分法公式解释 符号解释 公式逻辑与案例 与标准DID的区别 总结 “双减” 政策动态差分模型 &#xff08;一&#xff09;设定处…

预测模型开发与评估:基于机器学习的数据分析实践

在当今数据驱动的时代&#xff0c;预测模型已成为各行各业决策制定的核心工具。本文将分享我在COMP5310课程项目中开发预测模型的经验&#xff0c;探讨从数据清洗到模型优化的完整过程&#xff0c;并提供详细的技术实现代码。 ## 研究问题与数据集 ### 研究问题 我们的研究聚焦…

Java 并发编程归纳总结(可重入锁 | JMM | synchronized 实现原理)

1、锁的可重入 一个不可重入的锁&#xff0c;抢占该锁的方法递归调用自己&#xff0c;或者两个持有该锁的方法之间发生调用&#xff0c;都会发生死锁。以之前实现的显式独占锁为例&#xff0c;在递归调用时会发生死锁&#xff1a; public class MyLock implements Lock {/* 仅…

数据治理域——数据同步设计

摘要 本文主要介绍了数据同步的多种方式&#xff0c;包括直连同步、数据文件同步和数据库日志解析同步。每种方式都有其适用场景、技术特点、优缺点以及适用的数据类型和实时性要求。文章还详细探讨了数据直连同步的特点、工作原理、优点、缺点、适用场景等&#xff0c;并对数…

AI人工智能在教育领域的应用

AI人工智能在教育领域的应用 随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;逐渐成为推动教育变革的重要力量。AI在教育领域的应用不仅改变了传统的教学模式&#xff0c;还为个性化学习、教育资源优化和教育管理带来了前所未有的机遇。本文将从多个方面探…

ohttps开启群晖ssl证书自动更新

开启群晖ssl证书自动更新OHTTPS ohttps是一个免费自动签发ssl证书、管理、部署的项目。 https://ohttps.com 本文举例以ohttps项目自动部署、更新群晖的ssl证书。 部署 签发证书 打开ohttps-证书管理-创建证书-按你实际情况创建证书。创建部署节点 打开Ohttps-部署节点-添加…

ElasticSearch聚合操作案例

1、根据color分组统计销售数量 只执行聚合分组&#xff0c;不做复杂的聚合统计。在ES中最基础的聚合为terms&#xff0c;相当于 SQL中的count。 在ES中默认为分组数据做排序&#xff0c;使用的是doc_count数据执行降序排列。可以使用 _key元数据&#xff0c;根据分组后的字段数…

SQLite 数据库常见问题及解决方法

一、数据库文件锁定问题 1. 问题表现 在多线程或多进程环境下访问 SQLite 数据库时&#xff0c;常常会出现数据库文件被锁定的情况。当一个进程对数据库执行写操作时&#xff0c;其他进程的读写操作都会被阻塞&#xff0c;导致应用程序出现卡顿甚至无响应。比如在移动应用开发…