web-dev-qa-db-fra.com

Comment détecter Edge et recadrer une image dans Python

Je suis nouveau dans le traitement d'images en Python et j'essaie de résoudre un problème commun. J'ai une image avec la signature d'une personne. Je veux trouver les bords et les recadrer pour adapter la signature dans l'image.

Image d'entrée

enter image description here

Production attendue

enter image description here

J'ai essayé Canny Edge Detection et recadrer l'image en utilisant une liste de solutions existantes (articles et réponses) en utilisant PIL, CV2, mais aucune ne semble fonctionner. Je cherche une solution de travail.

Quelques solutions que j'ai essayées:

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

  2. Recadrer l'image de tous les côtés après la détection du bord

  3. Comment recadrer le plus grand rectangle d'une image

et bien d'autres ... Aucun n'a fonctionné bien que cela semble très simple. J'ai rencontré des erreurs ou une sortie non attendue en utilisant l'une des solutions existantes.

9
Kartik Rokde

Ce dont vous avez besoin, c'est de seuillage. Dans OpenCV, vous pouvez accomplir cela en utilisant cv2.threshold() .

J'ai pris une photo. Mon approche était la suivante:

  1. Convertir en niveaux de gris
  2. Seuil de l'image pour obtenir uniquement la signature et rien d'autre
  3. Trouvez où se trouvent ces pixels qui apparaissent dans l'image seuil
  4. Recadrez cette région en niveaux de gris d'origine
  5. Créez une nouvelle image seuillée à partir du recadrage qui n'est pas aussi stricte pour l'affichage

Voici ma tentative, je pense que cela a plutôt bien fonctionné.

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)

Et voici le résultat: Cropped signature with thresholding

22
alkasm