C# Нормализация RGB и создание нового изображения
Я пытаюсь создать программу, которая принимает изображение, рекурсивно проходит через каждый пиксель, нормализует пиксель и заново создает НОВОЕ изображение, которое выглядит так же, как оригинал, но вместо этого имеет нормализованные пиксели.
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");
}
3 ответа
Вы создаете новое растровое изображение и сохраняете файл для каждого пикселя изображения. Переместить
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.