Алгоритм уменьшения эффекта красных глаз

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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
42
0
18 464
10
Перейти к ответу Данный вопрос помечен как решенный

Ответы 10

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

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

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

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

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

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

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

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

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

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

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

Я не думаю, что источник более доступен.

John T 05.04.2009 13:37

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

Ответ принят как подходящий

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

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

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

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

Вы также можете использовать инструмент выбора «волшебная палочка» в точке щелчка с максимальным радиусом, предоставленным пользователем.

rafaelcastrocouto 19.02.2017 16:19

Вот решение для реализации 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

Другие вопросы по теме