Алгоритм сокращения красных глаз
Мне нужно реализовать уменьшение эффекта "красных глаз" для приложения, над которым я работаю.
Googling в основном предоставляет ссылки на коммерческие конечные продукты.
Знаете ли вы хороший алгоритм сокращения красных глаз, который можно использовать в приложении GPL?
Ответы
Ответ 1
Я опоздал на вечеринку, но для будущих искателей я использовал следующий алгоритм для личного приложения, которое я написал.
Прежде всего, область для уменьшения выбирается пользователем и передается методу уменьшения эффекта красных глаз в качестве центральной точки и радиуса. Метод проходит через каждый пиксель в радиусе и выполняет следующий расчет:
//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));
}
Мне очень нравятся результаты этого, потому что они сохраняют интенсивность цвета, а это означает, что световое отражение глаза не уменьшается. (Это означает, что глаза сохраняют "живой" вид.)
Ответ 2
отличная библиотека для поиска глаз openCV.
он очень богат функциями обработки изображений.
см. также этот документ с названием "Автоматическое обнаружение красных глаз" от Илии В. Сафонова.
Ответ 3
Сначала вам нужно найти глаза!
Стандартным способом было бы запустить детектор кромок, а затем преобразование Хафа, чтобы найти два круга одинакового размера, но могут быть более простые алгоритмы для простого поиска кластеров с красными пикселями.
Затем вам нужно решить, что заменить их, если в изображении достаточно зеленых/синих данных, вы можете просто игнорировать красный канал.
OpenCV - очень хорошая бесплатная библиотека для обработки изображений, она может быть излишней для того, что вы хотите - но имеет множество примеров и очень активное сообщество.
Вы также можете искать алгоритмы отслеживания объектов, отслеживание цветного объекта в сцене - очень похожая и общая проблема.
Ответ 4
Если никто больше не приступает к более прямому ответу, вы всегда можете скачать исходный код для GIMP и посмотреть, как они это делают.
Ответ 5
Самый простой алгоритм, и все же тот, который очень эффективен, должен был бы обнулить R тройки RGB для интересующей области.
Красный исчезает, но сохраняются другие цвета.
Дальнейшее расширение этого алгоритма может включать обнуление значения R только для троек, где красный цвет является доминирующим (R > G и R > B).
Ответ 6
Вы можете попробовать imagemagick - некоторые советы на этой странице, как это сделать
http://www.cit.gu.edu.au/~anthony/info/graphics/imagemagick.hints
искать красные глаза на странице
Ответ 7
Проект с открытым исходным кодом Paint.NET имеет реализацию на С#.
Ответ 8
Вот решение для реализации 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);
Ответ 9
Это более полная реализация ответа, предоставленного Бенри:
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;
}
Ответ 10
Прочтите этот блог, есть хорошее объяснение относительно обнаружения и коррекции эффекта красных глаз.
Коррекция красных глаз с помощью OpenCV и python