理论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度
更多请参考: