矩陣變形方法

 http://blog.youkuaiyun.com/as3_flash/article/details/2378571

用戶在代碼中可以創建矩陣類的實例,並通過手動設置矩陣的內部屬性abcdtxty,純手工的創造或改變一個變換矩陣。如果用戶具備豐富的圖形學知識,可以自己算出位移,縮放,旋轉,斜切等變形所需要的二次變換矩陣值,那麼使用這種方法就足夠了。高級用戶使用這種方式將會相當的高效。

但是,顯然大多數用戶並不瞭解矩陣數學和計算機圖形學算法。對它們而言,直接操作Matrix類的屬性是很不容易的。所以為了簡化用戶操作,AS3中的Matrix類綁定了一些內部方法。初級用戶完全可以不顧及矩陣數學和圖形學算法,通過使用這些內建的方法,修改它們的參數,累加它們的效果,最終得到想要的結果。

表所示為AS3Matrix類內建的變形方法:

表Matrix類內建變形方法

名稱

詳情

translate(tx ty)

實現顯示對象的移動。

其中的txty描述的是顯示對像移動的差值,而不是目標點的最終坐標。

scale(sx sy)

實現顯示對象的放大和縮小。

sx:倍數,對應x坐標。

sy:倍數,對應y坐標。

rotate(q)

旋轉一個對象的

q:對象的旋轉量。這是一個弧度值。

為了瞭解矩陣類的實際使用,下面介紹一個最簡單的實例。新建AS3項目,在代碼編輯器中直接輸入以下代碼:

var myMatrix:Matrix=new Matrix;

trace(myMatrix.toString());

 

//使用translate()方法修改矩陣

myMatrix.translate(5,13);

trace(myMatrix.toString());

 

//新建一個點

var myp:Point=new Point(5,5);

trace(myp.toString());

 

//新建一個目標點,用於接受位移後的坐標

var mypt:Point;

//應用位移矩陣

mypt=myMatrix.transformPoint(myp);

 

//輸出目標點的坐標

trace(mypt.toString());

以上代碼較為簡單,註釋也很清楚,不再贅述。運行這段代碼,可以得到輸出:

(a=1, b=0, c=0, d=1, tx=0, ty=0)//初始變換矩陣

(a=1, b=0, c=0, d=1, tx=5, ty=13)//修改後的變形矩陣

(x=5, y=5)//原坐標

(x=10, y=18)//目標坐標

至此,矩陣類的運行流程就很清楚了。聲明一個矩陣類就建立了一個初始變換矩陣,初始矩陣如圖所示:

使用矩陣類的方法其本質是修改這個初始矩陣,應用矩陣類其實就是用該變形矩陣代入仿射變形公式進行運算的過程。

有的用戶覺得這些方法使用起來並不方便,因為它們都是相對值。例如,其中的translate(txty)方法,並不能將對像直接移動到目標點,其真實作用是在水平方向上移動tx距離,在垂直方向上移動ty距離。如果想把顯示對像移動到某點,用戶必須自己進行計算前後的距離差。

其實這是矩陣的內部機製造成的。Matrix類的這些方法都是基於矩陣操作的,遵循的是數學思維。當用戶使用translate(txty)方法時,本質上構建一個產生位移的數學矩陣。矩陣提供了一種仿射變形的映射。AS3執行時,將這個矩陣應用在顯示對像內部的每一個點,令它們在水平方向上移動tx距離,在垂直方向上移動ty距離。假設能夠指定最終的目標值,則運算後,顯示對象的每一個點都會被映射到這同一個點,則顯示對象就被扭曲壓縮了,這顯然是不正確的。

如果用戶從人的思維去考慮,覺得這些內建方法不方便,可以自己寫一組自定義函數,擴展它們的功能。

 

OpenCV 是一个开源的计算机视觉库,提供了丰富的图像处理功能。矩阵变形是其中一种常见的图像处理技术,用于对图像进行几何变换。矩阵变形通过一个变换矩阵来描述图像的变换,包括平移、旋转、缩放、仿射变换和透视变换等。 以下是一些常见的矩阵变形方法及其实现方式: ### 1. 平移变换 平移变换通过将图像沿x轴和y轴移动来实现。变换矩阵如下: \[ T = \begin{bmatrix} 1 & 0 & tx \\ 0 & 1 & ty \\ 0 & 0 & 1 \end{bmatrix} \] ```cpp #include <opencv2/opencv.hpp> int main() { cv::Mat image = cv::imread("input.jpg"); cv::Mat translatedImage; // 定义平移矩阵 cv::Mat translationMatrix = (cv::Mat_<double>(2,3) << 1, 0, tx, 0, 1, ty); // 应用平移变换 cv::warpAffine(image, translatedImage, translationMatrix, image.size()); cv::imshow("Translated Image", translatedImage); cv::waitKey(0); return 0; } ``` ### 2. 旋转变换 旋转变换通过将图像绕某一点旋转一定角度来实现。变换矩阵如下: \[ R = \begin{bmatrix} \cos(\theta) & -\sin(\theta) \\ \sin(\theta) & \cos(\theta) \end{bmatrix} \] ```cpp #include <opencv2/opencv.hpp> int main() { cv::Mat image = cv::imread("input.jpg"); cv::Mat rotatedImage; // 定义旋转矩阵 cv::Point2f center(image.cols/2.0F, image.rows/2.0F); double angle = 45.0; double scale = 1.0; cv::Mat rotationMatrix = cv::getRotationMatrix2D(center, angle, scale); // 应用旋转变换 cv::warpAffine(image, rotatedImage, rotationMatrix, image.size()); cv::imshow("Rotated Image", rotatedImage); cv::waitKey(0); return 0; } ``` ### 3. 仿射变换 仿射变换是一种线性变换,可以保持图像的平行性和比例。变换矩阵如下: \[ A = \begin{bmatrix} a_{11} & a_{12} & b_1 \\ a_{21} & a_{22} & b_2 \\ 0 & 0 & 1 \end{bmatrix} \] ```cpp #include <opencv2/opencv.hpp> int main() { cv::Mat image = cv::imread("input.jpg"); cv::Mat affineImage; // 定义仿射变换矩阵 cv::Point2f srcTri[] = {cv::Point2f(0,0), cv::Point2f(image.cols - 1, 0), cv::Point2f(0, image.rows - 1)}; cv::Point2f dstTri[] = {cv::Point2f(image.cols*0.0, image.rows*0.33), cv::Point2f(image.cols*0.85, image.rows*0.25), cv::Point2f(image.cols*0.15, image.rows*0.7)}; cv::Mat affineMatrix = cv::getAffineTransform(srcTri, dstTri); // 应用仿射变换 cv::warpAffine(image, affineImage, affineMatrix, image.size()); cv::imshow("Affine Transformed", affineImage); cv::waitKey(0); return 0; } ``` ### 4. 透视变换 透视变换是一种非线性变换,可以模拟3D效果。变换矩阵如下: \[ P = \begin{bmatrix} p_{11} & p_{12} & p_{13} \\ p_{21} & p_{22} & p_{23} \\ p_{31} & p_{32} & p_{33} \end{bmatrix} \] ```cpp #include <opencv2/opencv.hpp> int main() { cv::Mat image = cv::imread("input.jpg"); cv::Mat perspectiveImage; // 定义透视变换矩阵 cv::Point2f srcQuad[] = {cv::Point2f(0,0), cv::Point2f(image.cols - 1, 0), cv::Point2f(0, image.rows - 1), cv::Point2f(image.cols - 1, image.rows - 1)}; cv::Point2f dstQuad[] = {cv::Point2f(image.cols*0.05, image.rows*0.33), cv::Point2f(image.cols*0.9, image.rows*0.25), cv::Point2f(image.cols*0.2, image.rows*0.7), cv::Point2f(image.cols*0.8, image.rows*0.9)}; cv::Mat perspectiveMatrix = cv::getPerspectiveTransform(srcQuad, dstQuad); // 应用透视变换 cv::warpPerspective(image, perspectiveImage, perspectiveMatrix, image.size()); cv::imshow("Perspective Transformed", perspectiveImage); cv::waitKey(0); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值