其他
为了给女朋友独特的七夕惊喜,我学会了人像美肤算法!
在人像美颜中,美肤是一个非常重要的组成部分,健康的肤色,可以凸显一个人整体的气质。搞定一套人像美肤算法,从根源解决你不会P图的烦恼,从此的你指哪磨哪,让女票对你刮目相看!你看,夺好
皮肤美白算法
皮肤调色算法
皮肤美白算法
#include <string.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include"Commen.h"
#include"f_LUTFilter.h"
#include"f_SkinPDF.h"
#include"f_GaussFilter.h"
#include"f_SkinWhite.h"
/*************************************************************************
*函数: 肤色美白
*参数:
*srcData:32BGRA 位图像数据
*width: 图像宽度
*height: 图像高度
*stride: 图像 Stride
*skinMask: 皮肤蒙版
*lutData: 32BGRA LUT 图像数据
*ratio: 美白程度,范围[0,100]
*返回值: 0-成功,其他失败
**************************************************************************/
int f_SkinWhite(unsigned char* srcData, int width, int height, int stride,
unsigned char* lutData, int ratio)
{
int ret = 0;
int length = height * stride;
unsigned char* tempData = (unsigned char*)malloc(sizeof(unsigned char) *
length);
memcpy(tempData, srcData, sizeof(unsigned char) * length);
unsigned char* skinPDF = (unsigned char*)malloc(sizeof(unsigned char) *
length);
memcpy(skinPDF, srcData, sizeof(unsigned char) * length);
ret = f_SkinPDF(skinPDF, width, height, stride);
int maskSmoothRadius = 3;
ret = f_FastGaussFilter(skinPDF, width, height, stride,
maskSmoothRadius);
ret = f_LUTFilter(tempData, width, height, stride, lutData);
unsigned char* pSrc = srcData;
unsigned char* pLut = tempData;
unsigned char* pSkin = skinPDF;
for(int j = 0; j < height; j++)
{
for(int i = 0; i < width; i++)
{
int r, g, b, a;
b = CLIP3((pSrc[0] * (100 - ratio) + pLut[0] * ratio) / 100, 0, 255);
g = CLIP3((pSrc[1] * (100 - ratio) + pLut[1] * ratio) / 100, 0, 255);
r = CLIP3((pSrc[2] * (100 - ratio) + pLut[2] * ratio) / 100, 0, 255);
a = (pSkin[0] + pSkin[1] + pSkin[2]) / 3;
pSrc[0] = CLIP3((b * a + pSrc[0] * (255 - a)) / 255, 0, 255);
pSrc[1] = CLIP3((g * a + pSrc[1] * (255 - a)) / 255, 0, 255);
pSrc[2] = CLIP3((r * a + pSrc[2] * (255 - a)) / 255, 0, 255);
pSrc += 4;
pLut += 4;
pSkin += 4;
}
}
free(tempData);
free(skinPDF);
return ret;
};
/*************************************************************************
*函数: 肤色美白曲线法
*参数:
*srcData:32BGRA 图像数据
*width: 图像宽度
*height: 图像高度
*stride: 图像 Stride
*belta: 曲线参数 belta,范围[2,10],默认:2
*ratio: 磨皮程度,范围 [0,100]
*返回值: 0-成功,其他失败
*参考资料: "A Two-Stage Contrast Enhancement Algorithm for Digital Images"
**************************************************************************/
int f_SkinWhiteCurve(unsigned char* srcData, int width, int height, int
stride, int belta, int ratio)
{
int ret = 0;
int length = height * stride;
unsigned char* skinPDF = (unsigned char*)malloc(sizeof(unsigned char) *
length);
memcpy(skinPDF, srcData, sizeof(unsigned char) * length);
ret = f_SkinPDF(skinPDF, width, height, stride);
int maskSmoothRadius = 3;
ret = f_FastGaussFilter(skinPDF, width, height, stride,
maskSmoothRadius);
unsigned char* pSrc = srcData;
unsigned char* pSkin = skinPDF;
for(int j = 0; j < height; j++)
{
for(int i = 0; i < width; i++)
{
int r, g, b, a;
//skin white curve
b = CLIP3(log((float)pSrc[0] * (belta - 1) / 255.0f + 1) /
log((float)belta) * 255.0f, 0, 255);
g = CLIP3(log((float)pSrc[1] * (belta - 1) / 255.0f + 1) /
log((float)belta) * 255.0f, 0, 255);
r = CLIP3(log((float)pSrc[2] * (belta - 1) / 255.0f + 1) /
log((float)belta) * 255.0f, 0, 255);
b = CLIP3((b * ratio + pSrc[0] * (100 - ratio)) / 100, 0, 255);
g = CLIP3((g * ratio + pSrc[1] * (100 - ratio)) / 100, 0, 255);
r = CLIP3((r * ratio + pSrc[2] * (100 - ratio)) / 100, 0, 255);
//skin pdf
a = (pSkin[0] + pSkin[1] + pSkin[2]) / 3;
pSrc[0] = CLIP3((b * a + pSrc[0] * (255 - a)) / 255, 0, 255);
pSrc[1] = CLIP3((g * a + pSrc[1] * (255 - a)) / 255, 0, 255);
pSrc[2] = CLIP3((r * a + pSrc[2] * (255 - a)) / 255, 0, 255);
pSrc += 4;
pSkin += 4;
}
}
free(skinPDF);
return ret;
}
inline int ModeSmoothLight(int basePixel,int mixPixel)
{
int res = 0;
res = mixPixel > 128 ?
((int)((float)basePixel+((float)mixPixel+(float)mixPixel-
255.0f)*((sqrt((float)basePixel/255.0f) )*255.0f-(float)basePixel)/255.0f)):
((int)((float)basePixel+((float)mixPixel+(float)mixPixel-
255.0f)*((float)basePixel-(float)basePixel*(float)basePixel/255.0f)/255.0f));
return CLIP3(res, 0, 255);
};
/*************************************************************************
*函数: PS 图层法肤色美白
*参数:
*srcData:32BGRA 图像数据
*width: 图像宽度
*height: 图像高度
*stride: 图像 Stride
*ratio: 磨皮程度,范围 [0,100]
*返回值: 0-成功,其他失败
**************************************************************************/
int f_SkinWhitePS(unsigned char* srcData, int width, int height, int stride,
int ratio)
{
int ret = 0;
int length = height * stride;
unsigned char* skinPDF = (unsigned char*)malloc(sizeof(unsigned char) *
length);
memcpy(skinPDF, srcData, sizeof(unsigned char) * length);
ret = f_SkinPDF(skinPDF, width, height, stride);
int maskSmoothRadius = 3;
ret = f_FastGaussFilter(skinPDF, width, height, stride, maskSmoothRadius);
unsigned char* pSrc = srcData;
unsigned char* pSkin = skinPDF;
for(int j = 0; j < height; j++)
{
for(int i = 0; i < width; i++)
{
int r, g, b, a;
//skin white using smoothlight of ps
b = ModeSmoothLight(pSrc[0], 255);
g = ModeSmoothLight(pSrc[1], 255);
r = ModeSmoothLight(pSrc[2], 255);
b = CLIP3((b * ratio + pSrc[0] * (100 - ratio)) / 100, 0, 255);
g = CLIP3((g * ratio + pSrc[1] * (100 - ratio)) / 100, 0, 255);
r = CLIP3((r * ratio + pSrc[2] * (100 - ratio)) / 100, 0, 255);
//skin pdf
a = (pSkin[0] + pSkin[1] + pSkin[2]) / 3;
pSrc[0] = CLIP3((b * a + pSrc[0] * (255 - a)) / 255, 0, 255);
pSrc[1] = CLIP3((g * a + pSrc[1] * (255 - a)) / 255, 0, 255);
pSrc[2] = CLIP3((r * a + pSrc[2] * (255 - a)) / 255, 0, 255);
pSrc += 4;
pSkin += 4;
}
}
free(skinPDF);
return ret;
}
皮肤调色算法
#include <string.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include"Commen.h"
#include"f_LUTFilter.h"
#include"f_SkinPDF.h"
#include"f_GaussFilter.h"
#include"f_SkinColor.h"
/*************************************************************************
*函数: 肤色调节
*参数:
*srcData:32BGRA 图像数据
*width: 图像宽度
*height: 图像高度
*stride: 图像 Stride
*skinMask: 皮肤蒙版
*lutData: 32BGRA LUT 图像数据
*ratio: 肤色程度,范围 [0,100]
*返回值: 0-成功,其他失败
**************************************************************************/
int f_SkinColor(unsigned char* srcData, int width, int height, int stride,
unsigned char* lutData, int ratio)
{
int ret = 0;
int length = height * stride;
unsigned char* tempData = (unsigned char*)malloc(sizeof(unsigned char) *
length);
memcpy(tempData, srcData, sizeof(unsigned char) * length);
unsigned char* skinPDF = (unsigned char*)malloc(sizeof(unsigned char) *
length);
memcpy(skinPDF, srcData, sizeof(unsigned char) * length);
ret = f_SkinPDF(skinPDF, width, height, stride);
int maskSmoothRadius = 3;
ret = f_FastGaussFilter(skinPDF, width, height, stride,
maskSmoothRadius);
ret = f_LUTFilter(tempData, width, height, stride, lutData);
unsigned char* pSrc = srcData;
unsigned char* pLut = tempData;
unsigned char* pSkin = skinPDF;
for(int j = 0; j < height; j++)
{
for(int i = 0; i < width; i++)
{
int r, g, b, a;
b = CLIP3((pSrc[0] * (100 - ratio) + pLut[0] * ratio) / 100, 0, 255);
g = CLIP3((pSrc[1] * (100 - ratio) + pLut[1] * ratio) / 100, 0, 255);
r = CLIP3((pSrc[2] * (100 - ratio) + pLut[2] * ratio) / 100, 0, 255);
a = (pSkin[0] + pSkin[1] + pSkin[2]) / 3;
pSrc[0] = CLIP3((b * a + pSrc[0] * (255 - a)) / 255, 0, 255);
pSrc[1] = CLIP3((g * a + pSrc[1] * (255 - a)) / 255, 0, 255);
pSrc[2] = CLIP3((r * a + pSrc[2] * (255 - a)) / 255, 0, 255);
pSrc += 4;
pLut += 4;
pSkin += 4;
}
}
free(tempData);
free(skinPDF);
return ret;
};
胡耀武 谭娟 李云夕 著
3 本书系统、全面地介绍了与图像视频滤镜和人像美颜美妆特效相关的算法基础知识与方法思路,涵盖了市面上流行的美颜美妆App的特效功能,包括传统方法和基于深度学习的AI滤镜和美颜算法。
热文推荐