Вернуться наверх
aco.ifmo.ru photonic
вернуться в оглавление предыдущая глава предыдущий параграф следующий параграф следующая глава


Бинаризация

Простейшим методом препарирования изображений является бинаризация. Это преобразование заключается в превращении изображения в двухцветное черно-белое. Главным параметром такого преобразования является порог – значение, которое будет критерием проверки интенсивности точки изображения. Функция бинаризации представлена на рисунке 1.

Рис. 1. Функция бинаризации

В библиотеке IPL для выполнения бинаризации используется функция iplThreshold, которая имеет следующий прототип:

void iplThreshold(IplImage* srcImage, IplImage* dstImage, int threshold);

где srcImage – указатель на исходное изображение, а dstImage – указатель на изображение, в котором будет сохраняться результат. Аргумент threshold задает пороговое значение. Функция бинаризации может выполняться по месту, то есть ее использование никаких затруднений не вызывает.

Результат выполнения бинаризации с полутоновым изображением представлен на рисунке 2, а с цветным – на рисунке 3.

iplThreshold

Рис. 2. Действие функции iplThreshold с пороговым значением 128

iplThreshold

Рис. 3. Действие функции iplThreshold с пороговым значением 128

Иногда при обработке приходится иметь дело с изображениями, хранимыми как полутоновые, но по своему содержанию мало отличающимися от бинарных. К ним относятся текст, штриховые рисунки, чертежи, изображение отпечатка пальца. Замена исходного полутонового изображения бинарным препаратом решает две основные задачи. Во-первых, достигается большая наглядность при визуальном восприятии, чем у исходного изображения. Во-вторых, ощутимо сокращается объем запоминающего устройства для хранения изображения, поскольку бинарный препарат для записи каждой точки бинарного изображения требует лишь 1 бит памяти, в то время как полутоновое изображение для решения той же задачи при наиболее часто применяемом формате представления - 8 бит.

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

typedef struct _IplLUT
{
    int num; // количество ключевых значений
    int* key; // указатель на массив ключевых значений
    int* value; // указатель на массив значений (либо величина сдвига, либо непосредствено новые значения интенсивности)
    int* factor; // указатель на массив дополнительных множителей
    int interpolateType; // тип преобразования
} IplLUT;

Массив ключевых значений должен иметь размер равный num. Массивы value и factor должны иметь размер num-1. Параметр interpolateType может быть равен IPL_LUT_LOOKUP или IPL_LUT_INTER.

Если тип преобразования IPL_LUT_LOOKUP, то интенсивность исходного изображения D из диапазона key[0] <= D < key[1] после преобразования будет равна значению value[0], из диапазона key[1] <= D < key[2] – value[1] и так далее.

Если тип преобразования IPL_LUT_INTER, то интенсивность исходного изображения D из диапазона key[0] <= D < key[1] после преобразования будет равна значению линейно интерполированному значению: value[0] + [(value[1] – value[0]) / (key[1] – key[0])] * (D – key[0]).

Значение (value[1] – value[0]) / (key[1] – key[0]) соответствует наклону интерполирующей линии в этой точке и должно быть заранее вычислено и сохранено в factor[0]. Формулу, которая используется библиотекой, можно записать так: D_ = value[i] + factor[i] * (D – key[i]).

К сожалению, библиотека IPL не предоставляет никаких функций для созданий и манипулирования структурой IplLUT, поэтому создадим свои:

void CreateLUT(IplLUT* lut)
{
    lut->key = new int[lut->num];
    lut->value = new int[lut->num-1];
    lut->factor = new int[lut->num-1];

    for(int i=0; i<lut->num; i++)
    {
        lut->key[i] = i;
    }
}

void DeleteLUT(IplLUT* lut)
{
    delete [] lut->key;
    delete [] lut->value;
    delete [] lut->factor;
}

Функция для выполнения препарирования изображений может быть реализована следующим образом:

void Preparing(IplImage* img, int type)
{
// Создание lookup-таблиц
    IplLUT lut[3] = {{256 + 1, NULL, NULL, NULL, IPL_LUT_INTER},
        {256+1, NULL, NULL, NULL, IPL_LUT_INTER},
        {256+1, NULL, NULL, NULL, IPL_LUT_INTER}};

// Создание и инициализация массива указателей на lookup-таблицы
    IplLUT* plut[3];
    plut[0] = &lut[0];
    plut[1] = &lut[1];
    plut[2] = &lut[2];

// Инициализация членов lookup-таблиц
    CreateLUT(plut[0]);
    CreateLUT(plut[1]);
    CreateLUT(plut[2]);

    switch(type)
    {
    // Подготовка lookup-таблиц
        ...
    }

// Препарирование
    iplContrastStretch(img, img, plut);

// Удаление членов lookup-таблиц
    DeleteLUT(plut[0]);
    DeleteLUT(plut[1]);
    DeleteLUT(plut[2]);
}

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

void iplComputeHisto(IplImage* srcImage, IplLUT** lut);

где srcImage – изображение для которого будет вычисляться гистограмма, а lut – массив указателей на структуры LUT (один указатель на каждый канал).