Рекурсивно выполнять уменьшение эффекта «красных глаз» на изображении в C#

Пример Выполнение эффекта красных глаз на picture в C# исследует пиксели в выбранном прямоугольнике и преобразует любой пиксель, который является более красным, чем зеленый или синий, в оттенки серого. Это устраняет эффект «красных глаз» в области, но также преобразует любые другие красные пиксели в оттенки серого. На картинке лица в этом примере много розоватой кожи. Розовый в основном светлый оттенок красного, поэтому программа преобразует розовую кожу в оттенки серого, если она находится в выбранном прямоугольнике.

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

// Выполнение эффекта «красных глаз», начиная с щелчка.
private void picImage_MouseClick(object sender, MouseEventArgs e)
{
    Bitmap bm = (Bitmap)picImage.Image;
    RemoveRedEyeAtPoint(1, bm, e.X, e.Y);
    picImage.Image = bm;
}

Этот код в основном просто вызывает следующий рекурсивный метод RemoveRedEyeAtPoint, передавая ему точку, которую вы нажали.

// Удаление красных глаз в прямоугольнике.
private void RemoveRedEyeAtPoint(int depth, Bitmap bm, int x, int y)
{
    // Не повторяйте слишком глубоко.
    if (depth > 100) return;

    // Не делайте ничего, если этот пиксель не в основном красный.
    Color clr = bm.GetPixel(x, y);
    if ((clr.R <= clr.G + 10) || (clr.R <= clr.B + 10)) return;
        
    // Удалите красные глаза в этот момент.
    byte new_clr = (byte)((clr.R + clr.G + clr.B) / 3);
    bm.SetPixel(x, y, Color.FromArgb(new_clr, new_clr, new_clr));

    // Проверяем соседние пиксели.
    int min_x = Math.Max(x - 1, 0);
    int max_x = Math.Min(x + 1, bm.Width - 1);
    int min_y = Math.Max(y - 1, 0);
    int max_y = Math.Min(y + 1, bm.Height - 1);
    for (int new_x = min_x; new_x <= max_x; new_x++)
    {
        for (int new_y = min_y; new_y <= max_y; new_y++)
        {
            if ((new_x != 0) || (new_y != 0))
                RemoveRedEyeAtPoint(depth + 1, bm, new_x, new_y);
        }
    }
}

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

Далее код получает цвет своего целевого пикселя. Если этот цвет не является главным образом красным, метод возвращается. В этой версии я добавил небольшое смещение, поэтому красный компонент должен быть как минимум на 10 больше, чем зеленые компоненты синего цвета. Это не позволяет методу преобразовать пиксели, которые в основном серые, но имеют бесконечно красное, чем зеленое или синее.

Если код делает это так далеко, он преобразует целевой пиксель в оттенки серого.

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

Источник: http://csharphelper.com/blog/2015/07/recursively-perform-red-eye-reduction-on-a-picture-in-c/

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Adblock
detector