//白平衡算法,灰度世界算法 preset色溫算法
enum WB_PRESET { //自動白平衡 AUTO, //陰天 7500k CLOUDY, //日光 6500k DAYLIGHT, //白熱光 5000k INCANDESCENCE, //日光燈 4400k FLUORESCENT, //鎢絲燈 2800k TUNGSTEN, };
void GrayWorld(Image<Bgr, Byte> img, WB_PRESET preset) { int avgR = 0, avgG = 0, avgB = 0; int sumR = 0, sumG = 0, sumB = 0; for (int h = 0; h < img.Height; ++h) { for (int w = 0; w < img.Width; ++w) { sumB += img.Data[h, w, 0]; sumG += img.Data[h, w, 1]; sumR += img.Data[h, w, 2]; } } int size = img.Height * img.Width; avgB = sumB / size; avgG = sumG / size; avgR = sumR / size; //double k = (avgB + avgG + avgR) / 3; double k = 0.299 * avgR + 0.587 * avgG + 0.114 * avgB; switch (preset) { case WB_PRESET.AUTO: avgR = (sumR / size); avgG = (sumG / size); avgB = (sumB / size); break; case WB_PRESET.CLOUDY: avgR = (int)(sumR * 1.953125 / size); avgG = (int)(sumG * 1.0390625 / size); avgB = (int)(sumB / size); break; case WB_PRESET.DAYLIGHT: avgR = (int)(sumR * 1.2734375 / size); avgG = (int)(sumG / size); avgB = (int)(sumB * 1.0625 / size); break; case WB_PRESET.INCANDESCENCE: avgR = (int)(sumR * 1.2890625 / size); avgG = (int)(sumG / size); avgB = (int)(sumB * 1.0625 / size); break; case WB_PRESET.FLUORESCENT: avgR = (int)(sumR * 1.1875 / size); avgG = (int)(sumG / size); avgB = (int)(sumB * 1.3125 / size); break; case WB_PRESET.TUNGSTEN: avgR = (int)(sumR / size); avgG = (int)(sumG * 1.0078125 / size); avgB = (int)(sumB * 1.28125 / size); break; default: break; } double kr = k / avgR; double kg = k / avgG; double kb = k / avgB; double newB, newG, newR; for (int h = 0; h < img.Height; ++h) { for (int w = 0; w < img.Width; ++w) { newB = img.Data[h, w, 0] * kb; newG = img.Data[h, w, 1] * kg; newR = img.Data[h, w, 2] * kr; img.Data[h, w, 0] = (byte)(newB > 255 ? 255 : newB); img.Data[h, w, 1] = (byte)(newG > 255 ? 255 : newG); img.Data[h, w, 2] = (byte)(newR > 255 ? 255 : newR); } } }