注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

慵懒的乌龟

——若有,且珍惜~

 
 
 

日志

 
 

图像旋转公式及opencv中cvGetQuadrangleSubPix 的用法 [转]  

2011-03-14 21:37:40|  分类: opencv 学习 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

来源: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 );  
void cvGetQuadrangleSubPix( const CvArr* src, CvArr* dst, const CvMat* map_matrix, int fill_outliers=0, CvScalar fill_value=cvScalarAll(0) );

src
输入图像.
dst
提取的四边形.
map_matrix
3 × 2 变换矩阵 [A|b] (见讨论).

fill_outliers
该标志位指定是否对原始图像边界外面的象素点使用复制模式(fill_outliers=0)进行差值或者将其设置为指定值(fill_outliers=1)。
fill_value
对原始图像边界外面的象素设定固定值,当 fill_outliers=1.



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


dst(x + width(dst) / 2,y + height(dst) / 2) = src(A11x + A12y + b1,A21x + A22y + b2)


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

map_matrix | A11 A12 b1 | map_matrix = | | | A21 A22 b2 |



其中在非整数坐标 A?(x,y)T+b 的象素点值通过双线性变换得到。当函数需要图像边界外的像素点时,使用重复边界模式(replication border mode)恢复出所需的值。多通道图像的每一个通道都单独计算。

    例子:使用 cvGetQuadrangleSubPix 进行图像旋转

   

   

#include "cv.h"
#include "highgui.h"
#include "math.h"
#include<stdio.h>
int main( int argc, char** argv )
{
IplImage* src;
/* the first command line parameter must be image file name */
if( (src = cvLoadImage(".\\1q.png", -1)))
{
   printf("sdfs");
   IplImage* dst = cvCloneImage( src );
   int delta = 1;
   int angle = 0;
        int opt = 0;   // 1: 旋转加缩放
                       // 0: 仅仅旋转
        double factor;
        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.05)*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
    cvGetQuadrangleSubPix( src, dst, &M);
    cvNamedWindow( "dst", 1 );
    cvShowImage( "dst", dst );
    if( cvWaitKey(85) == 27 )
     break;
    angle =(int) (angle /*+ delta*/) % 360;
   } // for-loop
}
return 0;
}

  评论这张
 
阅读(1680)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017