Reputation: 53
Basically, I have scanned in many old photos using our printer. About four photos fit on each page of the scan (around the four corners of the page), and the white space isn't always completely white. I want to use openCV to automatically crop them into individual photos. Need suggestions for a way to tackle this problem, thanks!
I thought about detecting the shape of the four rectangles on the page to get the coordinate or using opencv grabCut... I don't know
I've tried to use PIL, but couldn't crop the photos correctly since some photos also had the same color as the background which would cause the crop to end prematurely.
This is a rough sketch of what it looks like
(except they would be actual photos of people)
Upvotes: 4
Views: 2186
Reputation: 46680
Here's an approach based on the assumption that the photos will not be intersecting each other
Threshold image
Next we obtain the contours using cv2.findContours()
and grab the bounding boxes using cv2.boundingRect()
. We can then extract the ROIs with
x,y,w,h = cv2.boundingRect(c)
ROI = original[y:y+h, x:x+w]
Here's the results
Photo #1
Photo #2
Photo #3
Photo #4
import cv2
image = cv2.imread('1.png')
original = image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (3, 3), 0)
thresh = cv2.threshold(blurred, 230,255,cv2.THRESH_BINARY_INV)[1]
# Find contours
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
# Iterate thorugh contours and filter for ROI
image_number = 0
for c in cnts:
x,y,w,h = cv2.boundingRect(c)
cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 2)
ROI = original[y:y+h, x:x+w]
cv2.imwrite("ROI_{}.png".format(image_number), ROI)
image_number += 1
cv2.imshow('thresh', thresh)
cv2.imshow('image', image)
cv2.waitKey(0)
Upvotes: 4