From 6f7bf653f7f848619d6f37eda350cec48281212c Mon Sep 17 00:00:00 2001 From: Tetragramm Date: Fri, 21 Oct 2016 20:01:12 -0500 Subject: [PATCH 1/3] Add 90 degree rotation methods. This provides a quick simple way of doing 90 degree rotations. Also fix warnings that show up on other compilers in test builds. --- modules/core/include/opencv2/core.hpp | 18 +++++++++++ modules/core/src/copy.cpp | 44 +++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/modules/core/include/opencv2/core.hpp b/modules/core/include/opencv2/core.hpp index 4a21aab66e..226327280b 100644 --- a/modules/core/include/opencv2/core.hpp +++ b/modules/core/include/opencv2/core.hpp @@ -1022,6 +1022,24 @@ around both axes. */ CV_EXPORTS_W void flip(InputArray src, OutputArray dst, int flipCode); +enum RotateFlags { + ROTATE_90 = 0, //Rotate 90 degrees clockwise + ROTATE_180 = 1, //Rotate 180 degrees clockwise + ROTATE_270 = 2, //Rotate 270 degrees clockwise +}; +/** @brief Rotates a 2D array in multiples of 90 degrees. +The function rotate rotates the array in one of three different ways: +* Rotate by 90 degrees clockwise (rotateCode = ROTATE_90). +* Rotate by 180 degrees clockwise (rotateCode = ROTATE_180). +* Rotate by 270 degrees clockwise (rotateCode = ROTATE_270). +@param src input array. +@param dst output array of the same type as src. The size is the same with ROTATE_180, +and the rows and cols are switched for ROTATE_90 and ROTATE_270. +@param rotateCode an enum to specify how to rotate the array; see the enum RotateFlags +@sa transpose , repeat , completeSymm, flip, RotateFlags +*/ +CV_EXPORTS_W void rotate(InputArray src, OutputArray dst, int rotateCode); + /** @brief Fills the output array with repeated copies of the input array. The function cv::repeat duplicates the input array one or more times along each of the two axes: diff --git a/modules/core/src/copy.cpp b/modules/core/src/copy.cpp index 7d5e4d8ec1..0310329649 100644 --- a/modules/core/src/copy.cpp +++ b/modules/core/src/copy.cpp @@ -826,6 +826,50 @@ void flip( InputArray _src, OutputArray _dst, int flip_mode ) flipHoriz( dst.ptr(), dst.step, dst.ptr(), dst.step, dst.size(), esz ); } +#ifdef HAVE_OPENCL + +static bool ocl_rotate(InputArray _src, OutputArray _dst, int rotateMode) +{ + switch (rotateMode) + { + case ROTATE_90: + flip(_src.getUMat().t(), _dst, 1); + break; + case ROTATE_180: + flip(_src, _dst, -1); + break; + case ROTATE_270: + flip(_src.getUMat().t(), _dst, 0); + break; + default: + break; + } + return true; +} +#endif + +void rotate(InputArray _src, OutputArray _dst, int rotateMode) +{ + CV_Assert(_src.dims() <= 2); + + CV_OCL_RUN(_dst.isUMat(), ocl_rotate(_src, _dst, rotateMode)) + + switch (rotateMode) + { + case ROTATE_90: + flip(_src.getMat().t(), _dst, 1); + break; + case ROTATE_180: + flip(_src, _dst, -1); + break; + case ROTATE_270: + flip(_src.getMat().t(), _dst, 0); + break; + default: + break; + } +} + #if defined HAVE_OPENCL && !defined __APPLE__ static bool ocl_repeat(InputArray _src, int ny, int nx, OutputArray _dst) From ad5c50a9231182b6ec384acccb776282a7a41a4b Mon Sep 17 00:00:00 2001 From: Tetragramm Date: Wed, 2 Nov 2016 17:44:13 -0500 Subject: [PATCH 2/3] Improve the efficiency as suggested by vpisarev. Alter the Rotation enum to be unambiguous as to direction. --- modules/core/include/opencv2/core.hpp | 4 ++-- modules/core/src/copy.cpp | 20 ++++++++++++-------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/modules/core/include/opencv2/core.hpp b/modules/core/include/opencv2/core.hpp index 226327280b..5208d032a8 100644 --- a/modules/core/include/opencv2/core.hpp +++ b/modules/core/include/opencv2/core.hpp @@ -1023,9 +1023,9 @@ around both axes. CV_EXPORTS_W void flip(InputArray src, OutputArray dst, int flipCode); enum RotateFlags { - ROTATE_90 = 0, //Rotate 90 degrees clockwise + ROTATE_90_CLOCKWISE = 0, //Rotate 90 degrees clockwise ROTATE_180 = 1, //Rotate 180 degrees clockwise - ROTATE_270 = 2, //Rotate 270 degrees clockwise + ROTATE_90_COUNTERCLOCKWISE = 2, //Rotate 270 degrees clockwise }; /** @brief Rotates a 2D array in multiples of 90 degrees. The function rotate rotates the array in one of three different ways: diff --git a/modules/core/src/copy.cpp b/modules/core/src/copy.cpp index 0310329649..259b71c645 100644 --- a/modules/core/src/copy.cpp +++ b/modules/core/src/copy.cpp @@ -832,14 +832,16 @@ static bool ocl_rotate(InputArray _src, OutputArray _dst, int rotateMode) { switch (rotateMode) { - case ROTATE_90: - flip(_src.getUMat().t(), _dst, 1); + case ROTATE_90_CLOCKWISE: + _dst.getUMat() = _src.getUMat().t(); + flip(_dst, _dst, 1); break; case ROTATE_180: flip(_src, _dst, -1); break; - case ROTATE_270: - flip(_src.getUMat().t(), _dst, 0); + case ROTATE_90_COUNTERCLOCKWISE: + _dst.getUMat() = _src.getUMat().t(); + flip(_dst, _dst, 0); break; default: break; @@ -856,14 +858,16 @@ void rotate(InputArray _src, OutputArray _dst, int rotateMode) switch (rotateMode) { - case ROTATE_90: - flip(_src.getMat().t(), _dst, 1); + case ROTATE_90_CLOCKWISE: + _dst.getMat() = _src.getMat().t(); + flip(_dst, _dst, 1); break; case ROTATE_180: flip(_src, _dst, -1); break; - case ROTATE_270: - flip(_src.getMat().t(), _dst, 0); + case ROTATE_90_COUNTERCLOCKWISE: + _dst.getMat() = _src.getMat().t(); + flip(_dst, _dst, 0); break; default: break; From 24379fcb5fdcbecb48c3057cbefe332525d04a60 Mon Sep 17 00:00:00 2001 From: Tetragramm Date: Thu, 10 Nov 2016 21:35:00 -0600 Subject: [PATCH 3/3] Use transpose() as suggested, because it works on pre-existing destination Mats. --- modules/core/src/copy.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/core/src/copy.cpp b/modules/core/src/copy.cpp index 259b71c645..1dd56f3cfe 100644 --- a/modules/core/src/copy.cpp +++ b/modules/core/src/copy.cpp @@ -833,14 +833,14 @@ static bool ocl_rotate(InputArray _src, OutputArray _dst, int rotateMode) switch (rotateMode) { case ROTATE_90_CLOCKWISE: - _dst.getUMat() = _src.getUMat().t(); + transpose(_src, _dst); flip(_dst, _dst, 1); break; case ROTATE_180: flip(_src, _dst, -1); break; case ROTATE_90_COUNTERCLOCKWISE: - _dst.getUMat() = _src.getUMat().t(); + transpose(_src, _dst); flip(_dst, _dst, 0); break; default: @@ -859,14 +859,14 @@ void rotate(InputArray _src, OutputArray _dst, int rotateMode) switch (rotateMode) { case ROTATE_90_CLOCKWISE: - _dst.getMat() = _src.getMat().t(); + transpose(_src, _dst); flip(_dst, _dst, 1); break; case ROTATE_180: flip(_src, _dst, -1); break; case ROTATE_90_COUNTERCLOCKWISE: - _dst.getMat() = _src.getMat().t(); + transpose(_src, _dst); flip(_dst, _dst, 0); break; default: