Как я могу определить цвет букв на этих изображениях?

Я использую эту статью, чтобы решить капчи. Он работает, удаляя фон с изображения с помощью AForge, а затем применяя оптический анализ Тессеракта к полученному очищенному изображению.

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

Как я могу определить цвет букв?

Изображение с буквами в нем

Изображение с буквами в нем

2 ответа

Решение

Используя ответ @Robert Harvey♦ Я пошел и разработал тот же код, используя LockBits а также unsafe методы, чтобы улучшить его скорость. Вы должны скомпилировать с включенным флагом "Разрешить небезопасный код". Обратите внимание, что порядок пикселей, возвращаемых из изображения, находится в bgr не rgb формат, и я блокирую растровое изображение, используя формат Format24bppRgb заставить его использовать 3 байта на цвет.

public unsafe Color GetTextColour(Bitmap bitmap)
{
    BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
    try
    {
        const int bytesPerPixel = 3;
        const int red = 2;
        const int green = 1;

        int halfHeight = bitmap.Height / 2;

        byte* row = (byte*)_bitmapData.Scan0 + (halfHeight * _bitmapData.Stride);

        Color startingColour = Color.FromArgb(row[red], row[green], row[0]);
        for (int wi = bytesPerPixel, wc = _bitmapData.Width * bytesPerPixel; wi < wc; wi += bytesPerPixel)
        {
            Color thisColour = Color.FromArgb(row[wi + red], row[wi + green], row[wi]);
            if (thisColour != startingColour)
            {
                return thisColour;
            }
        }

        return Color.Empty; //Or some other default value
    }
    finally
    {
        bitmap.UnlockBits(bitmapData);
    }
}

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

public Color GetTextColor(Bitmap bitmap)
{
    var y = bitmap.Height/2;
    var startingColor = bitmap.GetPixel(0, y);

    for (int x = 1; x < bitmap.Width; x++)
    {
        var thisColor = bitmap.GetPixel(x, y);
        if (thisColor != startingColor)
            return thisColor;
    }
    return null;
}
Другие вопросы по тегам