Rotación de imágenes usando OpenCV en Java

La rotación de imágenes es una rutina común de procesamiento de imágenes que se utiliza para rotar imágenes en cualquier ángulo deseado. Esto ayuda en la inversión de la imagen, voltear y obtener una vista deseada de la imagen. La rotación de imágenes tiene aplicaciones en el emparejamiento, la alineación y otros algoritmos basados ​​en imágenes. OpenCV es una biblioteca muy conocida que se utiliza para el procesamiento de imágenes.

Acercarse: 

Antes de continuar, configure un entorno OpenCV para Java para tratar con imágenes y luego realizar la acción en ellas. Ahora, la rotación de imágenes se realiza en OpenCV con la ayuda del método warpAffine() . La imagen se puede rotar en cualquier ángulo utilizando esta técnica para lo cual se requiere definir alrededor de qué punto o eje se va a realizar la rotación.

Los siguientes pasos se siguen en serie como se menciona:

  1. Identifique un punto sobre el cual se va a realizar la rotación y el ángulo de rotación.
  2. Obtenga una array de rotación para la imagen de origen.
  3. Use la transformación Affine en la imagen de origen usando la array de rotación obtenida.

Además de este enfoque, existen dos enfoques más para rotar una imagen en ángulos que son múltiplos de 90 grados (es decir, ±90, ±180, ±270). Una transformación afín es docenas de veces más intensiva desde el punto de vista computacional. Affine interpola y usa mucha aritmética de punto flotante. Los siguientes enfoques son mucho más efectivos que warpAffine() para ángulos que son múltiplos de 90 grados.

Casos de uso en la rotación de imágenes que pueden ocurrir

  1. Método de rotación
  2. Método de transposición y volteo

Métodos requeridos:

  1. deformación afín()
  2. getRotationMatrix2D()
  3. girar()
  4. dar la vuelta()
  5. Transponer()

Los métodos se describen a continuación:

1. warpAffine() : aplica una transformación afín a una imagen.

Sintaxis

Imgproc.warpAffine(Mat src, Mat dst, Mat M, Size dsize, int flags)

Parámetros:

  • src – imagen de entrada.
  • dst : imagen de salida que tiene el tamaño dsize y el mismo tipo que src.
  • M – Array de transformación (rotación) 2×3.
  • dsize : tamaño de la imagen de salida.
  • banderas – Campo opcional. Indicador WARP_INVERSE_MAP.
    • Cuando no se proporciona la bandera, el mapeo de la imagen se realiza en sentido contrario a las agujas del reloj.
    • Si se establece el indicador WARP_INVERSE_MAP, el mapeo de imágenes se realiza en el sentido de las agujas del reloj.

2. getRotationMatrix2D() : Calcula una array afín de rotación 2D.

Sintaxis: 

Imgproc.getRotationMatrix2D(Point center, double angle, double scale)

Parámetros:

  • centro : centro de la rotación en la imagen de origen.
  • ángulo : ángulo de rotación en grados. Los valores positivos significan rotación en sentido contrario a las agujas del reloj
  • escala : factor de escala isotrópico.

3. rotate(): rota una array 2D en múltiplos de 90 grados.

Sintaxis:

Core.rotate(Mat src, Mat dst, int rotateCode)

Parámetros:

  • src – array de entrada.
  • dst : array de salida del mismo tipo que src.
  • rotarCode : una enumeración para especificar cómo rotar la array.
    • ROTATE_90_CLOCKWISE: Gira la imagen 90 grados en el sentido de las agujas del reloj o 270 grados en el sentido contrario a las agujas del reloj
    • ROTATE_90_COUNTERCLOCKWISE: gira la imagen 90 grados en sentido contrario a las agujas del reloj o 270 grados en el sentido de las agujas del reloj
    • ROTATE_180 : Girar 180 grados.

4. flip(): voltea una array 2D alrededor de los ejes vertical, horizontal o ambos.

Sintaxis: 

Core.flip(Mat src, Mat dst, int flipCode)

Parámetros:

  • src – array de entrada.
  • dst : array de salida del mismo tamaño y tipo que src.
  • flipCode : una bandera para especificar cómo voltear la array.
    • flipCode=0 significa voltear alrededor del eje x.
    • flipCode>0 (Valor positivo como 1) significa girar alrededor del eje y.
    • flipcode<0 (Valor negativo como -1) significa girar alrededor de ambos ejes.

5. Transpose() : Transpone una array.

Sintaxis: 

Core.transpose(Mat src, Mat dst)

Parámetros:

  • src – array de entrada.
  • dst : array de salida del mismo tipo que src.

Ilustración: 

Entrada: considerando una imagen de entrada de muestra:

Imagen de entrada 

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());

Pasos a seguir-

  • punto medio de una imagen de origen,
  • rotPoint, se considera para la rotación,
  • el ángulo de rotación es de 45°.
    • La array de rotación se obtiene mediante el método getRotationMatrix2D().
    • La transformación afín se realiza mediante el método warpAffine().
  • La imagen de entrada se girará 45° en sentido contrario a las agujas del reloj, como se muestra a continuación.

Salida: la imagen es como se muestra:

Imagen girada 45° en el sentido contrario a las agujas del reloj

Imagen de entrada de muestra: para fines de implementación

Imagen de entrada 

Caso 1: método de rotación: considerando la misma imagen de entrada para la parte de implementación.

Rotar una imagen utilizando el método de rotación implica el uso correcto de código de rotación.

  • Si el ángulo es de 90° o -270°
    • Usa el código de rotación → ROTATE_90_CLOCKWISE
  • Si el ángulo es de 180° o -180°
    • Usar código de rotación → ROTATE_180
  • Si el ángulo es de 270° o -90°
    • Usa el código de rotación → ROTATE_90_COUNTERCLOCKWISE

Ejemplo

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");
    }
}

Producción:

Caso 2: método de transposición y volteo

  • Si el ángulo es de 90° o -270°, transponga la array de la imagen de origen y luego
    • darle la vuelta con valor positivo como flipcode
  • Si el ángulo es de 270° o -90°, transponga la array de la imagen de origen y luego
    • darle la vuelta con 0 como flipcode
  • Si el ángulo es de 180°, voltea la imagen de origen con -1 como flipcode

Implementación:

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");
    }
}

Producción:

Publicación traducida automáticamente

Artículo escrito por hemavatisabu y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *