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]]; } } }
附上磨皮加美白的效果图