OpenCV中并没有直接提供实现rotate的函数,这里通过getRotationMatrix2D和warpAffine函数实现rotate,并增加了一个crop参数,用来判断是否进行crop。目前支持uchar和float两种类型,经测试,与OpenCV3.1结果完全一致。
实现代码rotate.hpp:
- // fbc_cv是免费软件,并且使用与OpenCV相同的许可证
- #ifndef FBC_CV_ROTATE_HPP_
- #define FBC_CV_ROTATE_HPP_
- /* reference: include/opencv2/imgproc.hpp
- modules/imgproc/src/imgwarp.cpp
- */
- #include "core/mat.hpp"
- #include "warpAffine.hpp"
- namespace fbc {
- // 计算2D旋转的仿射矩阵
- // 正值表示逆时针旋转(坐标原点假定为左上角)
- FBC_EXPORTS int getRotationMatrix2D(Point2f center, double angle, double scale, Mat_<double, 1>& dst);
- // 将旋转应用于图像
- // 该功能无法正常工作
- // 支持类型:uchar / float
- template<typename _Tp, int chs>
- int rotate(const Mat_<_Tp, chs>& src, Mat_<_Tp, chs>& dst, Point2f center, double angle,
- bool crop = true, int flags = INTER_LINEAR, int borderMode = BORDER_CONSTANT, const Scalar& borderValue = Scalar())
- {
- FBC_Assert(typeid(float).name() == typeid(_Tp).name() || typeid(uchar).name() == typeid(_Tp).name());
- FBC_Assert(src.data != NULL && src.rows > 0 && src.cols > 0);
- Mat_<double, 1> rot_matrix(2, 3);
- getRotationMatrix2D(center, angle, 1.0, rot_matrix);
- if (crop) {
- if (dst.data == NULL) {
- dst = Mat_<_Tp, chs>(src.rows, src.cols);
- }
- } else {
- Rect bbox = RotatedRect(center, Size2f(src.cols, src.rows), angle).boundingRect();
- double* p = (double*)rot_matrix.data;
- p[2] += bbox.width / 2.0 - center.x;
- p[5] += bbox.height / 2.0 - center.y;
- if (dst.rows != bbox.height || dst.cols != bbox.width) {
- dst = Mat_<_Tp, chs>(bbox.height, bbox.width);
- }
- }
- warpAffine(src, dst, rot_matrix, flags, borderMode, borderValue);
- return 0;
- }
- } // 命名空间fbc
- #endif // FBC_CV_ROTATE_HPP_