2016-08-25
转载地址:http://blog.csdn.net/baidu_23287903/article/details/52311149
理论
http://www.cnblogs.com/wangguchangqing/p/4045150.html
翻开任意一本图像处理的书,都会讲到图像的几何变换,这里面包括:仿射变换(affine transformation)、投影变换(projecttive transformation)。前者针对的是平面上的物体位姿变化,如水平/垂直方向位移、旋转、缩小/放大,常见的应用有ORC字符识别。后者针对的是三维空间中的位置变化,受限于物体依然是平面的,也称为二维投影变换,常见的应用有车牌识别。
图像变换:以上所有变换均可以通过矩阵描述,将输入图像与变换矩阵进行矩阵乘法得到变换后的图像坐标。显然,这种方式非常适合编程实现。
OpenCV仿射变换函数说明
opencv提供了,从变换矩阵计算,到图像变换,每个流程的一揽子解决方案。
以opencv 3.0为例,参考几何变换模块说明:
1、getAffineTransform
- Mat getAffineTransform(InputArray src, InputArray dst)
2、getRotationMatrix2D
- Mat getRotationMatrix2D(Point2f center, double angle, double scale)
3、warpAffine
- void warpAffine(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())
src为输入图像
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 , ho ) = src(x,y)f$
- - flag is set: f$dst(x,y) = src( phi , ho )f$
- */
- WARP_INVERSE_MAP = 16 //逆变换
- };
- 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());
更多请参考: