Изменение размеров изображения
Для изменения размеров изображения можно воспользоваться следующими функциями библиотеки IPL:
void iplZoom(IplImage* srcImage, IplImage* dstImage, int xDst, int xSrc, int yDst, int ySrc, int interpolate); // растягивает или увеличивает изображение
void iplDecimate(IplImage* srcImage, IplImage* dstImage, int xDst, int xSrc, int yDst, int ySrc, int interpolate); // сжимает или уменьшает изображение
void iplResize(IplImage* srcImage, IplImage* dstImage, int xDst, int xSrc, int yDst, int ySrc, int interpolate); // изменяет размеры изображения
void iplDecimateBlur (IplImage* srcImage, IplImage* dstImage, int xDst, int xSrc, int yDst, int ySrc, int interpolate, int xMaskSize, int yMaskSize); // уменьшает и размывает изображение
Как видите, эти функции имеют почти одинаковые наборы аргументов, где:
IplImage* srcImage; // указатель на исходное изображение
IplImage* dstImage; // указатель на изображение, в котором функция должна сохранить результат
Положительные целочисленные аргументы xDst и xSrc определяют коэффициент масштабирования по x, который равен отношению xDst/xSrc , а yDst и ySrc – коэффициент масштабирования по y, равный отношению yDst/ySrc .
Для увеличения изображения в два раза в каждом направлении можно воспользоваться функцией iplZoom . Аргументы xDst , xSrc , yDst и ySrc при вызове этой функции должны иметь следующие значения: xDst=2 , xSrc=1 , yDst=2 и ySrc=1 (Рис. 1). В этой функции отношения xDst/xSrc и yDst/ySrc должны быть больше либо равны 1, иначе во время выполнения библиотека выдаст сообщение об ошибке (Рис. 2).
Рис. 1. Действие функции iplZoom с аргументами xDst=2 , xSrc=1 , yDst=2 и ySrc=1
Рис. 2. Сообщение об ошибке в функции iplZoom .
Для уменьшения изображения в два раза в каждом направлении можно воспользоваться функцией iplDecimate или функцией iplDecimateBlur . Аргументы xDst , xSrc , yDst и ySrc при вызове этой функции должны иметь следующие значения: xDst=1 , xSrc=2 , yDst=1 и ySrc=2 (Рис. 3). В этих функциях отношения xDst/xSrc и yDst/ySrc должны быть меньше либо равны 1, иначе во время выполнения библиотека выдаст сообщение об ошибке (Рис. 4).
Рис. 3. Действие функции iplDecimate с аргументами xDst=1 , xSrc=2 , yDst=1 и ySrc=2
Рис. 4. Сообщение об ошибке в функции iplDecimate
Функция iplResize позволяет увеличивать изображение в одном направлении и уменьшать в другом. Например, для увеличения изображения в полтора раза в направлении x и одновременного уменьшения в полтора раза в направлении y аргументам: xDst , xSrc , yDst и ySrc необходимо присвоить следующие значения: xDst=3 , xSrc=2 , yDst=2 и ySrc=3 (Рис. 5). Таким образом, коэффициенты масштабирования по x и по y могут принимать любые значения, которые выражаются дробями xDst/xSrc и yDst/ySrc .
Рис. 5. Действие функции iplResize с аргументами xDst=3 , xSrc=2 , yDst=2 и ySrc=3 .
Последний целочисленный аргумент interpolate определяет метод интерполяции, который будет использоваться при вычислении неизвестных значений пикселов изображения в процессе изменения его размеров. Этот аргумент задаётся с помощью одной из трех констант:
IPL_INTER_NN; // определение неизвестных значений по ближайшему соседнему пикселу
IPL_INTER_LINEAR; // определение неизвестных значений с использованием линейной интерполяции
IPL_INTER_CUBIC; // определение неизвестных значений с использованием кубической интерполяции
На рисунке 6 представлен результат работы iplZoom в различных режимах интерполирования. При определении неизвестных значений по ближайшему соседнему пикселу на изображении образуются заметные прямоугольные области пикселов, имеющих одинаковый цвет. В изображении, увеличенном с использованием кубической интерполяции, отконтрастировались мелкие дефекты. Использование линейной интерполяции позволило получить увеличенное изображение с наилучшим визуальным качеством.
Рис. 6. Действие функции iplZoom в различных режимах интерполирования
Функция iplDecimateBlur требует задания двух дополнительных целочисленных аргументов xMaskSize и yMaskSize , которые определяют размер маски размытия. На рисунке 7 для сравнения представлены результаты уменьшения изображения выполненные с использованием функций iplDecimate и iplDecimateBlur . Изображение, полученное с помощью функции iplDecimateBlur , – визуально более "гладкое", но заметна тёмная рамка, которая является результатом процедуры фильтрации.
Рис. 7. Действие функции iplDecimate с аргументами xDst=1 , xSrc=2 , yDst=1 и ySrc=2
При выполнении изменений размеров изображения можно воспользоваться макроопределениями iplZoomFit , iplDecimateFit и iplResizeFit , предоставляемыми библиотекой IPL. Макроопределения при нимяют всего три аргумента: указатель на исходное изображение srcImage , указатель на изображение dstImage , в котором будет сохранен результат преобразований, и целочисленный аргумент interpolate , определяющий метод интерполирования. Коэффициенты масштабирования в этих макроопределениях вычисляются исходя из размеров изображений srcImage и dstImage .
В прикладных программах обработки изображений результат преобразований часто необходимо поместить на место исходного изображения. Если в функции геометрических преобразований попытаться передать в качестве указателя на результат указатель на исходное изображение, то во время выполнения библиотека выдаст сообщение об ошибке (Рис. 8).
Рис. 8. Сообщение об ошибке в функции не выполняющей преобразование по месту
Для организации выполнения преобразований по месту необходимо выполнить следующие действия:
- Создать временное изображение требуемого размера.
- Выполнить преобразование исходного изображения и записать результат во временное изображение.
- Удалить исходное изображение.
- Скопировать временное изображение на место исходного.
- Удалить временное изображение.
Для примера эти действия реализованы в функции ZoomImage , которая предназначена для пропорционального увеличения или уменьшения изображения и принимает два аргумента: указатель на преобразуемое изображение img и коэффициент масштабирования scale . Для преобразования изображений в функции ZoomImage используются макроопределения iplZoomFit и iplDecimateFit .
void ZoomImage(IplImage* img, double scale)
{
// Создать временное изображения с измененным размером
IplImage* tmp = iplCreateImageHeader(3, 0, IPL_DEPTH_8U, "RGB", "BGR",
IPL_DATA_ORDER_PIXEL, IPL_ORIGIN_BL, IPL_ALIGN_DWORD,
img->width*scale, img->height*scale,
NULL, NULL, NULL, NULL);
// Занять память под временное изображение
iplAllocateImage(tmp, 0, 0);
if(scale > 1.)
{
// Выполнить увеличение изображения
iplZoomFit(img, tmp, IPL_INTER_LINEAR);
}
else
{
// Выполнить уменьшение изображения
iplDecimateFit(img, tmp, IPL_INTER_LINEAR);
}
// Освободить память исходного изображения
iplDeallocate(img, IPL_IMAGE_ALL);
// Скопировать результат в исходное изображение
img=iplCloneImage(tmp);
// Освободить память временного изображения
iplDeallocate(tmp, IPL_IMAGE_ALL);
}
|