En este tutorial, aprenderá cómo procesar imágenes en Python usando la biblioteca OpenCV.

OpenCV es una biblioteca gratuita de código abierto que se utiliza en el procesamiento de imágenes en tiempo real. Se usa para procesar imágenes, videos e incluso transmisiones en vivo, pero en este tutorial, procesaremos imágenes solo como un primer paso. Antes de comenzar, instalemos OpenCV.

Instalar OpenCV

Para instalar OpenCV en su sistema, ejecute el siguiente comando pip :

pip instalar opencv-python

Imagen de Python

Ahora OpenCV se instaló correctamente y estamos listos. ¡Divirtámonos con algunas imágenes!

Rotar una imagen

En primer lugar, importe el módulo cv2.

importar cv2

Ahora, para leer la imagen, utilice el método imread () del módulo cv2, especifique la ruta a la imagen en los argumentos y almacene la imagen en una variable como se muestra a continuación:

img = cv2.imread ("pyimg.jpg")

La imagen ahora se trata como una matriz con valores de filas y columnas almacenados en img.

En realidad, si marca el tipo de img, le dará el siguiente resultado:

1
2
3
>>>print(type(img))
 
<class 'numpy.ndarray'>

¡Es una matriz NumPy ! Es por eso que el procesamiento de imágenes con OpenCV es tan fácil. Todo el tiempo está trabajando con una matriz NumPy.

Para mostrar la imagen, puede utilizar el método imshow () de cv2.

1
2
3
cv2.imshow('Original Image', img)
 
cv2.waitKey(0)

Las funciones de la tecla de espera toman tiempo como un argumento en milisegundos como un retraso para que se cierre la ventana. Aquí configuramos el tiempo a cero para mostrar la ventana para siempre hasta que la cerremos manualmente.

Imagen de Python

Para rotar esta imagen, necesitas el ancho y el alto de la imagen porque los usarás en el proceso de rotación como verás más adelante.

alto, ancho = img.shape [0: 2]

El atributo de forma devuelve la altura y el ancho de la matriz de la imagen. Si imprime img.shape [0: 2], obtendrá el siguiente resultado:

Bien, ahora tenemos nuestra matriz de imágenes y queremos obtener la matriz de rotación. Para obtener la matriz de rotación, usamos el método getRotationMatrix2D () de cv2. La sintaxis de getRotationMatrix2D () es:

cv2.getRotationMatrix2D (centro, ángulo, escala)

Aquí el centro es el punto central de rotación, el ángulo es el ángulo en grados y la escala es la propiedad de escala que hace que la imagen se ajuste a la pantalla.

Para obtener la matriz de rotación de nuestra imagen, el código será:

RotationMatrix = cv2.getRotationMatrix2D ((ancho / 2, alto / 2), 90, .5)

El siguiente paso es rotar nuestra imagen con la ayuda de la matriz de rotación.

Para rotar la imagen, tenemos un método cv2 llamado wrapAffine que toma la imagen original, la matriz de rotación de la imagen y el ancho y alto de la imagen como argumentos.

rotatedImage = cv2.warpAffine (img, rotacionMatrix, (ancho, alto))

La imagen rotada se almacena en la matriz rotatedImage. Para mostrar la imagen, use imshow () como se muestra a continuación:

1
2
3
cv2.imshow('Rotated Image', rotatedImage)
 
cv2.waitKey(0)

Después de ejecutar las líneas de código anteriores, tendrá el siguiente resultado:

Imagen de Python

Recortar una imagen

Primero, necesitamos importar el módulo cv2 y leer la imagen y extraer el ancho y alto de la imagen:

1
2
3
4
5
import cv2
 
img = cv2.imread("pyimg.jpg")
 
height, width = img.shape[0:2]

Ahora obtenga el índice inicial y final de la fila y la columna. Esto definirá el tamaño de la imagen recién creada. Por ejemplo, comenzar desde la fila número 10 hasta la fila número 15 dará la altura de la imagen.

Del mismo modo, comience desde la columna número 10 hasta la columna número 15 le dará el ancho de la imagen.

Puede obtener el punto de partida especificando el valor porcentual de la altura total y el ancho total. De manera similar, para obtener el punto final de la imagen recortada, especifique los valores porcentuales como se muestra a continuación:

1
2
3
4
5
6
7
startRow = int(height*.15)
 
startCol = int(width*.15)
 
endRow = int(height*.85)
 
endCol = int(width*.85)

Ahora mapee estos valores a la imagen original. Tenga en cuenta que debe convertir los valores inicial y final en números enteros porque, al mapear, los índices son siempre números enteros.

croppedImage = img [startRow: endRow, startCol: endCol]

Aquí especificamos el rango desde el inicio hasta el final de filas y columnas.

Ahora muestre la imagen original y recortada en la salida:

1
2
3
4
5
cv2.imshow('Original Image', img)
 
cv2.imshow('Cropped Image', croppedImage)
 
cv2.waitKey(0)

El resultado será el siguiente:

Imagen de Python

Cambiar el tamaño de una imagen

Para cambiar el tamaño de una imagen, puede utilizar el método resize () de openCV. En el método de cambio de tamaño, puede especificar los valores de los ejes xey o el número de filas y columnas que indica el tamaño de la imagen.

Importa y lee la imagen:

1
2
3
import cv2
 
img = cv2.imread("pyimg.jpg")

Ahora usando el método de cambio de tamaño con valores de eje:

1
2
3
4
5
newImg = cv2.resize(img, (0,0), fx=0.75, fy=0.75)
 
cv2.imshow('Resized Image', newImg)
 
cv2.waitKey(0)

El resultado será el siguiente:

Imagen de Python

Ahora usando los valores de fila y columna para cambiar el tamaño de la imagen:

1
2
3
4
5
newImg = cv2.resize(img, (550, 350))
 
cv2.imshow('Resized Image', newImg)
 
cv2.waitKey(0)

Decimos que queremos 550 columnas (el ancho) y 350 filas (el alto).

El resultado será:

Imagen de Python

Ajustar el contraste de la imagen

En el módulo Python OpenCV, no hay una función particular para ajustar el contraste de la imagen, pero la documentación oficial de OpenCV sugiere una ecuación que puede realizar el brillo de la imagen y el contraste de la imagen al mismo tiempo.

nueva_img = a * original_img + b

Aquí es alfa que define el contraste de la imagen. Si a es mayor que 1, habrá mayor contraste.

Si el valor de a está entre 0 y 1 (menor que 1 pero mayor que 0), el contraste sería menor. Si a es 1, no habrá efecto de contraste en la imagen.

b significa beta. Los valores de b varían de -127 a +127.

Para implementar esta ecuación en Python OpenCV, puede usar el método addWeighted (). Usamos el método addWeighted () ya que genera la salida en el rango de 0 y 255 para una imagen en color de 24 bits.

La sintaxis del método addWeighted () es la siguiente:

cv2.addWeighted (source_img1, alpha1, source_img2, alpha2, beta)

Esta sintaxis combinará dos imágenes, la primera imagen de origen (source_img1) con un peso de alpha1 y la segunda imagen de origen (source_img2).

Si solo desea aplicar contraste en una imagen, puede agregar una segunda fuente de imagen como ceros usando NumPy.

Trabajemos en un ejemplo sencillo. Importe los siguientes módulos:

1
2
3
import cv2
 
import numpy as np

Lea la imagen original:

img = cv2.imread ("pyimg.jpg")

Ahora aplica el contraste. Como no hay otra imagen, usaremos np.zeros que creará una matriz de la misma forma y tipo de datos que la imagen original, pero la matriz se rellenará con ceros.

1
2
3
4
5
6
7
contrast_img = cv2.addWeighted(img, 2.5, np.zeros(img.shape, img.dtype), 0, 0)
 
cv2.imshow('Original Image', img)
 
cv2.imshow('Contrast Image', contrast_img)
 
cv2.waitKey(0)

En el código anterior, el brillo se establece en 0 ya que solo queremos aplicar contraste.

La comparación de la imagen original y de contraste es la siguiente:

Imagen de Python

Hacer una imagen borrosa

Desenfoque gaussiano

Para hacer una imagen borrosa, puede usar el método GaussianBlur () de OpenCV.

GaussianBlur () usa el kernel gaussiano. La altura y el ancho del núcleo deben ser un número positivo e impar.

Luego, debe especificar la dirección X e Y que es sigmaX y sigmaY respectivamente. Si solo se especifica uno, ambos se consideran iguales.

Considere el siguiente ejemplo:

01
02
03
04
05
06
07
08
09
10
11
import cv2
 
img = cv2.imread("pyimg.jpg")
 
blur_image = cv2.GaussianBlur(img, (7,7), 0)
 
cv2.imshow('Original Image', img)
 
cv2.imshow('Blur Image', blur_image)
 
cv2.waitKey(0)

En el fragmento anterior, la imagen real se pasa a GaussianBlur () junto con la altura y el ancho del kernel y las direcciones X e Y.

La comparación de la imagen original y borrosa es la siguiente:

Imagen de Python

Desenfoque medio

En el desenfoque medio, la mediana de todos los píxeles de la imagen se calcula dentro del área del kernel. Luego, el valor central se reemplaza con el valor mediano resultante. El desenfoque medio se utiliza cuando hay ruido de sal y pimienta en la imagen.

Para aplicar el desenfoque medio, puede utilizar el método medianBlur () de OpenCV.

Considere el siguiente ejemplo donde tenemos un ruido de sal y pimienta en la imagen:

1
2
3
4
5
import cv2
 
img = cv2.imread("pynoise.png")
 
blur_image = cv2.medianBlur(img,5)

Esto aplicará un 50% de ruido en la imagen junto con un desenfoque medio. Ahora muestra las imágenes:

1
2
3
4
5
cv2.imshow('Original Image', img)
 
cv2.imshow('Blur Image', blur_image)
 
cv2.waitKey(0)

El resultado será como el siguiente:

Imagen de Python

Otra comparación de la imagen original y después de desenfocar:

Imagen de Python

Detectar bordes

Para detectar los bordes en una imagen, puede usar el método Canny () de cv2 que implementa el detector de bordes Canny. El detector de bordes Canny también se conoce como el detector óptimo .

La sintaxis de Canny () es la siguiente:

cv2.Canny (imagen, minVal, maxVal)

Aquí, minVal y maxVal son los valores de gradiente de intensidad mínimo y máximo, respectivamente.

Considere el siguiente código:

1
2
3
4
5
6
7
8
9
import cv2
 
img = cv2.imread("pyimg.jpg")
 
edge_img = cv2.Canny(img,100,200)
 
cv2.imshow("Detected Edges", edge_img)
 
cv2.waitKey(0)

La salida será la siguiente:

Imagen de Python

Aquí está el resultado del código anterior en otra imagen:

Imagen de Python

Convertir imagen a escala de grises (blanco y negro)

La forma más sencilla de convertir una imagen en escala de grises es cargarla así:

img = cv2.imread ("pyimg.jpg", 0)

Hay otro método que usa BGR2GRAY.

Para convertir una imagen en color en una imagen en escala de grises, use el atributo BGR2GRAY del módulo cv2. Esto se demuestra en el siguiente ejemplo:

Importe el módulo cv2:

importar cv2

Leer la imagen:

img = cv2.imread ("pyimg.jpg")

Utilice el método cvtColor () del módulo cv2 que toma la imagen original y el atributo COLOR_BGR2GRAY como argumento. Almacene la imagen resultante en una variable:

gray_img = cv2.cvtColor (img, cv2.COLOR_BGR2GRAY)

Visualice las imágenes originales y en escala de grises:

1
2
3
4
5
cv2.imshow("Original Image", img)
 
cv2.imshow("Gray Scale Image", gray_img)
 
cv2.waitKey(0)

La salida será la siguiente:

Imagen de Python

Detección de centroides (centro de blob)

Para encontrar el centro de una imagen, el primer paso es convertir la imagen original a escala de grises. Podemos usar el método cvtColor () de cv2 como lo hicimos antes.

Esto se demuestra en el siguiente código:

1
2
3
4
5
import cv2
 
img = cv2.imread("py.jpg")
 
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

Leemos la imagen y la convertimos en una imagen en escala de grises. La nueva imagen se almacena en gray_img.

Ahora tenemos que calcular los momentos de la imagen. Utilice el método de momentos () de cv2. En el método momentos (), la imagen en escala de grises se pasará de la siguiente manera:

momento = cv2.moments (gray_img)

Luego, necesitamos calcular las coordenadas xey del centro de la imagen usando los momentos que obtuvimos arriba:

1
2
3
X = int(moment ["m10"] / moment["m00"])
 
Y = int(moment ["m01"] / moment["m00"])

Finalmente, tenemos el centro de la imagen. Para resaltar esta posición central, podemos usar el método del círculo que creará un círculo en las coordenadas dadas del radio dado.

El método circle () toma el img, las coordenadas xey donde se creará el círculo, el tamaño, el color que queremos que tenga el círculo y el grosor.

cv2.circle (img, (X, Y), 15, (205, 114, 101), 1)

El círculo se crea en la imagen.

1
2
3
cv2.imshow("Center of the Image", img)
 
cv2.waitKey(0)

La imagen original es:

Imagen de Python

Después de detectar el centro, nuestra imagen será la siguiente:

Imagen de Python

Aplicar una máscara para una imagen en color.

El enmascaramiento de imágenes significa aplicar alguna otra imagen como máscara en la imagen original o cambiar los valores de píxeles en la imagen.

Para aplicar una máscara en la imagen, usaremos el método HoughCircles () del módulo OpenCV. El método HoughCircles () detecta los círculos en una imagen. Después de detectar los círculos, simplemente podemos aplicar una máscara en estos círculos.

El método HoughCircles () toma la imagen original, el gradiente de Hough (que detecta la información del gradiente en los bordes del círculo) y la información de la siguiente ecuación del círculo:

(x - xcentro) 2 + (y - ycentro) 2 = r2

En esta ecuación (x centro , y centro ) es el centro del círculo y r es el radio del círculo.

Nuestra imagen original es:

Imagen de Python

Después de detectar círculos en la imagen, el resultado será:

Imagen de Python

Bien, tenemos los círculos en la imagen y podemos aplicar la máscara. Considere el siguiente código:

1
2
3
4
5
6
7
import cv2
 
import numpy as np
 
img1 = cv2.imread('pyimg.jpg')
 
img1 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

Detectando los círculos en la imagen usando el código HoughCircles () de OpenCV: Hough Circle Transform :

1
2
3
4
5
gray_img = cv2.medianBlur(cv2.cvtColor(img, cv2.COLOR_RGB2GRAY), 3)
 
circles = cv2.HoughCircles(gray_img, cv2.HOUGH_GRADIENT, 1, 20, param1=50, param2=50, minRadius=0, maxRadius=0)
 
circles = np.uint16(np.around(circles))

Para crear la máscara, use np.full que devolverá una matriz NumPy de la forma dada:

1
2
3
4
5
masking=np.full((img1.shape[0], img1.shape[1]),0,dtype=np.uint8)
 
for j in circles[0, :]:
 
    cv2.circle(masking, (j[0], j[1]), j[2], (255, 255, 255), -1)

El siguiente paso es combinar la imagen y la matriz de enmascaramiento que creamos usando el operador bitwise_or de la siguiente manera:

final_img = cv2.bitwise_or (img1, img1, masking = masking)

Muestre la imagen resultante:

Imagen de Python

Extraer texto de una imagen (OCR)

Para extraer texto de una imagen, puede utilizar Google Tesseract-OCR. Puedes descargarlo desde este enlace

Luego, debe instalar el módulo pytesseract, que es un contenedor de Python para Tesseract-OCR.

pip instalar pytesseract

Imagen de Python

La imagen de la que extraeremos el texto es la siguiente:

Imagen de Python

Ahora convierta el texto de esta imagen en una cadena de caracteres y mostremos el texto como una cadena en la salida:

Importe el módulo pytesseract:

importar pytesseract

Establezca la ruta del archivo ejecutable Tesseract-OCR:

pytesseract.pytesseract.tesseract_cmd = r'C: \ Archivos de programa (x86) \ Tesseract-OCR \ tesseract '

Ahora use el método image_to_string para convertir la imagen en una cadena:

imprimir (pytesseract.image_to_string ('pytext.png'))

La salida será la siguiente:

Imagen de Python

¡Funciona a las mil maravillas!

Detectar y corregir la inclinación del texto

En esta sección, corregiremos el sesgo del texto.

La imagen original es la siguiente:

Imagen de Python

Importa los módulos cv2, NumPy y lee la imagen:

1
2
3
4
5
import cv2
 
import numpy as np
 
img = cv2.imread("pytext1.png")

Convierta la imagen en una imagen en escala de grises:

gray_img = cv2.cvtColor (img, cv2.COLOR_BGR2GRAY)

Invertir la imagen en escala de grises usando bitwise_not :

gray_img = cv2.bitwise_not (gray_img)

Seleccione las coordenadas xey de los píxeles mayores que cero utilizando el método column_stack de NumPy:

coordenadas = np.column_stack (np.where (gray_img> 0))

Ahora tenemos que calcular el ángulo de inclinación. Usaremos el método minAreaRect () de cv2 que devuelve un rango de ángulo de -90 a 0 grados (donde 0 no está incluido).

ang = cv2.minAreaRect (coordenadas) [- 1]

El ángulo girado de la región de texto se almacenará en la variable ang. Ahora agregamos una condición para el ángulo; si el ángulo de la región del texto es menor que -45, agregaremos 90 grados; de lo contrario, multiplicaremos el ángulo por menos para hacer que el ángulo sea positivo.

1
2
3
4
5
6
7
if ang<-45:
 
    ang=-(90+ang)
 
else:
 
    ang=-ang

Calcule el centro de la región del texto:

1
2
3
height, width = img.shape[:2]
 
center_img = (width / 2, height / 2)

Ahora que tenemos el ángulo de inclinación del texto, aplicaremos getRotationMatrix2D () para obtener la matriz de rotación y luego usaremos el método wrapAffine () para rotar el ángulo (explicado anteriormente).

1
2
3
rotationMatrix = cv2.getRotationMatrix2D(center, angle, 1.0)
 
rotated_img = cv2.warpAffine(img, rotationMatrix, (width, height), borderMode = cv2.BORDER_REFLECT)

Mostrar la imagen rotada:

1
2
3
cv2.imshow("Rotated Image", rotated_img)
 
cv2.waitKey(0)
Imagen de Python

Detección de color

Detectemos el color verde de una imagen:

Importe los módulos cv2 para imágenes y NumPy para matrices de imágenes:

1
2
3
import cv2
 
import numpy as np

Lea la imagen y conviértala en HSV usando cvtColor ():

1
2
3
img = cv2.imread("pydetect.png")
 
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

Mostrar la imagen:

cv2.imshow ("Imagen HSV", hsv_img)

Imagen de Python

Ahora cree una matriz NumPy para los valores verdes inferiores y los valores verdes superiores:

1
2
3
lower_green = np.array([34, 177, 76])
 
upper_green = np.array([255, 255, 255])

Use el método inRange () de cv2 para verificar si los elementos de la matriz de imágenes dados se encuentran entre los valores de la matriz de los límites superior e inferior:

masking = cv2.inRange (hsv_img, lower_green, upper_green)

Esto detectará el color verde.

Finalmente, muestre las imágenes originales y resultantes:

cv2.imshow ("Imagen original", img)

Imagen de Python
1
2
3
cv2.imshow("Green Color detection", masking)
 
cv2.waitKey(0)
Imagen de Python

Reduce el ruído

Para reducir el ruido de una imagen, OpenCV proporciona los siguientes métodos:

  1. fastNlMeansDenoising (): elimina el ruido de una imagen en escala de grises
  2. fastNlMeansDenoisingColored (): elimina el ruido de una imagen en color
  3. fastNlMeansDenoisingMulti (): elimina el ruido de los fotogramas de la imagen en escala de grises (un video en escala de grises)
  4. fastNlMeansDenoisingColoredMulti (): Igual que 3 pero funciona con marcos de colores

Usemos fastNlMeansDenoisingColored () en nuestro ejemplo:

Importe el módulo cv2 y lea la imagen:

1
2
3
import cv2
 
img = cv2.imread("pyn1.png")

Aplique la función de eliminación de ruido que toma respectivamente la imagen original (src), el destino (que no hemos guardado ya que estamos almacenando el resultado), la fuerza del filtro, el valor de la imagen para eliminar el ruido de color (generalmente igual a la fuerza del filtro o 10 ), el tamaño del parche de la plantilla en píxeles para calcular los pesos que siempre deben ser impares (el tamaño recomendado es igual a 7) y el tamaño de la ventana en píxeles para calcular el promedio del píxel dado.

resultado = cv2.fastNlMeansDenoisingColored (img, Ninguno, 20,10,7,21)

Mostrar imagen original y sin ruido:

1
2
3
4
5
cv2.imshow("Original Image", img)
 
cv2.imshow("Denoised Image", result)
 
cv2.waitKey(0)

La salida será:

Imagen de Python

Obtener contorno de imagen

Los contornos son las curvas de una imagen que se unen. Las curvas unen los puntos continuos en una imagen. El propósito de los contornos se utiliza para detectar los objetos.

La imagen original de la que obtenemos los contornos se muestra a continuación:

Imagen de Python

Considere el siguiente código donde usamos el método findContours () para encontrar los contornos en la imagen:

Importar módulo cv2:

importar cv2

Lea la imagen y conviértala en una imagen en escala de grises:

1
2
3
img = cv2.imread('py1.jpg')
 
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

Encuentra el umbral:

retval, thresh = cv2.threshold (gray_img, 127, 255, 0)

Use findContours () que toma la imagen (pasamos el umbral aquí) y algunos atributos. Consulte findContours () Official .

img_contours, _ = cv2.findContours (thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

Dibuja los contornos en la imagen usando el método drawContours ():

cv2.drawContours (img, img_contours, -1, (0, 255, 0))

Mostrar la imagen:

1
2
3
cv2.imshow('Image Contours', img)
 
cv2.waitKey(0)

El resultado será:

Imagen de Python

Eliminar el fondo de una imagen

Para eliminar el fondo de una imagen, encontraremos los contornos para detectar los bordes del objeto principal y crearemos una máscara con np.zeros para el fondo y luego combinaremos la máscara y la imagen usando el operador bitwise_and .

Considere el siguiente ejemplo:

Importa los módulos (NumPy y cv2):

1
2
3
import cv2
 
import numpy as np

Lea la imagen y convierta la imagen en una imagen en escala de grises:

1
2
3
img = cv2.imread("py.jpg")
 
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

Encuentra el umbral:

_, thresh = cv2.threshold (gray_img, 127, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

En el método del umbral (), el último argumento define el estilo del umbral. Consulte la documentación oficial del umbral OpenCV .

Encuentra los contornos de la imagen:

img_contours = cv2.findContours (trillado, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) [- 2]

Ordenar los contornos:

1
2
3
4
5
6
7
img_contours = sorted(img_contours, key=cv2.contourArea)
 
for i in img_contours:
 
    if cv2.contourArea(i) > 100:
 
        break

Genere la máscara usando np.zeros:

máscara = np.zeros (img.shape [: 2], np.uint8)

Dibujar contornos:

cv2.drawContours (máscara, [i], - 1, 255, -1)

Aplicar el operador bitwise_and:

new_img = cv2.bitwise_and (img, img, máscara = máscara)

Mostrar la imagen original:

cv2.imshow ("Imagen original", img)

Imagen de Python

Muestre la imagen resultante:

1
2
3
cv2.imshow("Image with background removed", new_img)
 
cv2.waitKey(0)
Imagen de Python

El procesamiento de imágenes es divertido cuando se usa OpenCV como vio. Espero que el tutorial te resulte útil. Sigue regresando.

Gracias.