Алгоритм уменьшения эффекта красных глаз - PullRequest
41 голосов
/ 25 сентября 2008

Мне нужно реализовать функцию уменьшения эффекта красных глаз для приложения, над которым я работаю.

Googling в основном предоставляет ссылки на коммерческие продукты для конечных пользователей.

Знаете ли вы хороший алгоритм уменьшения эффекта красных глаз, который можно использовать в приложении GPL?

Ответы [ 10 ]

43 голосов
/ 05 апреля 2009

Я опаздываю на вечеринку здесь, но для будущих поисковиков я использовал следующий алгоритм для личного приложения, которое я написал.

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

//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));
}

Мне действительно нравятся результаты этого, потому что они сохраняют интенсивность цвета, что означает, что световое отражение глаза не уменьшается. (Это означает, что глаза сохраняют свой «живой» вид.)

7 голосов
/ 26 сентября 2008

отличная библиотека для поиска глаз openCV . он очень богат функциями обработки изображений. см. также эту бумагу с заголовком «Автоматическое обнаружение красных глаз» от Ильи В. Сафонова.

6 голосов
/ 25 сентября 2008

Сначала нужно найти глаза! Стандартным способом было бы запустить детектор краев, а затем преобразование Хафа, чтобы найти два круга одного и того же размера, но могли бы быть более простые алгоритмы для простого поиска скоплений красных пикселей.

Затем вам нужно решить, чем их заменить, предполагая, что на изображении достаточно зеленых / синих данных, которые вы можете просто игнорировать красный канал.

OpenCV - очень хорошая бесплатная библиотека для обработки изображений, она может быть излишней для того, что вы хотите - но в ней много примеров и очень активное сообщество. Вы также можете искать алгоритмы отслеживания объектов, отслеживание цветного объекта в сцене является очень похожей и обычной проблемой.

4 голосов
/ 25 сентября 2008

Если никто не придет с более прямым ответом, вы всегда можете скачать исходный код для GIMP и посмотреть, как они это делают.

3 голосов
/ 25 сентября 2008

Проект с открытым исходным кодом Paint.NET имеет реализацию на C #.

3 голосов
/ 25 сентября 2008

Вы можете попробовать imagemagick - некоторые советы на этой странице о том, как это сделать

http://www.cit.gu.edu.au/~anthony/info/graphics/imagemagick.hints

поиск эффекта красных глаз на странице

3 голосов
/ 25 сентября 2008

Самый простой и очень эффективный алгоритм - обнуление R тройки RGB для интересующей области.

Красный исчезает, но другие цвета сохраняются.

Дальнейшее расширение этого алгоритма может включать обнуление значения R только для троек, где красный является доминирующим цветом (R> G и R> B).

2 голосов
/ 10 мая 2011

Вот решение для реализации 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);
1 голос
/ 25 сентября 2012

Это более полная реализация ответа, предоставленного Бенри:

  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;
  }
0 голосов
/ 13 апреля 2017

Прочитайте этот блог, есть хорошее объяснение относительно обнаружения и коррекции эффекта красных глаз. Коррекция красных глаз с OpenCV и python

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...