From 28857d55e7850ba26dadfade5f6b7e24c46b3ecb Mon Sep 17 00:00:00 2001 From: Jose Luis Blanco-Claraco Date: Fri, 11 Oct 2024 12:40:29 +0200 Subject: [PATCH] Add common image rotation as special cases --- doc/source/doxygen-docs/changelog.md | 2 ++ libs/img/include/mrpt/img/CImage.h | 4 +++- libs/img/src/CImage.cpp | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/doc/source/doxygen-docs/changelog.md b/doc/source/doxygen-docs/changelog.md index 18fbfc14a1..6b6141a8f8 100644 --- a/doc/source/doxygen-docs/changelog.md +++ b/doc/source/doxygen-docs/changelog.md @@ -2,6 +2,8 @@ # Version 2.14.3: UNRELEASED - Changes in libraries: + - \ref mrpt_img_grp: + - mrpt::img::CImage::rotateImage(): Special angles 90,-90, 180 are handled as expected with a quick image transformation and rotation. - \ref mrpt_nav_grp: - mrpt::nav::CWaypointsNavigator: New parameter "minimum_target_approach_per_step" and feature to keep approaching waypoints until no significant improvement is done. - \ref mrpt_ros1bridge_grp and mrpt_ros2bridge_grp: diff --git a/libs/img/include/mrpt/img/CImage.h b/libs/img/include/mrpt/img/CImage.h index 3a6f88a90d..71d1f384cb 100644 --- a/libs/img/include/mrpt/img/CImage.h +++ b/libs/img/include/mrpt/img/CImage.h @@ -261,8 +261,10 @@ class CImage : public mrpt::serialization::CSerializable, public CCanvas unsigned int height, TInterpolationMethod interp = IMG_INTERP_CUBIC) const; - /** Rotates the image by the given angle around the given center point, with + /** Rotates the image by the given angle (in radians) around the given center point, with * an optional scale factor. + * The output image will have the same size as the input, except if angle is exactly ±90 degrees, + * in which case a quick image rotation (switching height and widht) will be performed instead. * \sa resize, scaleImage */ void rotateImage( diff --git a/libs/img/src/CImage.cpp b/libs/img/src/CImage.cpp index 87b6d78359..1dc32ab586 100644 --- a/libs/img/src/CImage.cpp +++ b/libs/img/src/CImage.cpp @@ -1797,6 +1797,21 @@ void CImage::rotateImage( // Detect in-place operation and make a deep copy if needed: if (out_img.m_impl->img.data == srcImg.data) srcImg = srcImg.clone(); + // quick rotation? + if (std::abs(M_PI * 0.5 - std::abs(ang)) < 1e-3 || std::abs(M_PI - std::abs(ang)) < 1e-3) + { + int rotCode = 0; + if (std::abs(M_PI * 0.5 - ang) < 1e-3) + rotCode = cv::ROTATE_90_COUNTERCLOCKWISE; + else if (std::abs(-M_PI * 0.5 - ang) < 1e-3) + rotCode = cv::ROTATE_90_CLOCKWISE; + else if (std::abs(M_PI - ang) < 1e-3) + rotCode = cv::ROTATE_180; + + cv::rotate(srcImg, out_img.m_impl->img, rotCode); + } + // else: general rotation: + out_img.resize(getWidth(), getHeight(), getChannelCount()); // Based on the blog entry: