Cómo detectar bordes y recortar una imagen en Python

Soy nuevo en Image Processing en Python y estoy tratando de resolver un problema común. Tengo una imagen con la firma de una persona. Quiero encontrar los bordes y recortarlos para que se ajusten a la firma en la imagen.

Imagen de entrada

introduzca la descripción de la imagen aquí

Rendimiento esperado

introduzca la descripción de la imagen aquí

Probé la detección de Canny Edge y recorté la imagen usando una lista de soluciones existentes (artículos y respuestas) usando PIL, CV2, pero ninguna parece funcionar. Estoy buscando una solución de trabajo.

Algunas soluciones que probé:

  1. https://www.quora.com/How-can-I-detect-an-object-from-static-image-and-crop-it-from-the-image-using-openCV

  2. Recortar imagen desde todos los lados después de la detección de bordes

  3. Cómo recortar el rectángulo más grande de una imagen

y muchos más … Ninguno funcionó aunque parece muy simple. Encontré errores o resultados no esperados utilizando cualquiera de las soluciones existentes.

Lo que necesitas es un umbral. En OpenCV puedes lograr esto usando cv2.threshold() .

Le di un tiro. Mi enfoque fue el siguiente:

  1. Convertir a escala de grises
  2. Umbral de la imagen para obtener solo la firma y nada más.
  3. Encuentra dónde están esos píxeles que aparecen en la imagen del umbral
  4. Cultivo alrededor de esa región en la escala de grises original
  5. Cree una nueva imagen de umbral del recorte que no sea tan estricta para la visualización

Aquí fue mi bash, creo que funcionó bastante bien.

 import cv2 import numpy as np # load image img = cv2.imread('image.jpg') rsz_img = cv2.resize(img, None, fx=0.25, fy=0.25) # resize since image is huge gray = cv2.cvtColor(rsz_img, cv2.COLOR_BGR2GRAY) # convert to grayscale # threshold to get just the signature retval, thresh_gray = cv2.threshold(gray, thresh=100, maxval=255, type=cv2.THRESH_BINARY) # find where the signature is and make a cropped region points = np.argwhere(thresh_gray==0) # find where the black pixels are points = np.fliplr(points) # store them in x,y coordinates instead of row,col indices x, y, w, h = cv2.boundingRect(points) # create a rectangle around those points x, y, w, h = x-10, y-10, w+20, h+20 # make the box a little bigger crop = gray[y:y+h, x:x+w] # create a cropped region of the gray image # get the thresholded crop retval, thresh_crop = cv2.threshold(crop, thresh=200, maxval=255, type=cv2.THRESH_BINARY) # display cv2.imshow("Cropped and thresholded image", thresh_crop) cv2.waitKey(0) 

Y aquí está el resultado: Firma recortada con umbral