public static RGB YCbCrToRGB(YCbCr ycbcr) { float r = Math.Max(0.0f, Math.Min(1.0f, (float)(ycbcr.Y + 0.0000 * ycbcr.Cb + 1.4022 * ycbcr.Cr))); float g = Math.Max(0.0f, Math.Min(1.0f, (float)(ycbcr.Y - 0.3456 * ycbcr.Cb - 0.7145 * ycbcr.Cr))); float b = Math.Max(0.0f, Math.Min(1.0f, (float)(ycbcr.Y + 1.7710 * ycbcr.Cb + 0.0000 * ycbcr.Cr))); return(new RGB((byte)(r * 255), (byte)(g * 255), (byte)(b * 255))); }
public static byte[] BayerDemosaic24(int width, int height, ref byte[] pixels24) { int widthPixel = width * 3; byte[] bReturn = new byte[widthPixel * height]; YCbCr[,] yCbCrs = new YCbCr[height, width]; RGB[,] rGBs = new RGB[height, width]; for (int i = 0; i < height; ++i) { int currentLine = i * width * 3; for (int j = 0; j < widthPixel; j += 3) { rGBs[i, j / 3] = new RGB(pixels24[currentLine + j], pixels24[currentLine + j + 1], pixels24[currentLine + j + 2]); yCbCrs[i, j / 3] = SpaceColorConverter.RGBToYCbCr(rGBs[i, j / 3]); } } bool isBColumn = false; bool isBRow = false; bool isBPosition, isRPosition, isGPosition; for (int i = 0; i < height; ++i) { //determine blue row isBRow = i % 2 == 1; for (int j = 0; j < width; j += 3) { if (i < 2 || j < 2 || i > height - 3 || j > width - 3) { continue; } byte r = 0, g = 0, b = 0; //determine blue column isBColumn = (j / 3) % 2 == 1; //determine position if (isBColumn && isBRow) { isBPosition = true; isRPosition = isGPosition = false; } else if (!isBColumn && !isBRow) { isRPosition = true; isBPosition = isGPosition = false; } else { isGPosition = true; isRPosition = isBPosition = false; } //Built 8 case if (isRPosition) { //G at R position //Get Chroma float cbG = (yCbCrs[i - 1, j].Cb + yCbCrs[i + 1, j].Cb + yCbCrs[i, j - 1].Cb + yCbCrs[i, j + 1].Cb) / 4.0f; float crG = (yCbCrs[i - 1, j].Cr + yCbCrs[i + 1, j].Cr + yCbCrs[i, j - 1].Cr + yCbCrs[i, j + 1].Cr) / 4.0f; //Get Luminance float yG = (4 * yCbCrs[i, j].Y + 2 * (yCbCrs[i - 1, j].Y + yCbCrs[i + 1, j].Y + yCbCrs[i, j - 1].Y + yCbCrs[i, j + 1].Y) - (yCbCrs[i - 2, j].Y + yCbCrs[i + 2, j].Y + yCbCrs[i, j - 2].Y + yCbCrs[i, j + 2].Y)) / 8; g = SpaceColorConverter.YCbCrToRGB(new YCbCr(yG, cbG, crG)).G; //B at red in R row R column //Get Chroma float cbB = (yCbCrs[i - 1, j - 1].Cb + yCbCrs[i + 1, j - 1].Cb + yCbCrs[i - 1, j + 1].Cb + yCbCrs[i + 1, j + 1].Cb) / 4.0f; float crB = (yCbCrs[i - 1, j - 1].Cr + yCbCrs[i + 1, j - 1].Cr + yCbCrs[i - 1, j + 1].Cr + yCbCrs[i + 1, j + 1].Cr) / 4.0f; //Get Luminance float yB = (6 * yCbCrs[i, j].Y + 2 * (yCbCrs[i - 1, j - 1].Y + yCbCrs[i + 1, j - 1].Y + yCbCrs[i - 1, j + 1].Y + yCbCrs[i + 1, j + 1].Y) - 3 / 2 * (yCbCrs[i - 2, j].Y + yCbCrs[i + 2, j].Y + yCbCrs[i, j - 2].Y + yCbCrs[i, j + 2].Y)) / 20; b = SpaceColorConverter.YCbCrToRGB(new YCbCr(yB, cbB, crB)).B; r = SpaceColorConverter.YCbCrToRGB(yCbCrs[i, j]).R; } if (isGPosition) { if (isBRow) { //R at green in B row R column //Get Chroma float cbR = (yCbCrs[i, j - 1].Cb + yCbCrs[i, j + 1].Cb) / 2.0f; float crR = (yCbCrs[i, j - 1].Cr + yCbCrs[i, j + 1].Cr) / 2.0f; //Get Luminance float yR = (5 * yCbCrs[i, j].Y + 4 * (yCbCrs[i, j - 1].Y + yCbCrs[i, j + 1].Y) - (yCbCrs[i - 1, j - 1].Y + yCbCrs[i + 1, j - 1].Y + yCbCrs[i - 1, j + 1].Y + yCbCrs[i - 1, j + 1].Y + yCbCrs[i, j - 2].Y + yCbCrs[i, j + 2].Y) + 1 / 2 * (yCbCrs[i - 2, j].Y + yCbCrs[i + 2, j].Y)) / 8.0f; r = SpaceColorConverter.YCbCrToRGB(new YCbCr(yR, cbR, crR)).R; //B at green in B row R column //Get Chroma float cbB = (yCbCrs[i - 1, j].Cb + yCbCrs[i + 1, j].Cb) / 2.0f; float crB = (yCbCrs[i - 1, j].Cr + yCbCrs[i + 1, j].Cr) / 2.0f; //Get Luminance float yB = (5 * yCbCrs[i, j].Y + 4 * (yCbCrs[i - 1, j].Y + yCbCrs[i + 1, j].Y) - (yCbCrs[i - 1, j - 1].Y + yCbCrs[i + 1, j - 1].Y + yCbCrs[i - 1, j + 1].Y + yCbCrs[i - 1, j + 1].Y + yCbCrs[i, j - 2].Y + yCbCrs[i, j + 2].Y) + 1 / 2 * (yCbCrs[i - 2, j].Y + yCbCrs[i + 2, j].Y)) / 8.0f; b = SpaceColorConverter.YCbCrToRGB(new YCbCr(yB, cbB, crB)).B; g = SpaceColorConverter.YCbCrToRGB(yCbCrs[i, j]).G; } else { //R at green in R row B column //Get Chroma float cbR = (yCbCrs[i - 1, j].Cb + yCbCrs[i + 1, j].Cb) / 2.0f; float crR = (yCbCrs[i - 1, j].Cr + yCbCrs[i + 1, j].Cr) / 2.0f; //Get Luminance float yR = (5 * yCbCrs[i, j].Y + 4 * (yCbCrs[i - 1, j].Y + yCbCrs[i + 1, j].Y) - (yCbCrs[i - 1, j - 1].Y + yCbCrs[i + 1, j - 1].Y + yCbCrs[i - 1, j + 1].Y + yCbCrs[i - 1, j + 1].Y + yCbCrs[i, j - 2].Y + yCbCrs[i, j + 2].Y) + 1 / 2 * (yCbCrs[i - 2, j].Y + yCbCrs[i + 2, j].Y)) / 8.0f; r = SpaceColorConverter.YCbCrToRGB(new YCbCr(yR, cbR, crR)).R; //B at green in R row B column //Get Chroma float cbB = (yCbCrs[i, j - 1].Cb + yCbCrs[i, j + 1].Cb) / 2.0f; float crB = (yCbCrs[i, j - 1].Cr + yCbCrs[i, j + 1].Cr) / 2.0f; //Get Luminance float yB = (5 * yCbCrs[i, j].Y + 4 * (yCbCrs[i, j - 1].Y + yCbCrs[i, j + 1].Y) - (yCbCrs[i - 1, j - 1].Y + yCbCrs[i + 1, j - 1].Y + yCbCrs[i - 1, j + 1].Y + yCbCrs[i - 1, j + 1].Y + yCbCrs[i, j - 2].Y + yCbCrs[i, j + 2].Y) + 1 / 2 * (yCbCrs[i - 2, j].Y + yCbCrs[i + 2, j].Y)) / 8.0f; b = SpaceColorConverter.YCbCrToRGB(new YCbCr(yB, cbB, crB)).B; g = SpaceColorConverter.YCbCrToRGB(yCbCrs[i, j]).G; } } if (isBPosition) { //G at B position float cbG = (yCbCrs[i - 1, j].Cb + yCbCrs[i + 1, j].Cb + yCbCrs[i, j - 1].Cb + yCbCrs[i, j + 1].Cb) / 4.0f; float crG = (yCbCrs[i - 1, j].Cr + yCbCrs[i + 1, j].Cr + yCbCrs[i, j - 1].Cr + yCbCrs[i, j + 1].Cr) / 4.0f; //Get Luminance float yG = (4 * yCbCrs[i, j].Y + 2 * (yCbCrs[i - 1, j].Y + yCbCrs[i + 1, j].Y + yCbCrs[i, j - 1].Y + yCbCrs[i, j + 1].Y) - (yCbCrs[i - 2, j].Y + yCbCrs[i + 2, j].Y + yCbCrs[i, j - 2].Y + yCbCrs[i, j + 2].Y)) / 8; g = SpaceColorConverter.YCbCrToRGB(new YCbCr(yG, cbG, crG)).G; //R at blue in B row B column //Get Chroma float cbR = (yCbCrs[i - 1, j - 1].Cb + yCbCrs[i + 1, j - 1].Cb + yCbCrs[i - 1, j + 1].Cb + yCbCrs[i + 1, j + 1].Cb) / 4.0f; float crR = (yCbCrs[i - 1, j - 1].Cr + yCbCrs[i + 1, j - 1].Cr + yCbCrs[i - 1, j + 1].Cr + yCbCrs[i + 1, j + 1].Cr) / 4.0f; //Get Luminance float yR = (6 * yCbCrs[i, j].Y + 2 * (yCbCrs[i - 1, j - 1].Y + yCbCrs[i + 1, j - 1].Y + yCbCrs[i - 1, j + 1].Y + yCbCrs[i + 1, j + 1].Y) - 3 / 2 * (yCbCrs[i - 2, j].Y + yCbCrs[i + 2, j].Y + yCbCrs[i, j - 2].Y + yCbCrs[i, j + 2].Y)) / 20; r = SpaceColorConverter.YCbCrToRGB(new YCbCr(yR, cbR, crR)).R; b = SpaceColorConverter.YCbCrToRGB(yCbCrs[i, j]).B; rGBs[i, j] = new RGB(r, g, b); } rGBs[i, j] = new RGB(r, g, b); } } for (int i = 0; i < height; ++i) { int currentLine = i * width * 3; for (int j = 0; j < widthPixel; j += 3) { bReturn[currentLine + j] = rGBs[i, j / 3].R; bReturn[currentLine + j + 1] = rGBs[i, j / 3].G; bReturn[currentLine + j + 2] = rGBs[i, j / 3].B; } } return(bReturn); }
public bool Equals(YCbCr ycbcr) { return((this.Y == ycbcr.Y) && (this.Cb == ycbcr.Cb) && (this.Cr == ycbcr.Cr)); }