• 第六章


    拉伸、收缩、扭曲、旋转是图像的几何变换,在三维视觉技术中大量应用到这些变换,又分为仿射变换和透视变换。仿射变换通常用单应性建模,利用cvWarpAffine解决密集映射,用cvTransform解决稀疏映射。仿射变换可以将矩形转换成平行四边形,它可以将矩形的边压扁但必须保持边是平行的,也可以将矩形旋转或者按比例变化。透视变换提供了更大的灵活性,一个透视变换可以将矩阵转变成梯形。当然,平行四边形也是梯形,所以仿射变换是透视变换的子集。

    本小节实现图像的仿射变换。

    ------------------------------------------------------------------------------------ 

    以下是本例程用到的方法:

    CloneImage
    制作图像的完整拷贝

    IplImage* cvCloneImage( const IplImage* image );
    image
    原图像.
    函数 cvCloneImage 制作图像的完整拷贝包括头、ROI和数据
    -----------------------------

    GetAffineTransform

    由三对点计算仿射变换

    CvMat* cvGetAffineTransform( const CvPoint2D32f* src,const CvPoint2D32f* dst, CvMat* map_matrix );

    src

    输入图像的三角形顶点坐标。

    dst

    输出图像的相应的三角形顶点坐标。

    map_matrix

    指向2×3输出矩阵的指针。

    函数cvGetAffineTransform计算满足以下关系的仿射变换矩阵:

    这里,dst(i)= (x'i,y'i),src(i)= (xi,yi),i = 0..2.

    -----------------------------

     

    WarpAffine

    对图像做仿射变换

    void cvWarpAffine( const CvArr* src, CvArr* dst, constCvMat* map_matrix,

                      int flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS,

                      CvScalar fillval=cvScalarAll(0) );

    src

    输入图像.

    dst

    输出图像.

    map_matrix

    2×3 变换矩阵

    flags

    插值方法和以下开关选项的组合:

    ·       CV_WARP_FILL_OUTLIERS - 填充所有输出图像的象素。如果部分象素落在输入图像的边界外,那么它们的值设定为 fillval.

    ·       CV_WARP_INVERSE_MAP - 指定 map_matrix是输出图像到输入图像的反变换,因此可以直接用来做象素插值。否则, 函数从 map_matrix 得到反变换。

    fillval

    用来填充边界外面的值

    函数 cvWarpAffine 利用下面指定的矩阵变换输入图像:

    • 如果没有指定 CV_WARP_INVERSE_MAP ,
    • 否则, 

    函数与 cvGetQuadrangleSubPix 类似,但是不完全相同。cvWarpAffine 要求输入和输出图像具有同样的数据类型,有更大的资源开销(因此对小图像不太合适)而且输出图像的部分可以保留不变。而 cvGetQuadrangleSubPix 可以精确地从8位图像中提取四边形到浮点数缓存区中,具有比较小的系统开销,而且总是全部改变输出图像的内容。要变换稀疏矩阵,使用 cxcore 中的函数 cvTransform 。

    -----------------------------

    2DRotationMatrix

    2DRotationMatrix
    计算二维旋转的仿射变换矩阵

    CvMat* cv2DRotationMatrix( CvPoint2D32f center, double angle,
    double scale, CvMat* map_matrix );
    center
    输入图像的旋转中心坐标
    angle
    旋转角度(度)。正值表示逆时针旋转(坐标原点假设在左上角).
    scale
    各项同性的尺度因子
    map_matrix
    输出 2×3 矩阵的指针
    函数 cv2DRotationMatrix 计算矩阵:

    [ α β | (1-α)*center.x - β*center.y ]
    [ -β α | β*center.x + (1-α)*center.y ]

    where α=scale*cos(angle), β=scale*sin(angle)
    该变换并不改变原始旋转中心点的坐标,如果这不是操作目的,则可以通过调整平移量改变其坐标(译者注:通过简单的推导可知,仿射变换的实现是首先将旋转中心置为坐标原点,再进行旋转和尺度变换,最后重新将坐标原点设定为输入图像的左上角,这里的平移量是center.x, center.y).

     ------------------------------------------------------------------------------------ 

    /*code*/

      1. #include <highgui.h>   
      2. #include <cv.h>   
      3.   
      4. int main(int argc, char** argv)  
      5. {  
      6.     CvPoint2D32f srcTri[3], dstTri[3]; //二维坐标下的点,类型为浮点   
      7.     CvMat* rot_mat = cvCreateMat( 2, 3, CV_32FC1 );  //多通道矩阵   
      8.     CvMat* warp_mat = cvCreateMat( 2, 3, CV_32FC1 );  
      9.     IplImage *src, *dst;  
      10.   
      11.     if( argc == 2 && ( ( src = cvLoadImage( argv[1], 1 ) ) != 0 ) )  
      12.     {  
      13.         dst = cvCloneImage( src );  //制作图像的完整拷贝   
      14.         dst ->origin = src ->origin;    
      15.         /* 
      16.         int origin; /* 0 - 顶—左结构, 
      17.         1 - 底—左结构 (Windows bitmaps 风格)  
      18.         */  
      19.         cvZero( dst );  //清空数组   
      20.   
      21.         //计算矩阵仿射变换   
      22.         srcTri[0].x = 0;  
      23.         srcTri[0].y = 0;  
      24.         srcTri[1].x = src -> width - 1;  //缩小一个像素   
      25.         srcTri[1].y = 0;  
      26.         srcTri[2].x = 0;  
      27.         srcTri[2].y = src -> height - 1;  
      28.   
      29.         //改变目标图像大小   
      30.         dstTri[0].x = src -> width * 0.0;  
      31.         dstTri[0].y = src -> height * 0.33;  
      32.         dstTri[1].x = src -> width * 0.85;  
      33.         dstTri[1].y = src -> height * 0.25;  
      34.         dstTri[2].x = src -> width * 0.15;  
      35.         dstTri[2].y = src -> height * 0.7;  
      36.         cvGetAffineTransform( srcTri, dstTri, warp_mat );  //由三对点计算仿射变换    
      37.         cvWarpAffine( src, dst, warp_mat );  //对图像做仿射变换   
      38.         cvCopy( dst, src );  //将dst拷贝给src   
      39.   
      40.         //计算旋转仿射变换   
      41.         CvPoint2D32f center = cvPoint2D32f( src -> width / 2, src -> height / 2 );  
      42.         double angle = -50.0; //旋转角度,负值表示顺时针   
      43.         double scale = 0.6;  //各项同性的尺度因子    
      44.         cv2DRotationMatrix( center, angle, scale, rot_mat );  
      45.         cvWarpAffine( src, dst, rot_mat );  //将src仿射变换存入dst   
      46.   
      47.         //输出   
      48.         cvNamedWindow( "Affine_Transform", 1 );  
      49.         cvShowImage( "Affine_Transform", dst );  //最终是输出dst    
      50.         cvWaitKey();  
      51.     }  
      52.     cvReleaseImage( &dst );  
      53.     cvReleaseMat( &rot_mat );  
      54.     cvReleaseMat( &warp_mat );  
      55.   
      56.     return 0;  
      57. }  
  • 相关阅读:
    20080619 SQL SERVER 输入 NULL 的快捷键
    20090406 Adobe的“此产品的许可已停止工作”错误的解决办法
    20080908 Office Powerpoint 2007 不能输入中文的解决办法
    20080831 ClearGertrude Blog Skin 's cnblogs_code class
    20080603 Facebook 平台正式开放
    20080519 安装 Microsoft SQL Server 2000 时提示 创建挂起的文件操作
    test
    Linux—fork函数学习笔记
    SOA的设计理念
    Why BCP connects to SQL Server instance which start with account of Network Service fail?
  • 原文地址:https://www.cnblogs.com/wqj1212/p/3915891.html
Copyright © 2020-2023  润新知