I have taken some pictures of index cards but now I have the problem that the photographing was not perfect of course and there is a black border on each photo. I would like to crop the photo so that only the index card is left without a border.
Online I could find a similar problem, but it was only about computer images, so you could assume that the black had RGB (0,0,0), which is not the case with me. In the middle there is also black text, which I don't want to cut out.
Do you have any ideas how I can approach this?
Here is an example picture (it is in German):
解决方案
The idea is to threshold the image to obtain a binary image then find contours and sort using contour area. The largest contour should be the index card. We can then apply a four point perspective transform to obtain a birds eye view of the image. Here's the results:
Binary image
Result
I'll leave these steps to you :)
Code
from imutils.perspective import four_point_transform
import cv2
import numpy
# Load image, grayscale, Gaussian blur, Otsu's threshold
image = cv2.imread("1.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (5,5), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
# Find contours and sort for largest contour
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)
displayCnt = None
for c in cnts:
# Perform contour approximation
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02 * peri, True)
if len(approx) == 4:
displayCnt = approx
break
# Obtain birds' eye view of image
warped = four_point_transform(image, displayCnt.reshape(4, 2))
cv2.imshow("thresh", thresh)
cv2.imshow("warped", warped)
cv2.imshow("image", image)
cv2.imwrite("thresh.png", thresh)
cv2.imwrite("warped.png", warped)
cv2.imwrite("image.png", image)
cv2.waitKey()