public static double[] AutoWhiteBalance(this PixelByte p) { double Gr = p.TrimBayer(0, 0).Med(); double Gb = p.TrimBayer(1, 1).Med(); double R = p.TrimBayer(1, 0).Med(); double B = p.TrimBayer(0, 1).Med(); return(new double[] { (Gr + Gb) / (2 * R), 1.0, (Gr + Gb) / (2 * B) }); }
public static Bitmap DemosaicingTest(this PixelByte p, double[] gain, double[,] matrix, double gamma, int bayer = 0) { #region 初期化 int s = p.Size; int h = p.Height; int w = p.Width; byte[] buf = new byte[s * 3]; double r = 0; double b = 0; double g = 0; Bitmap bit = new Bitmap(w, h, PixelFormat.Format24bppRgb); BitmapData bmpdat = bit.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); #endregion #region byte配列化 //RGB信号作成(8x8) int x = 0; int y = 0; #region ベイヤ補間/一階調 double gain_r = gain[0] / 9 / 255; double gain_g = gain[1] / 18 / 255; double gain_b = gain[2] / 9 / 255; Action FucA = () => { r = (p[x + 1, y + 0] + p[x + 3, y + 0] + p[x + 5, y + 0] + p[x + 1, y + 2] + p[x + 3, y + 2] + p[x + 5, y + 2] + p[x + 1, y + 4] + p[x + 3, y + 4] + p[x + 5, y + 4]) * gain_r; g = (p[x + 0, y + 0] + p[x + 2, y + 0] + p[x + 4, y + 0] + p[x + 1, y + 1] + p[x + 3, y + 1] + p[x + 5, y + 1] + p[x + 0, y + 2] + p[x + 2, y + 2] + p[x + 4, y + 2] + p[x + 1, y + 3] + p[x + 3, y + 3] + p[x + 5, y + 3] + p[x + 0, y + 4] + p[x + 2, y + 4] + p[x + 4, y + 4] + p[x + 1, y + 5] + p[x + 3, y + 5] + p[x + 5, y + 5] ) * gain_g; b = (p[x + 0, y + 1] + p[x + 2, y + 1] + p[x + 4, y + 1] + p[x + 0, y + 3] + p[x + 2, y + 3] + p[x + 4, y + 3] + p[x + 0, y + 5] + p[x + 2, y + 5] + p[x + 4, y + 5] ) * gain_b; }; Action FucB = () => { r = (p[x + 0, y + 0] + p[x + 2, y + 0] + p[x + 4, y + 0] + p[x + 0, y + 2] + p[x + 2, y + 2] + p[x + 4, y + 2] + p[x + 0, y + 4] + p[x + 2, y + 4] + p[x + 4, y + 4]) * gain_r; g = (p[x + 1, y + 0] + p[x + 3, y + 0] + p[x + 5, y + 0] + p[x + 0, y + 1] + p[x + 2, y + 1] + p[x + 4, y + 1] + p[x + 1, y + 2] + p[x + 3, y + 2] + p[x + 5, y + 2] + p[x + 0, y + 3] + p[x + 2, y + 3] + p[x + 4, y + 3] + p[x + 1, y + 4] + p[x + 3, y + 4] + p[x + 5, y + 4] + p[x + 0, y + 5] + p[x + 2, y + 5] + p[x + 4, y + 5] ) * gain_g; b = (p[x + 1, y + 1] + p[x + 3, y + 1] + p[x + 5, y + 1] + p[x + 1, y + 3] + p[x + 3, y + 3] + p[x + 5, y + 3] + p[x + 1, y + 5] + p[x + 3, y + 5] + p[x + 5, y + 5] ) * gain_b; }; Action FucC = () => { r = (p[x + 1, y + 1] + p[x + 3, y + 1] + p[x + 5, y + 1] + p[x + 1, y + 3] + p[x + 3, y + 3] + p[x + 5, y + 3] + p[x + 1, y + 5] + p[x + 3, y + 5] + p[x + 5, y + 5]) * gain_r; g = (p[x + 1, y + 0] + p[x + 3, y + 0] + p[x + 5, y + 0] + p[x + 0, y + 1] + p[x + 2, y + 1] + p[x + 4, y + 1] + p[x + 1, y + 2] + p[x + 3, y + 2] + p[x + 5, y + 2] + p[x + 0, y + 3] + p[x + 2, y + 3] + p[x + 4, y + 3] + p[x + 1, y + 4] + p[x + 3, y + 4] + p[x + 5, y + 4] + p[x + 0, y + 5] + p[x + 2, y + 5] + p[x + 4, y + 5] ) * gain_g; b = (p[x + 0, y + 0] + p[x + 2, y + 0] + p[x + 4, y + 0] + p[x + 0, y + 2] + p[x + 2, y + 2] + p[x + 4, y + 2] + p[x + 0, y + 4] + p[x + 2, y + 4] + p[x + 4, y + 4] ) * gain_b; }; Action FucD = () => { r = (p[x + 0, y + 1] + p[x + 2, y + 1] + p[x + 4, y + 1] + p[x + 0, y + 3] + p[x + 2, y + 3] + p[x + 4, y + 3] + p[x + 0, y + 5] + p[x + 2, y + 5] + p[x + 4, y + 5]) * gain_r; g = (p[x + 0, y + 0] + p[x + 2, y + 0] + p[x + 4, y + 0] + p[x + 1, y + 1] + p[x + 3, y + 1] + p[x + 5, y + 1] + p[x + 0, y + 2] + p[x + 2, y + 2] + p[x + 4, y + 2] + p[x + 1, y + 3] + p[x + 3, y + 3] + p[x + 5, y + 3] + p[x + 0, y + 4] + p[x + 2, y + 4] + p[x + 4, y + 4] + p[x + 1, y + 5] + p[x + 3, y + 5] + p[x + 5, y + 5] ) * gain_g; b = (p[x + 1, y + 0] + p[x + 3, y + 0] + p[x + 5, y + 0] + p[x + 1, y + 2] + p[x + 3, y + 2] + p[x + 5, y + 2] + p[x + 1, y + 4] + p[x + 3, y + 4] + p[x + 5, y + 4] ) * gain_b; }; #endregion #region マトリックス Action FuncMatrix = () => { double rr = r; double gg = g; double bb = b; r = matrix[0, 0] * rr + matrix[0, 1] * gg + matrix[0, 2] * bb; g = matrix[1, 0] * rr + matrix[1, 1] * gg + matrix[1, 2] * bb; b = matrix[2, 0] * rr + matrix[2, 1] * gg + matrix[2, 2] * bb; }; #endregion #region ガンマ Action FuncGamma = () => { r = 255 * Math.Pow(r, gamma); g = 255 * Math.Pow(g, gamma); b = 255 * Math.Pow(b, gamma); }; #endregion #region 配列化 int col = 0; Action FuncToByte = () => { //int col = (y * w + x) * 3; buf[col + 2] = (byte)(r < 0 ? 0 : (255 < r ? 255 : r)); buf[col + 1] = (byte)(g < 0 ? 0 : (255 < g ? 255 : g)); buf[col + 0] = (byte)(b < 0 ? 0 : (255 < b ? 255 : b)); }; #endregion Action Func1 = FucA; Action Func2 = FucB; Action Func3 = FucC; Action Func4 = FucD; switch (bayer) { case 0: Func1 = FucA; Func2 = FucB; Func3 = FucC; Func4 = FucD; break; case 1: Func1 = FucB; Func2 = FucA; Func3 = FucD; Func4 = FucC; break; case 2: Func1 = FucC; Func2 = FucD; Func3 = FucA; Func4 = FucB; break; case 3: Func1 = FucD; Func2 = FucC; Func3 = FucB; Func4 = FucA; break; } col = 0; for (y = 0; y < h - 6; y++) { for (x = 0; x < w - 6; x++) { Func1(); FuncMatrix(); FuncGamma(); FuncToByte(); col += 3; x++; Func2(); FuncMatrix(); FuncGamma(); FuncToByte(); col += 3; } col += (3 * 6); y++; for (x = 0; x < w - 6; x++) { Func3(); FuncMatrix(); FuncGamma(); FuncToByte(); col += 3; x++; Func4(); FuncMatrix(); FuncGamma(); FuncToByte(); col += 3; } col += (3 * 6); } #endregion #region BMPにマーシャルコピー/アンロック for (int j = 0; j < h; ++j) { IntPtr dst_line = (IntPtr)((Int64)bmpdat.Scan0 + j * bmpdat.Stride); Marshal.Copy(buf, j * w * 3, dst_line, w * 3); } bit.UnlockBits(bmpdat); #endregion return(bit); }