2012-09-18 131 views
3

我試圖從閃爍影片剪輯中的變換矩陣中獲取歪斜值。轉換矩陣表示爲從仿射變換矩陣得到歪斜或旋轉值

a b tx 
c d ty 
0 0 1 

我沒有關於執行什麼類型的轉換以及首先發生的信息。我知道在閃光燈中,您只能旋轉或傾斜影片剪輯(如果我錯了,請糾正我)。我可以從影片剪輯的scaleX和scaleY屬性中獲取縮放值。我相信翻譯並不重要,我只能將tx和ty等於零。

所以我的問題有2個部分。如何確定是否應用了歪斜或旋轉,以及如何獲取各個值?

+0

你在這方面有什麼進展,我經歷過同樣的麻煩,並且有一個有限用法的可行版本(禁止歪斜,並使每個位圖都符號)。它很髒,但工作。如果您仍然感興趣,請與我聯繫。 – yihuang

+0

另一個流浪漢..不能讓我的頭在這附近。如果有像我們這樣的俱樂部,請考慮我。我正在寫一個[Flump](http://tconkling.github.io/flump/)運行時 – sixFingers

回答

0

首先,您可以同時進行傾斜和旋轉,但您必須先選擇順序。偏斜矩陣解釋here,到斜矩陣添加到變換,用戶創建一個新的矩陣,做yourTransformMatrix.concat(skewMatrix);

我目前還不能說,如果你能在「旋轉角度」來檢索轉換的值,「skew_X角度「,」skew_Y角度「,」平移_X「,」平移_Y「,這通常是非線性方程組,其可能不具有針對特定矩陣的解。

+0

我不想做轉換矩陣。我正在導出由設計人員製作的Flash動畫,這是通過UI完成的,所以我無法確定哪些轉換先來過 – tzl

2

二維旋轉矩陣是

cos(theta) -sin(theta) 
sin(theta) cos(theta) 

所以如果你有沒有應用縮放或剪切

a = d 
and 
    c = -b 
and the angle of rotation is 
    theta = asin(c) = acos(a) 

如果你有縮放應用,可以恢復的縮放係數SX和sy,只需將sx中的第一行和sy中的第二行除以原始變換矩陣,然後如上所述恢復旋轉角度。

如果你在那裏的任何地方都有一個剪切(傾斜),我就跟前面的評論者一樣,除非在非常有限的情況下(例如一次只有一個已知方向剪切和按照已知的順序)。

2

您需要進行極性分解。這篇維基百科文章解釋了它是如何工作的: http://en.wikipedia.org/wiki/Polar_decomposition 這是我爲我自己的程序使用OpenCV庫編寫的代碼。

const double PI = 3.141592653; 
 
    cv::Mat rotationOutput = cv::Mat::zeros(warp00.size(),CV_64F); 
 
    cv::Mat_<double>::iterator rotIter = rotationOutput.begin<double>(); 
 
    cv::Mat_<double>::iterator warp00Iter = warp00.begin<double>(); 
 
    cv::Mat_<double>::iterator warp01Iter = warp01.begin<double>(); 
 
    cv::Mat_<double>::iterator warp10Iter = warp10.begin<double>(); 
 
    cv::Mat_<double>::iterator warp11Iter = warp11.begin<double>(); 
 

 
    for(; warp00Iter != warp00.end<double>(); ++warp00Iter, ++warp01Iter, ++warp10Iter, 
 
     ++warp11Iter, ++rotIter){ 
 
     cv::Matx22d fMatrix(*warp00Iter,*warp01Iter, *warp10Iter, *warp11Iter); 
 
     cv::Matx22d cMatrix; 
 
     cv::Matx22d cMatSqrt(0.,0.,0.,0.); 
 
     cv::mulTransposed(fMatrix, cMatrix, true); 
 
     cv::Matx21d eigenVals; 
 
     cv::Matx22d eigenVecs; 
 
     if((cMatrix(0,0) !=0.) && (cMatrix(1,1) !=0.)){ 
 
      if(cv::eigen(cMatrix,true,eigenVals,eigenVecs)){ 
 
       cMatSqrt = eigenVecs.t()* 
 
         cv::Matx22d(sqrt(eigenVals(0,0)),0.,0.,sqrt(eigenVals(1,0)))*eigenVecs; 
 
      } 
 
     } 
 
     cv::Matx22d rMat = fMatrix*cMatSqrt.inv(); 
 
     *rotIter = atan(rMat(1,0)/rMat(0,0)); 
 
     
 
    }

warp00,warp01,WARP10和warp11包含仿射的前4個PARAMS變換(不需要翻譯PARAMS warp02和warp12)。在你的情況下,它會是a,b,c,d。 您會在維基百科文章中注意到您需要計算矩陣的平方根。唯一的方法是計算特徵值,然後計算它們的平方根並將對角矩陣旋轉回原始座標系。 它很複雜,但它是計算旋轉時仿射變換的唯一方法。 在我的情況下,我只關心旋轉,所以我的代碼不會給你歪斜。