通过cvGetQuadrangleSubPix函数理解来图像的旋转与缩放实现。本节主要介绍相关知识。
函数cvGetQuadrangleSubPix提取像素四边形,并使用子像素精度。
格式:
/* Retrieves quadrangle from the input array. matrixarr = ( a11 a12 | b1 ) dst(x,y) <- src(A[x y]' + b) ( a21 a22 | b2 ) (bilinear interpolation is used to retrieve pixels with fractional coordinates) */ CVAPI(void) cvGetQuadrangleSubPix(const CvArr* src, CvArr* dst,const CvMat* map_matrix);函数参数:
说明:
函数cvGetQuadrangleSubPix提取像素四边形,并使用子像素精度从图像src中提取四边形,并将结果存储于dst,计算公式是:
dst[x + width(dst)/2, y + height(dst)/2] = src[x*A11 + y*A12 + b1, x*A21 + y*A22 + b2]
其中,A 和 b为几何变参数,均来自映射矩阵map_matrix.映射矩阵为
此处,非整数坐标A*(x,y)^T+b的像素点值通达双线插值得到。多通道图像的每一个通道都单独计算。
#include "opencv/cv.h" #include "opencv/highgui.h" int main( int argc, char**argv){ IplImage* pImg = cvLoadImage("test.jpg",1); if(!pImg){ printf("Could not Load File in cvLoadImage(..).\n"); return -1; } IplImage* dst = cvCreateImage(cvGetSize(pImg),pImg->depth,pImg->nChannels); dst = cvCloneImage(pImg); int flags = 1; // 1: rotate and scale // 0: only rotate double factor; float m[6]; // Matrix m looks like: // [ m0 m1 m2 ] ===> [ A11 A12 b1 ] // [ m3 m4 m5 ] ===> [ A21 A22 b2 ] CvMat M = cvMat( 2, 3, CV_32F, m ); nWidth = pImg->width; nHeight = pImg->height; int delta = 1; int angle = 0; while(true){ if(flags){ factor = (cos(angle*CV_PI/180.) + 2.0)*2; // rotate and scale printf("factor:%6f\n",factor); } else factor = 1;// only rotate m[0] = (float)(factor*cos(-angle*2*CV_PI/180.)); m[1] = (float)(factor*sin(-angle*2*CV_PI/180.)); m[3] = -m[1]; m[4] = m[0]; m[2] = nWidth*0.5f; m[5] = nHeight*0.5f; //dst(x,y) = A * src(x,y) + b cvGetQuadrangleSubPix( pImg, dst, &M); cvNamedWindow( "dst"); cvShowImage( "dst", dst ); if( cvWaitKey(10) == 27 ){ cvReleaseImage(&dst); cvDestroyWindow("dst"); break; } angle =(int) (angle + delta) % 360; } return 0; }
某一时刻,当时flags > 0时,输出的图像效果:
而flags = 0 时,输出的图像效果呢?自己动手试试。呵呵呵~~~~
import sys import math if _name_= '_main_': if len(sys.argv) == 2: src = cvLoadImage("test.jpg") if not src: sys.exit(-1) delta = 1; angle = 0; flags = 1; factor = 1; dst = cvCloneImage (src); M = cvCreateMat (2, 3, CV_32F) while True: w = src.width; h = src.height; M[0,0] = factor * math.cos (-angle * 2 * CV_PI / 180.0); M[0,1] = factor * math.sin (-angle * 2 * CV_PI / 180.0); M[1,0] = -M[0,1]; M[1,1] = M[0,0]; M[0,2] = w * 0.5; M[1,2] = h * 0.5; # dst(x,y) = A * src(x,y) + b cvZero (dst); cvGetQuadrangleSubPix (src, dst, M); cvNamedWindow ("dst", 1); cvShowImage ("dst", dst); if cvWaitKey(10) == '0x1b': break angle = (angle + delta) % 360
关于Image Engineering & Computer Vision的更多讨论与交流,敬请关注本博和新浪微博songzi_tea.