Rotar imagen sin cortar los lados usando Python – OpenCV

Requisito previo : procesamiento de imágenes en Python (escalado, rotación, desplazamiento y detección de bordes)

Rotar imágenes con OpenCV es fácil, pero a veces las tareas de rotación simples recortan/cortan los lados de una imagen, lo que lleva a una imagen a la mitad. Ahora, en este tutorial, exploraremos una solución para rotar una imagen de manera segura sin recortar/cortar los lados de una imagen para que toda la imagen se incluya en la rotación, y también compararemos el método de rotación convencional con la versión de rotación modificada.

Enfoque paso a paso:

  • Para rotar una imagen sin cortar los lados, crearemos una función explícita llamada ModifedWay() que tomará la imagen en sí y el ángulo al que se rotará la imagen como argumento.
  • En la función, primero, obtenga la altura y el ancho de la imagen.
  • Localiza el centro de la imagen.
  • Luego calcule la array de rotación 2D
  • Extraiga los valores absolutos de seno y coseno de la array de rotación.
  • Obtenga la nueva altura y anchura de la imagen y actualice los valores de la array de rotación para asegurarse de que no haya recortes.
  • Finalmente, use el método wrapAffine() para realizar la rotación real de la imagen.

A continuación se muestra la implementación del enfoque:

Python3

def ModifiedWay(rotateImage, angle):
    
    # Taking image height and width
    imgHeight, imgWidth = rotateImage.shape[0], rotateImage.shape[1]
  
    # Computing the centre x,y coordinates
    # of an image
    centreY, centreX = imgHeight//2, imgWidth//2
  
    # Computing 2D rotation Matrix to rotate an image
    rotationMatrix = cv2.getRotationMatrix2D((centreY, centreX), angle, 1.0)
  
    # Now will take out sin and cos values from rotationMatrix
    # Also used numpy absolute function to make positive value
    cosofRotationMatrix = np.abs(rotationMatrix[0][0])
    sinofRotationMatrix = np.abs(rotationMatrix[0][1])
  
    # Now will compute new height & width of
    # an image so that we can use it in
    # warpAffine function to prevent cropping of image sides
    newImageHeight = int((imgHeight * sinofRotationMatrix) +
                         (imgWidth * cosofRotationMatrix))
    newImageWidth = int((imgHeight * cosofRotationMatrix) +
                        (imgWidth * sinofRotationMatrix))
  
    # After computing the new height & width of an image
    # we also need to update the values of rotation matrix
    rotationMatrix[0][2] += (newImageWidth/2) - centreX
    rotationMatrix[1][2] += (newImageHeight/2) - centreY
  
    # Now, we will perform actual image rotation
    rotatingimage = cv2.warpAffine(
        rotateImage, rotationMatrix, (newImageWidth, newImageHeight))
  
    return rotatingimage

A continuación se muestran algunos ejemplos que muestran cómo rotar una imagen sin cortar los lados usando la función anterior:

Ejemplo 1:

A continuación se muestra la implementación de la versión de rotación modificada junto con su comparación con la versión de rotación normal:

Python3

# Importing Required Libraries
import cv2
import numpy as np
  
  
# The below function is for conventionally way of rotating
# an Image without preventing cutting off sides
def SimpleWay(rotateImage, angle):
    
    # Taking image height and width
    imgHeight, imgWidth = rotateImage.shape[0], rotateImage.shape[1]
  
    # Computing the centre x,y coordinates
    # of an image
    centreY, centreX = imgHeight//2, imgWidth//2
  
    # Computing 2D rotation Matrix to rotate an image
    rotationMatrix = cv2.getRotationMatrix2D((centreY, centreX), angle, 1.0)
  
    # Now, we will perform actual image rotation
    rotatingimage = cv2.warpAffine(
        rotateImage, rotationMatrix, (imgWidth, imgHeight))
  
    return rotatingimage
  
  
# The Below function is a modified version of the
# conventional way to rotate an image without
# cropping/cutting sides.
def ModifiedWay(rotateImage, angle):
    
    # Taking image height and width
    imgHeight, imgWidth = rotateImage.shape[0], rotateImage.shape[1]
  
    # Computing the centre x,y coordinates
    # of an image
    centreY, centreX = imgHeight//2, imgWidth//2
  
    # Computing 2D rotation Matrix to rotate an image
    rotationMatrix = cv2.getRotationMatrix2D((centreY, centreX), angle, 1.0)
  
    # Now will take out sin and cos values from rotationMatrix
    # Also used numpy absolute function to make positive value
    cosofRotationMatrix = np.abs(rotationMatrix[0][0])
    sinofRotationMatrix = np.abs(rotationMatrix[0][1])
  
    # Now will compute new height & width of
    # an image so that we can use it in
    # warpAffine function to prevent cropping of image sides
    newImageHeight = int((imgHeight * sinofRotationMatrix) +
                         (imgWidth * cosofRotationMatrix))
    newImageWidth = int((imgHeight * cosofRotationMatrix) +
                        (imgWidth * sinofRotationMatrix))
  
    # After computing the new height & width of an image
    # we also need to update the values of rotation matrix
    rotationMatrix[0][2] += (newImageWidth/2) - centreX
    rotationMatrix[1][2] += (newImageHeight/2) - centreY
  
    # Now, we will perform actual image rotation
    rotatingimage = cv2.warpAffine(
        rotateImage, rotationMatrix, (newImageWidth, newImageHeight))
  
    return rotatingimage
  
  
# Driver Code
  
# Loading an Image from Disk
DogImage = cv2.imread("doggy.png", 1)
  
  
# Performing 40 degree rotation
NormalRotation = SimpleWay(DogImage, 40)
ModifiedVersionRotation = ModifiedWay(DogImage, 40)
  
# Display image on Screen
cv2.imshow("Original Image", DogImage)
  
# Display rotated image on Screen
cv2.imshow("Normal Rotation", NormalRotation)
cv2.imshow("Modified Version Rotation", ModifiedVersionRotation)
  
  
# To hold the GUI screen and control until it is detected
# the input for closing it, Once it is closed
# control will be released
cv2.waitKey(0)
  
# To destroy and remove all created GUI windows from
#screen and memory
cv2.destroyAllWindows()

Producción:

Imagen original

Rotación normal con función SimpleWay()

Rotación con la función ModifiedWay()

Ejemplo 2:

Aquí hay otro ejemplo que representa el método de rotación moderno:

Python3

# Importing Required Libraries
import cv2
import numpy as np
  
  
# The Below function is a modified version of the
# conventional way to rotate an image without
# cropping/cutting sides.
def ModifiedWay(rotateImage, angle):
    
    # Taking image height and width
    imgHeight, imgWidth = rotateImage.shape[0], rotateImage.shape[1]
  
    # Computing the centre x,y coordinates
    # of an image
    centreY, centreX = imgHeight//2, imgWidth//2
  
    # Computing 2D rotation Matrix to rotate an image
    rotationMatrix = cv2.getRotationMatrix2D((centreY, centreX), angle, 1.0)
  
    # Now will take out sin and cos values from rotationMatrix
    # Also used numpy absolute function to make positive value
    cosofRotationMatrix = np.abs(rotationMatrix[0][0])
    sinofRotationMatrix = np.abs(rotationMatrix[0][1])
  
    # Now will compute new height & width of
    # an image so that we can use it in
    # warpAffine function to prevent cropping of image sides
    newImageHeight = int((imgHeight * sinofRotationMatrix) +
                         (imgWidth * cosofRotationMatrix))
    newImageWidth = int((imgHeight * cosofRotationMatrix) +
                        (imgWidth * sinofRotationMatrix))
  
    # After computing the new height & width of an image
    # we also need to update the values of rotation matrix
    rotationMatrix[0][2] += (newImageWidth/2) - centreX
    rotationMatrix[1][2] += (newImageHeight/2) - centreY
  
    # Now, we will perform actual image rotation
    rotatingimage = cv2.warpAffine(
        rotateImage, rotationMatrix, (newImageWidth, newImageHeight))
  
    return rotatingimage
  
  
# Driver Code
# Loading an Image from Disk
Image = cv2.imread("gfg.png", 1)
  
  
# Performing 40 degree rotation
ModifiedVersionRotation = ModifiedWay(Image, 40)
  
# Display image on Screen
cv2.imshow("Original Image", Image)
  
# Display rotated image on Screen
cv2.imshow("Modified Version Rotation", ModifiedVersionRotation)
  
  
# To hold the GUI screen and control until it is detected
# the input for closing it, Once it is closed
# control will be released
cv2.waitKey(0)
  
# To destroy and remove all created GUI windows from
#screen and memory
cv2.destroyAllWindows()

Producción:

Publicación traducida automáticamente

Artículo escrito por himanshukanojiya 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 *