I'm new to Image Processing in Python and I'm trying to solve a common problem. I have an image having a signature of a person. I want to find the edges and crop it to fit the signature in the image.
I tried Canny Edge Detection and cropping the image using a list of existing solutions (articles & answers) using PIL, CV2, but none seem to work. I'm looking for a working solution.
Some solutions I tried:
https://www.quora.com/How-can-I-detect-an-object-from-static-image-and-crop-it-from-the-image-using-openCV
Crop Image from all sides after edge detection
How to crop biggest rectangle out of an image
and many more... None worked although seems very simple. I encountered either errors or not expected output using any of the existing solutions.
Edge Detection, is an Image Processing discipline that incorporates mathematics methods to find edges in a Digital Image. Edge Detection internally works by running a filter/Kernel over a Digital Image, which detects discontinuities in Image regions like stark changes in brightness/Intensity value of pixels.
use findContours or extract all mask points (manually) and use the minBoundingRect function. Afterwards use subimage to get the cropped image.
Canny Edge detection is an Algorithm consisting of 4 major steps: Reduce Noise using Gaussian Smoothing. Compute image gradient using Sobel filter. Apply Non-Max Suppression or NMS to just jeep the local maxima.
What you need is thresholding. In OpenCV you can accomplish this using cv2.threshold()
.
I took a shot at it. My approach was the following:
Here was my attempt, I think it worked pretty well.
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)
And here's the result:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With