理論html
http://www.cnblogs.com/wangguchangqing/p/4045150.html
算法
翻開任意一本圖像處理的書,都會講到圖像的幾何變換,這裏麪包括:仿射變換(affine transformation)、投影變換(projecttive transformation)。前者針對的是平面上的物體位姿變化,如水平/垂直方向位移、旋轉、縮小/放大,常見的應用有ORC字符識別。後者針對的是三維空間中的位置變化,受限於物體依然是平面的,也稱爲二維投影變換,常見的應用有車牌識別。編程
圖像變換:以上全部變換都可以經過矩陣描述,將輸入圖像與變換矩陣進行矩陣乘法獲得變換後的圖像座標。顯然,這種方式很是適合編程實現。ide
opencv仿射變換函數說明函數
opencv提供了,從變換矩陣計算,到圖像變換,每一個流程的一攬子解決方案。spa
以opencv 3.0爲例,參考幾何變換模塊說明:.net
一、getAffineTransformrest
Mat getAffineTransform(InputArray src, InputArray dst)
該函數須要已知變換前與變換後的座標,返回相應的變換矩陣,至因而何種變換無需事先知道。適用於目標檢測場合,經過檢測獲得的特徵點進行圖像匹配。
二、getRotationMatrix2Dcode
Mat getRotationMatrix2D(Point2f center, double angle, double scale)
已知旋轉中心座標(座標原點爲圖像左上端點)、旋轉角度(單位爲度°,順時針爲負,逆時針爲正)、放縮比例,返回旋轉/放縮矩陣。與getAffineTransform相比,無需知道變換後坐標,適用於通常狀況下的圖像變換。
三、warpAffineorm
void warpAffine(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())
根據etAffineTransform或getRotationMatrix2D獲得的變換矩陣,計算變換後的圖像。
dst爲變換後圖像,類型與src一致。
M爲變換矩陣,須要經過其它函數得到,固然也能夠手動輸入。
dsize爲輸出圖像的大小
flags,插值算法,詳細以下:
-
enum InterpolationFlags{
-
/** nearest neighbor interpolation */
-
INTER_NEAREST =
0,
//最近鄰插值
-
/** bilinear interpolation */
-
INTER_LINEAR =
1,
//雙線性插值
-
/** bicubic interpolation */
-
INTER_CUBIC =
2,
//雙三次插值
-
/** resampling using pixel area relation. It may be a preferred method for image decimation, as
-
it gives moire'-free results. But when the image is zoomed, it is similar to the INTER_NEAREST
-
method. */
-
INTER_AREA =
3,
//區域插值,使用象素關係重採樣。當圖像縮小時候,該方法能夠避免波紋出現。當圖像放大時,相似於 <span style="font-family: Arial, Helvetica, sans-serif;">INTER_NEAREST</span>方法
-
/** Lanczos interpolation over 8x8 neighborhood */
-
INTER_LANCZOS4 =
4,
//Lanczos插值(超過8×8像素鄰域的Lanczos插值)
-
/** mask for interpolation codes */
-
INTER_MAX =
7,
-
/** flag, fills all of the destination image pixels. If some of them correspond to outliers in the
-
source image, they are set to zero */
-
WARP_FILL_OUTLIERS =
8,
//填充全部輸出圖像的象素
-
/** flag, inverse transformation
-
-
For example, polar transforms:
-
- flag is __not__ set: \f$dst( \phi , \rho ) = src(x,y)\f$
-
- flag is set: \f$dst(x,y) = src( \phi , \rho )\f$
-
*/
-
WARP_INVERSE_MAP =
16
//逆變換
-
};
borderMode,邊界處理方式
-
enum BorderTypes {
-
BORDER_CONSTANT =
0,
//!< `iiiiii|abcdefgh|iiiiiii` with some specified `i`
-
BORDER_REPLICATE =
1,
//!< `aaaaaa|abcdefgh|hhhhhhh`
-
BORDER_REFLECT =
2,
//!< `fedcba|abcdefgh|hgfedcb`
-
BORDER_WRAP =
3,
//!< `cdefgh|abcdefgh|abcdefg`
-
BORDER_REFLECT_101 =
4,
//!< `gfedcb|abcdefgh|gfedcba`
-
BORDER_TRANSPARENT =
5,
//!< `uvwxyz|absdefgh|ijklmno`
-
-
BORDER_REFLECT101 = BORDER_REFLECT_101,
//!< same as BORDER_REFLECT_101
-
BORDER_DEFAULT = BORDER_REFLECT_101,
//!< same as BORDER_REFLECT_101
-
BORDER_ISOLATED =
16
//!< do not look outside of ROI
-
};
opencv實現圖像旋轉(其它仿射變換的流程與此一致)
-
Mat src;
-
Mat dst(src.size(),src.type());
-
...
-
cv::
Point2f center(x0,y0);
-
double ang =
-30;
-
cv::Mat rotMat = cv::getRotationMatrix2D(center,ang,
1);
-
cv::warpAffine(src,dst,rotMat,src.size());
順時針旋轉30度
更多請參考: