I've figured out how to detect edges in an image using PIL (images will mostly be white background with black drawing marks). How can I detect the rectangle that encompasses these edges so that I can crop the image.
For example, I'd like to crop something like this:
into:
or this:
into:
I'm familiar with cropping in PIL except I don't know how to auto center around an object.
I've managed to detect the edges by doing the following:
from PIL import Image, ImageFilter
image = Image.open("myImage.png")
image = image.filter(ImageFilter.FIND_EDGES)
How would I get the rect containing all these edges?
You can do it e.g with opencv
import cv2
#Load the image in black and white (0 - b/w, 1 - color).
img = cv2.imread('input.png', 0)
#Get the height and width of the image.
h, w = img.shape[:2]
#Invert the image to be white on black for compatibility with findContours function.
imgray = 255 - img
#Binarize the image and call it thresh.
ret, thresh = cv2.threshold(imgray, 127, 255, cv2.THRESH_BINARY)
#Find all the contours in thresh. In your case the 3 and the additional strike
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
#Calculate bounding rectangles for each contour.
rects = [cv2.boundingRect(cnt) for cnt in contours]
#Calculate the combined bounding rectangle points.
top_x = min([x for (x, y, w, h) in rects])
top_y = min([y for (x, y, w, h) in rects])
bottom_x = max([x+w for (x, y, w, h) in rects])
bottom_y = max([y+h for (x, y, w, h) in rects])
#Draw the rectangle on the image
out = cv2.rectangle(img, (top_x, top_y), (bottom_x, bottom_y), (0, 255, 0), 2)
#Save it as out.jpg
cv2.imwrite('out.jpg', img)
Example output
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