Определите, является ли цветное растровое изображение черно-белым - PullRequest
1 голос
/ 04 ноября 2010

У меня есть HBitmap, который я получаю от API, который я использую для преобразования страниц в документы PDF. Результирующее растровое изображение - 24-битное цветное растровое изображение. Я пытаюсь определить, используя черно-белые отсканированные изображения, которые были преобразованы в PDF, черно-белые на результирующем растровом изображении от Foxit. Foxit - это PDF API. Вот код! (C ++ / CLI)

// Get HBITMAP using Foxit's RenderPage function
// to convert to dib later
IntPtr hbitmap = FlattenPageToHBitmap(filename, page);

if (hbitmap == IntPtr::Zero) 
    return IntPtr::Zero;

Bitmap^ b = Bitmap::FromHbitmap(hbitmap);

bool isColor = false;
for (int y = 0; y < b->Height; y++)
{
    for (int x = 0; x < b->Width; x++)
    {
         Color^ c = b->GetPixel(x, y);
         unsigned int bits = (int)c->ToArgb();
         bits = bits << 8;
         bits = bits >> 8; //should get rid of A in ARGB
         bool white = (bits == 0xFFFFFF);
         bool black = (bits == 0);
         if (!black && !white)
         {
        isColor = true;
        break;
         }
    }

    if (isColor)
         break;
    }
}

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

Проблема

Полученный HBitmap от Foxit никогда не выглядит полностью черным или белым. Есть ли алгоритм, который я могу использовать, чтобы увидеть, достаточно ли он «близок» и преобразовать его? пиксельный формат растрового изображения используется при сохранении его обратно в pdf для определения используемого сжатия.

Ответы [ 4 ]

6 голосов
/ 04 ноября 2010

Конечно, просто рассчитайте яркость и проверьте, действительно ли она близка к нулю или единице.

Color c = b->GetPixel(x, y); // no ^ because Color is a value type
float Y = (0.2126*c.R + 0.7152*c.G + 0.0722*c.B) / 255;
bool white = (Y > .95);
bool black = (Y < .05);
if (!black && !white)
{
    isColor = true;
    break;
}

Использование формулы яркости из Википедии .

Или Y = c.GetBrightness(); также может работать.

4 голосов
/ 04 ноября 2010

Если вы знаете, как получить R, G и B для каждого пикселя, тогда картинка BW должна иметь R == G == B.

Если это не так, и вы хотите, чтобы она была в градациях серого,используйте эту формулу для вычисления новых значений RGB:

value = 0.3 R + 0.59 G + 0.11 B

Заполните R, G и B значением, и все.

1 голос
/ 04 ноября 2010

Несмотря на то, что ответы уже даны, они, похоже, содержат магические числа.Вот общий, более настраиваемый подход на случай, если вам по какой-то странной причине придется использовать RGB (я только что понял, что с HSV / HSL это, конечно, тривиально):

Согласно Википедии , верноСерые цвета - это те, для которых краснота = зеленость = синева, т. е. те цвета на диагонали цветового пространства RGB.Поскольку вы также хотите, чтобы цвета были почти серыми, мы определим цвет как пороговое значение t Neargray для at> = 0, если оно лежит в радиусе t трубчатой ​​окрестности диагонали.Таким образом, чтобы определить, является ли RGB-цвет x порогом t близкого к серому, просто вычислите расстояние r между x и его ортогональной проекцией на диагональ.Если r <= t, то «достаточно серый».Отрегулируйте t по своему вкусу. </p>

1 голос
/ 04 ноября 2010

Вы имеете в виду, что используются цвета, которые являются очень темно-серыми (т.е. по существу черными) или очень светло-серыми (то есть по существу белыми); или вы имеете в виду большинство (но не все) пикселей черного или белого цвета?

Для начала вы можете найти функцию «расстояния». Например. dist = R * R + G * G + B * B. Затем выберите пороговые значения, которые определяют, насколько черный или белый. аналогично, вы можете сказать «черный - это когда R

Что касается пикселей, вы можете подсчитать все пиксели, которые соответствуют порогу, и решить, если порог превышает 80% (скажем), тогда он черный или белый.

...