OpenCV中文网站例程——图像旋转和缩放

来源:互联网 发布:成都知贤科技有限公司 编辑:程序博客网 时间:2024/05/19 13:17

相关知识点参考:http://xiangge2009.blog.sohu.com/147112222.html

首先根据旋转的角度、图象对角线的长度计算旋转后的图像的最大宽度、高度,根据旋转后图象最大的宽度、高度生成新的缓冲区,假设图像的左上角为(left,   top),右下角为(right,   bottom),则图像上任意点(x,   y)绕其中心(xcenter,   ycenter)逆时针旋转angle角度后,新的坐标位置(x1,   y1)的计算公式为:   
    
xcenter = (width+1)/2+left;   
ycenter = (height+1)/2+top;   
x1= (x-xcenter)cosθ-   (y-ycenter)sinθ+xcenter;   
y1= (x-xcenter)sinθ+   (y-ycenter)cosθ+ycenter;   
    
与图像的镜像变换相类似,把原图中的象素值读入新缓冲区的(x1,y1)点处。注意在新缓冲区中与原图没有对应的象素点的值用白色代替。   

GetQuadrangleSubPix

提取象素四边形,使用子象素精度

void cvGetQuadrangleSubPix( const CvArr* src, CvArr* dst, const CvMat* map_matrix );

src    输入图像. 

dst     提取的四边形. 

map_matrix  3 × 2 变换矩阵 [A|b] .

函数 cvGetQuadrangleSubPix 以子象素精度从图像 src 中提取四边形,使用子象素精度,并且将结果存储于 dst ,计算公式是: 

( + () / 2, + () / 2) = (11 + 12 + 1,21 + 22 + 2)

其中 A和 b 均来自映射矩阵(译者注:A, b为几何形变参数) 

其中在非整数坐标的象素点值通过双线性变换得到。当函数需要图像边界外的像素点时,使用重复边界模式(replication border 

mode)恢复出所需的值。多通道图像的每一个通道都单独计算。


例子结果:(图像结果都是动态显示)



例子程序:

#include "cv.h"
#include "highgui.h"
#include "math.h"
int main (int argc, char **argv)
{
  IplImage *src = 0;
  IplImage *dst = 0;
 
  /* the first command line parameter must be image file name */
  if ((src = cvLoadImage ("E://lena.jpg", -1)) != 0)
    {
      int delta = 1;
      int angle = 0;
      int opt = 1; // 1: 旋转加缩放
                        // 0:  仅仅旋转
      double factor;
 
      dst = cvCloneImage (src);
      cvNamedWindow ("src", 1);
      cvShowImage ("src", src);
 
      for (;;)
{
 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);
 int w = src->width;
 int h = src->height;
 if (opt) // 旋转加缩放
   factor = (cos (angle * CV_PI / 180.) + 1.0) * 2;
 else //  仅仅旋转
   factor = 1;
 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] = w * 0.5f;
 m[5] = h * 0.5f;
 //  dst(x,y) = A * src(x,y) + b
 cvZero (dst);
 cvGetQuadrangleSubPix (src, dst, &M);
 cvNamedWindow ("dst", 1);
 cvShowImage ("dst", dst);
 if (cvWaitKey (1) == 27)//ESC
   break;
 angle = (int) (angle + delta) % 360;   //旋转角度变换步长为1
} // for-loop
    }
  return 0;
}


0 0
原创粉丝点击