Изменение размеров изображения
Для изменения размеров изображения можно воспользоваться следующими функциями библиотеки 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);
}
|