C# 规范化 RGB 并创建新图像
本文关键字:图像 新图像 创建 规范化 RGB | 更新日期: 2023-09-27 18:36:38
我正在尝试创建一个程序,该程序接受图像,递归地遍历每个像素,规范化像素并重新创建一个看起来与原始图像相同的新图像,但具有规范化像素。
public void parseJpeg(String jpegPath)
{
var normalizedRed = 0.0;
var normalizedGreen = 0.0;
var normalizedBlue = 0.0;
Bitmap normalizedImage = null;
var image = new Bitmap(jpegPath);
normalizedImage = new Bitmap(image.Width, image.Height);
for (int x = 0; x < image.Width; ++x)
{
for (int y = 0; y < image.Height; ++y)
{
Color color = image.GetPixel(x, y);
double exponent = 2;
double redDouble = Convert.ToDouble(color.R);
double blueDouble = Convert.ToDouble(color.B);
double greenDouble = Convert.ToDouble(color.G);
double redResult = Math.Pow(redDouble, exponent);
double blueResult = Math.Pow(blueDouble, exponent);
double greenResult = Math.Pow(greenDouble, exponent);
double totalResult = redResult + blueResult + greenResult;
normalizedRed = Convert.ToDouble(color.R) / Math.Sqrt(totalResult);
normalizedGreen = Convert.ToDouble(color.G) / Math.Sqrt(totalResult);
normalizedBlue = Convert.ToDouble(color.B) / Math.Sqrt(totalResult);
Color newCol = Color.FromArgb(Convert.ToInt32(normalizedRed), Convert.ToInt32(normalizedGreen), Convert.ToInt32(normalizedBlue));
normalizedImage.SetPixel(x, y, newCol);
}
}
normalizedImage.Save("C:''Users''username''Desktop''test1.jpeg");
resultsViewBox.AppendText("Process completed.'n");
}
使用上面的代码会产生所有黑色像素,我不明白为什么。当它规范化时,它会设置 RGB = 1。归一化后,如何使用新的归一化值设置像素?
当我执行以下代码时,我在预览中得到一个黑色和蓝色的图像,但是当我打开文件时它是空白的。这比我以前得到的要好,全是黑色像素。不过,这仅适用于一个图像。所以我不确定它向前迈出了多大一步。
public void parseJpeg(String jpegPath)
{
Bitmap normalizedImage = null;
var image = new Bitmap(jpegPath);
normalizedImage = new Bitmap(image.Width, image.Height);
for (int x = 0; x < image.Width; ++x)
{
for (int y = 0; y < image.Height; ++y)
{
Color color = image.GetPixel(x, y);
float norm = (float)System.Math.Sqrt(color.R * color.R + color.B * color.B + color.G * color.G);
Color newCol = Color.FromArgb(Convert.ToInt32(norm));
normalizedImage.SetPixel(x, y, newCol);
}
}
normalizedImage.Save("C:''Users''username''Desktop''test1.jpeg");
resultsViewBox.AppendText("Process completed.'n");
}
我找到了我想要做的代码:http://www.lukehorvat.com/blog/normalizing-image-brightness-in-csharp/
public void parseJpeg(String jpegPath)
{
var image = new Bitmap(jpegPath);
normalizedImage = new Bitmap(image.Width, image.Height);
for (int x = 0; x < image.Width; ++x)
{
for (int y = 0; y < image.Height; ++y)
{
float pixelBrightness = image.GetPixel(x, y).GetBrightness();
minBrightness = Math.Min(minBrightness, pixelBrightness);
maxBrightness = Math.Max(maxBrightness, pixelBrightness);
}
}
for (int x = 0; x < image.Width; x++)
{
for (int y = 0; y < image.Height; y++)
{
Color pixelColor = image.GetPixel(x, y);
float normalizedPixelBrightness = (pixelColor.GetBrightness() - minBrightness) / (maxBrightness - minBrightness);
Color normalizedPixelColor = ColorConverter.ColorFromAhsb(pixelColor.A, pixelColor.GetHue(), pixelColor.GetSaturation(), normalizedPixelBrightness);
normalizedImage.SetPixel(x, y, normalizedPixelColor);
}
}
normalizedImage.Save("C:''Users''username''Desktop''test1.jpeg");
resultsViewBox.AppendText("Process completed.'n");
}
您正在创建一个新的位图,并为图像中的每个像素保存该文件。 移动
normalizedImage = new Bitmap(image.Width, image.Height);
行到循环之前,以及
normalizedImage.Save("C:''Users''username''Desktop''test1.jpeg");
行到你的循环之后。
您的规范化算法似乎不正确。 假设您的原始颜色是红色 (255,0,0),那么您的totalResult
将是 65025,您的normalizedRed
将是 255/sqrt(65025),即 1,为您提供新的标准化颜色 (1,0,0),本质上是黑色。
请注意,如果您在外观外部定义所有双精度值,然后在循环中分配它们,而不是每次迭代定义和删除 8 个双精度中的每一个,您的代码将运行得更快
与其弄乱颜色,不如使用亮度或亮度因子来实现归一化。这是已经回答的问题的链接,可以帮助您。您可以将每个 RGB 像素转换为 HSL 并缩小 L 因子:
如何规范化图像?
您共享的代码实际上是 HSL 操作的精简版本。