Мне нужно реализовать уменьшение эффекта красных глаз для приложения, над которым я работаю.
Поиск в Google в основном предоставляет ссылки на коммерческие продукты для конечных пользователей.
Знаете ли вы хороший алгоритм уменьшения эффекта красных глаз, который можно было бы использовать в приложении GPL?





Самый простой и очень эффективный алгоритм - обнулить R тройки RGB для интересующей области.
Красный исчезает, но остальные цвета сохраняются.
Дальнейшее расширение этого алгоритма может включать обнуление значения R только для троек, где красный является доминирующим цветом (R> G и R> B).
Если никто другой не предложит более прямого ответа, вы всегда можете скачать исходный код для GIMP и посмотреть, как они это делают.
Вы можете попробовать imagemagick - на этой странице есть несколько советов, как это сделать
http://www.cit.gu.edu.au/~anthony/info/graphics/imagemagick.hints
поиск эффекта красных глаз на странице
Для начала нужно найти глаза! Стандартный способ - запустить детектор краев, а затем преобразование Хафа, чтобы найти два круга одинакового размера, но могут быть более простые алгоритмы для простого поиска кластеров красных пикселей.
Затем вам нужно решить, чем их заменить, при условии, что на изображении достаточно данных зеленого / синего, вы можете просто игнорировать красный канал.
OpenCV - очень хорошая бесплатная библиотека для обработки изображений, она может быть излишней для того, что вы хотите, но имеет много примеров и очень активное сообщество. Вы также можете искать алгоритмы отслеживания объектов, отслеживание цветного объекта в сцене - очень похожая и распространенная проблема.
Проект с открытым исходным кодом Paint.NET имеет реализацию на C#.
Я очень опаздываю на вечеринку, но для будущих искателей я использовал следующий алгоритм для личного приложения, которое я написал.
Прежде всего, область для уменьшения выбирается пользователем и передается методу уменьшения эффекта красных глаз в виде центральной точки и радиуса. Метод перебирает каждый пиксель в пределах радиуса и выполняет следующие вычисления:
//Value of red divided by average of blue and green:
Pixel pixel = image.getPixel(x,y);
float redIntensity = ((float)pixel.R / ((pixel.G + pixel.B) / 2));
if (redIntensity > 1.5f) // 1.5 because it gives the best results
{
// reduce red to the average of blue and green
bm.SetPixel(i, j, Color.FromArgb((pixel.G + pixel.B) / 2, pixel.G, pixel.B));
}
Мне очень нравятся результаты, потому что они сохраняют интенсивность цвета, что означает, что световое отражение глаз не уменьшается. (Это означает, что глаза сохраняют свой «живой» вид.)
Вы также можете использовать инструмент выбора «волшебная палочка» в точке щелчка с максимальным радиусом, предоставленным пользователем.
Вот решение для реализации Java
public void corrigirRedEye(int posStartX, int maxX, int posStartY, int maxY, BufferedImage image) {
for(int x = posStartX; x < maxX; x++) {
for(int y = posStartY; y < maxY; y++) {
int c = image.getRGB(x,y);
int red = (c & 0x00ff0000) >> 16;
int green = (c & 0x0000ff00) >> 8;
int blue = c & 0x000000ff;
float redIntensity = ((float)red / ((green + blue) / 2));
if (redIntensity > 2.2) {
Color newColor = new Color(90, green, blue);
image.setRGB(x, y, newColor.getRGB());
}
}
}
}
Параметры, полученные из двух прямоугольников, обнаруженных приложением, например open cv (это должен быть прямоугольник с указанием положения глаз)
int posStartY = (int) leftEye.getY();
int maxX = (int) (leftEye.getX() + leftEye.getWidth());
int maxY = (int) (leftEye.getY() + leftEye.getHeight());
this.corrigirRedEye(posStartX, maxX, posStartY, maxY, image);
// right eye
posStartX = (int) rightEye.getX();
posStartY = (int) rightEye.getY();
maxX = (int) (rightEye.getX() + rightEye.getWidth());
maxY = (int) (rightEye.getY() + rightEye.getHeight());
this.corrigirRedEye(posStartX, maxX, posStartY, maxY, image);
Это более полная реализация ответа Бенри:
using SD = System.Drawing;
public static SD.Image ReduceRedEye(SD.Image img, SD.Rectangle eyesRect)
{
if ( (eyesRect.Height > 0)
&& (eyesRect.Width > 0)) {
SD.Bitmap bmpImage = new SD.Bitmap(img);
for (int x=eyesRect.X;x<(eyesRect.X+eyesRect.Width);x++) {
for (int y=eyesRect.Y;y<(eyesRect.Y+eyesRect.Height);y++) {
//Value of red divided by average of blue and green:
SD.Color pixel = bmpImage.GetPixel(x,y);
float redIntensity = ((float)pixel.R / ((pixel.G + pixel.B) / 2));
if (redIntensity > 2.2f)
{
// reduce red to the average of blue and green
bmpImage.SetPixel(x, y, SD.Color.FromArgb((pixel.G + pixel.B) / 2, pixel.G, pixel.B));
pixel = bmpImage.GetPixel(x,y); // for debug
}
}
}
return (SD.Image)(bmpImage);
}
return null;
}
Прочтите этот блог, там есть хорошее объяснение относительно обнаружения и коррекции красных глаз. Коррекция красных глаз с помощью OpenCV и Python
Я не думаю, что источник более доступен.