private void YCbCrToRGB() { progressLabel.Text = "Converting ycbcr to rgb..."; progressLabel.Visible = true; progressBar.Value = 0; progressBar.Visible = true; // needed to update UI this.Update(); for (int i = 0; i < tempImages.Length; i++) { Bitmap bitmap = new Bitmap(tempImages[i].width, tempImages[i].height); for (int x = 0; x < tempImages[i].width; x++) { for (int y = 0; y < tempImages[i].height; y++) { // Color conversion values from // https://www.renesas.com/eu/en/www/doc/application-note/an9717.pdf YCbCrPixel pixel = tempImages[i].GetPixel(x, y); int r = (int)(1.164 * (pixel.getY() - 16) + 1.596 * (pixel.getCr() - 128)); int g = (int)(1.164 * (pixel.getY() - 16) - 0.813 * (pixel.getCr() - 128) - 0.392 * (pixel.getCb() - 128)); int b = (int)(1.164 * (pixel.getY() - 16) + 2.017 * (pixel.getCb() - 128)); // safety mechanism getValidRGBValue(r, out r); getValidRGBValue(g, out g); getValidRGBValue(b, out b); Color color = Color.FromArgb(r, g, b); bitmap.SetPixel(x, y, color); } } outputImages[i] = bitmap; progressBar.Value = i; if (i % keyFrameEvery == 0) { GC.Collect(); } } progressLabel.Visible = false; progressBar.Visible = false; // needed to update UI this.Update(); }
//create a matrix containing only Y, Cb or Cr values public double[,] FillValueMatrix(YCbCrImage image, String channelString) { double[,] valueMatrix = null; // only save every Nth pixel depending on subsampling mode / channel string if (subsamplingMode == "4:4:4" || channelString == "Y") { valueMatrix = new double[image.width, image.height]; for (int height = 0; height < image.height; height++) { for (int width = 0; width < image.width; width++) { YCbCrPixel pixel = image.GetPixel(width, height); switch (channelString) { case "Y": valueMatrix[width, height] = pixel.getY(); break; case "Cb": valueMatrix[width, height] = pixel.getCb(); break; case "Cr": valueMatrix[width, height] = pixel.getCr(); break; default: break; } } } } else if (subsamplingMode == "4:2:2") { valueMatrix = new double[image.width / 2, image.height]; for (int height = 0; height < image.height; height++) { for (int width = 0; width < image.width; width += 2) { YCbCrPixel pixel = image.GetPixel(width, height); switch (channelString) { case "Cb": valueMatrix[width / 2, height] = pixel.getCb(); break; case "Cr": valueMatrix[width / 2, height] = pixel.getCr(); break; default: break; } } } } else if (subsamplingMode == "4:2:0") { valueMatrix = new double[image.width / 2, image.height / 2]; for (int height = 0; height < image.height; height += 2) { for (int width = 0; width < image.width; width += 2) { YCbCrPixel pixel = image.GetPixel(width, height); switch (channelString) { case "Cb": valueMatrix[width / 2, height / 2] = pixel.getCb(); break; case "Cr": valueMatrix[width / 2, height / 2] = pixel.getCr(); break; default: break; } } } } return(valueMatrix); }