QT5+OpenCV美白效果
来源:互联网 发布:恩比德体测数据 编辑:程序博客网 时间:2024/04/28 19:06
皮肤美白的详细内容请参考:对皮肤美白算法的一些研究。
本文采用上面文中的第一种方法即色彩平衡进行美白,首先看了下ImageStone的源码,找到了色彩平衡功能的相关代码如下(源代码在ImageStone中的include\pixelprocessor\PixelProcessorBase.h头文件中):
由于用色彩平衡来美白要满足以下三项,第一:色阶的三个调整值必须相同或者差异很小,不然输出图片会出现偏色,第二:一定选择中间调;第三:必须不勾选保持明度选项,所以对上面的代码简化后得到如下美白代码:
由于本文算法未对皮肤进行检测,所以美白对象为整张图,效果可能不是很好,有兴趣的可自行加上肤色检测
参考:
图像编辑之色彩平衡
皮肤检测算法三种,示例与代码
Opencv之人脸肤色检测总结
本文采用上面文中的第一种方法即色彩平衡进行美白,首先看了下ImageStone的源码,找到了色彩平衡功能的相关代码如下(源代码在ImageStone中的include\pixelprocessor\PixelProcessorBase.h头文件中):
FCPixelColorBalance (bool bPreLum, TONE_REGION ToneRgn, int cyan_red, int magenta_green, int yellow_blue) { m_bPreserveLuminosity = bPreLum ; int cyan_red_rgn[3] = {0,0,0}, magenta_green_rgn[3] = {0,0,0}, yellow_blue_rgn[3] = {0,0,0} ; cyan_red_rgn[ToneRgn] = cyan_red ; magenta_green_rgn[ToneRgn] = magenta_green ; yellow_blue_rgn[ToneRgn] = yellow_blue ; // add for lightening, sub for darkening PCL_array<double> highlights_add(256), midtones_add(256), shadows_add(256), highlights_sub(256), midtones_sub(256), shadows_sub(256) ; int i ; for (i=0 ; i < 256 ; i++) { highlights_add[i] = shadows_sub[255 - i] = (1.075 - 1 / (i / 16.0 + 1)) ; midtones_add[i] = midtones_sub[i] = 0.667 * (1 - FSquare ((i - 127.0) / 127.0)) ; shadows_add[i] = highlights_sub[i] = 0.667 * (1 - FSquare ((i - 127.0) / 127.0)) ; } // Set the transfer arrays (for speed) double * cyan_red_transfer[3], * magenta_green_transfer[3], * yellow_blue_transfer[3] ; cyan_red_transfer[TONE_SHADOWS] = (cyan_red_rgn[TONE_SHADOWS] > 0) ? shadows_add.get() : shadows_sub.get() ; cyan_red_transfer[TONE_MIDTONES] = (cyan_red_rgn[TONE_MIDTONES] > 0) ? midtones_add.get() : midtones_sub.get() ; cyan_red_transfer[TONE_HIGHLIGHTS] = (cyan_red_rgn[TONE_HIGHLIGHTS] > 0) ? highlights_add.get() : highlights_sub.get() ; magenta_green_transfer[TONE_SHADOWS] = (magenta_green_rgn[TONE_SHADOWS] > 0) ? shadows_add.get() : shadows_sub.get() ; magenta_green_transfer[TONE_MIDTONES] = (magenta_green_rgn[TONE_MIDTONES] > 0) ? midtones_add.get() : midtones_sub.get() ; magenta_green_transfer[TONE_HIGHLIGHTS] = (magenta_green_rgn[TONE_HIGHLIGHTS] > 0) ? highlights_add.get() : highlights_sub.get() ; yellow_blue_transfer[TONE_SHADOWS] = (yellow_blue_rgn[TONE_SHADOWS] > 0) ? shadows_add.get() : shadows_sub.get() ; yellow_blue_transfer[TONE_MIDTONES] = (yellow_blue_rgn[TONE_MIDTONES] > 0) ? midtones_add.get() : midtones_sub.get() ; yellow_blue_transfer[TONE_HIGHLIGHTS] = (yellow_blue_rgn[TONE_HIGHLIGHTS] > 0) ? highlights_add.get() : highlights_sub.get() ; for (i=0 ; i < 256 ; i++) { int r_n = i, g_n = i, b_n = i ; r_n += (int)(cyan_red_rgn[TONE_SHADOWS] * cyan_red_transfer[TONE_SHADOWS][r_n]); r_n = FClamp0255(r_n); r_n += (int)(cyan_red_rgn[TONE_MIDTONES] * cyan_red_transfer[TONE_MIDTONES][r_n]); r_n = FClamp0255(r_n); r_n += (int)(cyan_red_rgn[TONE_HIGHLIGHTS] * cyan_red_transfer[TONE_HIGHLIGHTS][r_n]); r_n = FClamp0255(r_n); g_n += (int)(magenta_green_rgn[TONE_SHADOWS] * magenta_green_transfer[TONE_SHADOWS][g_n]); g_n = FClamp0255(g_n); g_n += (int)(magenta_green_rgn[TONE_MIDTONES] * magenta_green_transfer[TONE_MIDTONES][g_n]); g_n = FClamp0255(g_n); g_n += (int)(magenta_green_rgn[TONE_HIGHLIGHTS] * magenta_green_transfer[TONE_HIGHLIGHTS][g_n]); g_n = FClamp0255(g_n); b_n += (int)(yellow_blue_rgn[TONE_SHADOWS] * yellow_blue_transfer[TONE_SHADOWS][b_n]); b_n = FClamp0255(b_n); b_n += (int)(yellow_blue_rgn[TONE_MIDTONES] * yellow_blue_transfer[TONE_MIDTONES][b_n]); b_n = FClamp0255(b_n); b_n += (int)(yellow_blue_rgn[TONE_HIGHLIGHTS] * yellow_blue_transfer[TONE_HIGHLIGHTS][b_n]); b_n = FClamp0255(b_n); m_pLookupR[i] = r_n ; m_pLookupG[i] = g_n ; m_pLookupB[i] = b_n ; } }
由于用色彩平衡来美白要满足以下三项,第一:色阶的三个调整值必须相同或者差异很小,不然输出图片会出现偏色,第二:一定选择中间调;第三:必须不勾选保持明度选项,所以对上面的代码简化后得到如下美白代码:
//定义转换数组 double highlights_add[256], highlights_sub[256]; double midtones_add[256], midtones_sub[256]; double shadows_add[256], shadows_sub[256];//初始化转换数组 for (int i = 0; i < 256; i++) { highlights_add[i] = shadows_sub[255 - i] = (1.075 - 1 / ((double) i / 16.0 + 1)); midtones_add[i] = midtones_sub[i] = 0.667 * (1 - (((double) i - 127.0) / 127.0)*(((double) i - 127.0) / 127.0)); shadows_add[i] = highlights_sub[i] = 0.667 * (1 - (((double) i - 127.0) / 127.0)*(((double) i - 127.0) / 127.0)); }//实现相关函数int FMax(const int X, const int Y){ return (X < Y ? Y : X);}int FMin(const int X, const int Y){ return (Y < X ? Y : X);}void BalanceColor(Mat& bitmap,int value){ int red, green, blue; unsigned char r_lookup[256],g_lookup[256],b_lookup[256]; for (int i = 0; i < 256; i++) { red = i; green = i; blue = i; red += (int)( 0.0 * shadows_sub[red] + value * midtones_add[red] + 0.0 * highlights_sub[red]); red = FMax(0,FMin(0xFF,red)); green += (int)( 0.0 * shadows_sub[green] + value * midtones_add[green] + 0.0 * highlights_sub[green]); green = FMax(0,FMin(0xFF,green)); blue += (int)( 0.0 * shadows_sub[blue] + value * midtones_add[blue] + 0.0 * highlights_sub[blue]); blue = FMax(0,FMin(0xFF,blue)); r_lookup[i] = (unsigned char)red; g_lookup[i] = (unsigned char)green; b_lookup[i] = (unsigned char)blue; } for (int row = 0; row < bitmap.rows; row++) { for (int col = 0; col < bitmap.cols; col++) { bitmap.at<Vec3b>(row, col)[0] = b_lookup[bitmap.at<Vec3b>(row, col)[0]]; bitmap.at<Vec3b>(row, col)[1] = g_lookup[bitmap.at<Vec3b>(row, col)[1]]; bitmap.at<Vec3b>(row, col)[2] = r_lookup[bitmap.at<Vec3b>(row, col)[2]]; } }}
附上磨皮加美白的效果图
由于本文算法未对皮肤进行检测,所以美白对象为整张图,效果可能不是很好,有兴趣的可自行加上肤色检测
PS:磨皮加美白完整代码点这里
参考:
图像编辑之色彩平衡
皮肤检测算法三种,示例与代码
Opencv之人脸肤色检测总结
1 0
- QT5+OpenCV美白效果
- QT5+OpenCV磨皮效果
- Qt5 for android + opencv
- Qt5 for android + opencv
- windows7 + Qt5 + opencv配置
- Qt5配置opencv注意事项
- Qt5 for android + opencv
- Qt5+OpenCV软件打包
- opencv+Qt5 知识点
- iOS OpenCV 图像美白处理
- 什么水果美白效果好
- Opencv+ qt5.1 完美配置
- QT5.3 +opencv +vs2010 配置,
- QT5.4.0配置OpenCV环境
- QT5+OpenCV人脸识别
- Qt5+opencv程序打包发布
- QT5.5.1+VS2013+OpenGL+OpenCV
- VS2012-QT5-OPENCV环境搭建
- Redis
- (有码)Block模式实现导航控制器页面传值
- 【第一行代码】Android系统架构
- Markdown简单实例教程
- 使用 Spring Data JPA 简化 JPA 开发
- QT5+OpenCV美白效果
- [android]_[初级][插入短信数据到短信数据库]
- Storm架构
- Linux内核调试工具: Crash - 调试page cache的新工具
- HDOJ 5611-Baby Ming and phone number【模拟】
- HDU(1301)最小生成树
- cocos中ProgressTimer,进度条
- IOS之c语言笔记 day04
- jQuery Validate验证框架详解