图像旋转与缩放实现

引言

通过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);
函数参数:

  • src:输入图像
  • dst: 提取的四边形
  • map_matrix: 2X3变换矩阵(见下面说明)

说明:

函数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的像素点值通达双线插值得到。多通道图像的每一个通道都单独计算。

参考代码

OpenCV1.x 版图像旋转与缩放

#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时,输出的图像效果:

图像旋转与缩放实现_第1张图片

而flags = 0 时,输出的图像效果呢?自己动手试试。呵呵呵~~~~

Python版图像旋转与缩放

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.


你可能感兴趣的:(旋转,缩放,opencv)