圖像任意角度的旋轉公式

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 ,計算公式是:


 

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


 

其中 A和 b 均來自映射矩陣(譯者注:A, 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;
 
 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 ) % 360;
  } // for-loop
 }
 return 0;
}

發佈了29 篇原創文章 · 獲贊 4 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章