Image rotation is a common image processing routine used to rotate images at any desired angle. This helps in image reversal, flipping, and obtaining an intended view of the image. Image rotation has applications in matching, alignment, and other image-based algorithms. OpenCV is a well-known library used for image processing.
Approach:
Before switching ahead, set up an OpenCV environment for Java in order to deal with images and later to perform the action on them. Now, image rotation is performed in OpenCV with the help of the warpAffine() method. The image can be rotated at any angle using this technique for which it is required to define around which point or axis rotation is to be performed.
Following steps are serially followed as mentioned:
- Identify a point about which rotation is to be done and rotation angle.
- Get a rotation matrix for the source image.
- Use Affine transformation on the source image using the rotation matrix obtained.
Besides this approach, there are two more approaches for rotating an image in angles that are multiples of 90 degrees (i.e., ±90, ±180, ±270). An affine transform is dozens of times more computationally intensive. Affine interpolates and uses a lot of floating-point arithmetic. Following approaches are much more effective than warpAffine() for angles that are multiples of 90 degrees.
Use-Cases in image rotation that can occur
- Rotate method
- Transpose and Flip method
Methods Required:
- warpAffine()
- getRotationMatrix2D()
- rotate()
- flip()
- Transpose()
Methods are described below:
1. warpAffine(): Applies an affine transformation to an image.
Syntax:
Imgproc.warpAffine(Mat src, Mat dst, Mat M, Size dsize, int flags)Parameters:
- src – input image.
- dst – output image that has the size dsize and the same type as src.
- M – 2×3 transformation (rotation) matrix.
- dsize – size of the output image.
- flags – Optional field. WARP_INVERSE_MAP flag.
- When flag is not provided, image mapping is in counterclockwise direction.
- If the WARP_INVERSE_MAP flag is set, image mapping is in clockwise direction.
2. getRotationMatrix2D() : Calculates an affine matrix of 2D rotation.
Syntax:
Imgproc.getRotationMatrix2D(Point center, double angle, double scale)Parameters:
- center – Center of the rotation in the source image.
- angle – Rotation angle in degrees. Positive values mean counter-clockwise rotation
- scale – Isotropic scale factor.
3. rotate() : Rotates a 2D array in multiples of 90 degrees.
Syntax:
Core.rotate(Mat src, Mat dst, int rotateCode)Parameters:
- src – input array.
- dst – output array of the same type as src.
- rotateCode – An enum to specify how to rotate the array.
- ROTATE_90_CLOCKWISE : Rotate image by 90 degrees clockwise or 270 degrees counter clockwise
- ROTATE_90_COUNTERCLOCKWISE : Rotate image by 90 degrees counterclockwise or 270 degrees clockwise
- ROTATE_180 : Rotate by 180 degrees.
4. flip(): Flips a 2D array around vertical, horizontal, or both axes.
Syntax:
Core.flip(Mat src, Mat dst, int flipCode)Parameters:
- src – input array.
- dst – output array of the same size and type as src.
- flipCode – a flag to specify how to flip the array.
- flipCode=0 means flipping around the x-axis.
- flipCode>0 (Positive value such as, 1) means flipping around y-axis.
- flipcode<0 (Negative value such as, -1) means flipping around both axes.
5. Transpose() : Transposes a matrix.
Syntax:
Core.transpose(Mat src, Mat dst)Parameters:
- src – input array.
- dst – output array of the same type as src.
Illustration:
Input: Considering a sample input image:
Pseudo Code: double angle=45 Point rotPoint=new Point(src.cols()/2.0, src.rows()/2.0) Mat rotMat = Imgproc.getRotationMatrix2D( rotPoint, angle, 1); Imgproc.warpAffine(src, dst, rotMat, src.size());Steps to be followed-
- midpoint of a source image,
- rotPoint, is considered for rotation,
- rotation angle is 45°.
- Rotation matrix is obtained by getRotationMatrix2D() method.
- Affine transformation is performed using warpAffine() method.
- Input image will be rotated in 45° counterclockwise direction as shown below.
Output: Image is as shown:
Sample input image: For implementation purposes
Case 1: Rotate method- considering the same input image for the implementation part.
Rotate an image using the rotate method involves the correct use of rotatecode.
- If the angle is 90° or -270°
- Use rotatecode → ROTATE_90_CLOCKWISE
- If the angle is 180° or -180°
- Use rotatecode → ROTATE_180
- If the angle is 270° or -90°
- Use rotatecode → ROTATE_90_COUNTERCLOCKWISE
Example
Java
// import required packages import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.core.Point; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; // Class to rotate image public class GFG { // Main driver method public static void main(String args[]) { // Load library required for OpenCV functions System.loadLibrary(Core.NATIVE_LIBRARY_NAME); // Read an image and store in a Matrix object // Local directory from where image is picked String file = "C:/opencv/image.jpg" ; Mat src = Imgcodecs.imread(file); // Create empty Mat object to store output image Mat dst = new Mat(); // Define Rotation Angle double angle = 90 ; // Image rotation according to the angle provided if (angle == 90 || angle == - 270 ) Core.rotate(src, dst, Core.ROTATE_90_CLOCKWISE); else if (angle == 180 || angle == - 180 ) Core.rotate(src, dst, Core.ROTATE_180); else if (angle == 270 || angle == - 90 ) Core.rotate(src, dst, Core.ROTATE_90_COUNTERCLOCKWISE); else { // Center of the rotation is given by // midpoint of source image : // (width/2.0,height/2.0) Point rotPoint = new Point(src.cols() / 2.0 , src.rows() / 2.0 ); // Create Rotation Matrix Mat rotMat = Imgproc.getRotationMatrix2D( rotPoint, angle, 1 ); // Apply Affine Transformation Imgproc.warpAffine(src, dst, rotMat, src.size(), Imgproc.WARP_INVERSE_MAP); // If counterclockwise rotation is required use // following: Imgproc.warpAffine(src, dst, // rotMat, src.size()); } // Save rotated image // Destination where rotated image is saved // on local directory Imgcodecs.imwrite( "C:/opencv/rotated_image.jpg" , dst // Print message for successful execution of program System.out.println( "Image Rotated Successfully" ); } } |
Output:
Case 2: Transpose and Flip method
- If the angle is 90° or -270°, transpose the source image matrix and then
- flip it with positive value as flipcode
- If the angle is 270° or -90°, transpose the source image matrix and then
- flip it with 0 as flipcode
- If the angle is 180°, flip source image with -1 as flipcode
Implementation:
Java
// Importing openCV libraries import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.core.Point; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; // Class to rotate images public class GFG { // Main driver method public static void main(String args[]) { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); String file = "C:/opencv/image.jpg" ; Mat src = Imgcodecs.imread(file); Mat dst = new Mat(); double angle = 180 ; // Rotate clockwise at 90 degrees if (angle == 90 || angle == - 270 ) { Core.transpose(src, dst); Core.flip(dst, dst, 1 ); } // Rotate clockwise at 180 degrees else if (angle == 180 || angle == - 180 ) Core.flip(src, dst, - 1 ); // Rotate clockwise at 270 degrees else if (angle == 270 || angle == - 90 ) { Core.transpose(src, dst); Core.flip(dst, dst, 0 ); } // Rotate Clockwise with any other angles else { Point rotPoint = new Point(src.cols() / 2.0 , src.rows() / 2.0 ) Mat rotMat = Imgproc.getRotationMatrix2D(rotpoint, angle, 1 ); Imgproc.warpAffine(src, dst, rotMat, src.size(), Imgproc.WARP_INVERSE_MAP); } // Destination where image is written in local // directory Imgcodecs.imwrite( "C:/opencv/rotated_image.jpg" , dst); // Print command for successful execution of program System.out.println( "Image Rotated Successfully" ); } } |
Output: