Преобразование плоскости(изображения) называется аффинным, если оно взаимно однозначно и образом любой прямой является прямая.
Взаимно однозначное преобразование, переводит каждую точку плоскости(изображения) I в другую точку плоскости(изображения) I', таким образом, что каждой точке I соответствует какая-то точка I'.
Примеры аффинных преобразований:
* обычное движение — фактически движение является параллельным переносом
* повороты
* растяжения или сжатия относительно прямой
Для осуществления аффинных преобразований, обычно используется матрица перехода.
В OpenCV аффинные преобразования осуществляются функцией cvWarpAffine():
— применение аффинной трансформации
src — исходное изображение
dst — целевое изображение
map_matrix — матрица трансформации 2х3
flags — комбинация флагов метода интерполяции и флагов:
CV_WARP_FILL_OUTLIERS — заполнить все пиксели целевого изображения (если пиксели отсутствуют на исходном изображени используются fillval) CV_WARP_INVERSE_MAP — используется обратная трансформация из dst в src
fillval — значение для заполнения пикселей вне исходного изображения
dst(x', y') = src(x; y)
Важным параметром функции cvWarpAffine() является map_matrix — матрица трансформации.
Сгенерировать эту матрицу можно с помощью двух методов — cvGetAffineTransform() или cv2DRotationMatrix():
— рассчитывает аффинную матрицу 2D-вращения
center — центр вращения на исходном изображении
angle — угол поворота в гардусах (положительная величина означает вращение против часовой стрелки)
scale — масштаб
map_matrix — указатель на получаемую матрицу 2х3
a b (1 - a)*center.x - b*center.y
b-1 a center.x - (1 - a)*center.y
, где
a = scale - cos(angle)
b = scale - sin(angle)
Пример программы, которая выполняет 2 аффинных преобразования — сначала по матрице, полученной из 3 пар точек, а затем по сгенерированной матрице вращения (поворот вокруг центра изображения на 60 градусов по часовой стрелке с масштабом 0.7).
//
// модифицированный пример Example 6-2. Аффинные трансформации
//
// из книги:
// Learning OpenCV: Computer Vision with the OpenCV Library
// by Gary Bradski and Adrian Kaehler
// Published by O'Reilly Media, October 3, 2008
//
// http://robocraft.ru
//
#include <cv.h>
#include <highgui.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
IplImage *src=0, *dst=0;
// имя картинки задаётся первым параметром
char* filename = argc == 2 ? argv[1] : "Image0.jpg";
// получаем картинку
src = cvLoadImage(filename,1);
printf("[i] image: %s\n", filename);
assert( src != 0 );
// покажем изображение
cvNamedWindow( "image", 1 );
cvShowImage( "image", src );
CvPoint2D32f srcTri[3], dstTri[3];
// матрицы трансформации
CvMat* rot_mat = cvCreateMat(2, 3, CV_32FC1);
CvMat* warp_mat = cvCreateMat(2, 3, CV_32FC1);
// клонируем изображение
dst = cvCloneImage(src);
#if 1
//
// трансформация по точкам
//
// по заданным точкам
// вычислим матрицу преобразования
srcTri[0].x = 0; //src Top left
srcTri[0].y = 0;
srcTri[1].x = src->width - 1; //src Top right
srcTri[1].y = 0;
srcTri[2].x = 0; //src Bottom left
srcTri[2].y = src->height - 1;
//- - - - - - - - - - - - - - -//
dstTri[0].x = src->width*0.0; //dst Top left
dstTri[0].y = src->height*0.33;
dstTri[1].x = src->width*0.85; //dst Top right
dstTri[1].y = src->height*0.25;
dstTri[2].x = src->width*0.15; //dst Bottom left
dstTri[2].y = src->height*0.7;
// получаем матрицу
cvGetAffineTransform(srcTri,dstTri,warp_mat);
// выполняем трансформацию
cvWarpAffine(src,dst,warp_mat);
#endif
// сохраним результат трансформации
cvCopy(dst, src);
#if 1
//
// поворот изображения
//
// рассчёт матрицы вращения
CvPoint2D32f center = cvPoint2D32f(src->width/2, src->height/2);
double angle = -60.0; // на 60 градусов по часовой стрелке
double scale = 0.7; // масштаб
cv2DRotationMatrix(center,angle,scale,rot_mat);
// выполняем вращение
cvWarpAffine(src, dst, rot_mat);
#endif
// показываем
cvNamedWindow( "cvWarpAffine");
cvShowImage( "cvWarpAffine", dst );
// ждём нажатия клавиши
cvWaitKey(0);
// освобождаем ресурсы
cvReleaseMat(&rot_mat);
cvReleaseMat(&warp_mat);
cvReleaseImage(&src);
cvReleaseImage(&dst);
// удаляем окна
cvDestroyAllWindows();
return 0;
}
— применение перспективной трансформации изображения
src — исходное изображение
dst — целевое изображение
map_matrix — матрица трансформации 3х3
flags — комбинация флагов метода интерполяции и флагов:
CV_WARP_FILL_OUTLIERS — заполнить все пиксели целевого изображения (если пиксели отсутствуют на исходном изображени используются fillval) CV_WARP_INVERSE_MAP — используется обратная трансформация из dst в src
fillval — значение для заполнения пикселей вне исходного изображения
— применяет базовую геометрическую трансформацию, используя специальную координатную карту
формула:
dst(x, y) = src(mapx(x, y), mapy(x, y))
src — исходное изображение
dst — целевое изображение
mapx — карта координат по x (изображение типа 32FC1)
mapy — карта координат по y (изображение типа 32FC1)
flags — флаг — комбинация флагов метода интерполяции и следующего флага:
#define CV_WARP_FILL_OUTLIERS 8
CV_WARP_FILL_OUTLIERS — заполнить все пиксели целевого изображения (если пиксели отсутствуют на исходном изображени используются fillval)
fillval — значение для заполнения пикселей вне исходного изображения
Подсажите плис:
Когда мы сделали преобразование — каким способом возможно «перспективное» перемещение, т.е. наблюдатель находится в состоянии покоя, а картинка перемещается (например как в навигационных картах при движении)?
Комментарии (10)
RSS свернуть / развернутьtipabot
korvova
basek
noonv
basek
basek
tubsids
А как получить изображение из кадра с FISH EYE в панорамную картинку?
Спасбо
tubsids
Когда мы сделали преобразование — каким способом возможно «перспективное» перемещение, т.е. наблюдатель находится в состоянии покоя, а картинка перемещается (например как в навигационных картах при движении)?
tubsids
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.