I'm trying to write a program in Python that can mark exam papers using opencv and imutils, I have attached an example. I'm trying to get a top down view of the page but it's not detecting the right contours.Contours drawn imutils four_point_transform applied I would like it to apply the function to the whole page and not to the questions. Is it possible to use the corner borders for four_point_transform? It may not be very visible so here is the original image.
# Import libraries
import cv2
import numpy as np
import imutils
from imutils import contours
from imutils.perspective import four_point_transform
# Verify exam sheet location
image = cv2.imread("test4.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (5, 5), 0)
edge = cv2.Canny(blur, 100, 200)
# Locate contours
contours = cv2.findContours(edge.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
contours = imutils.grab_contours(contours)
docCnt = None
# Verify main object is exam
if len(contours) > 0:
contours = sorted(contours, key=cv2.contourArea, reverse=True)
for c in contours:
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02 * peri, True)
if len(approx) == 4:
docCnt = approx
break
# Create a top-down view of paper
paper = four_point_transform(image, docCnt.reshape(4,2))
warped = four_point_transform(edge, docCnt.reshape(4,2))
# Draw contours
cv2.drawContours(image, contours, -1, (0,255,0), 3)
cv2.imwrite("Contours.jpg", image)
# Display images
cv2.imshow("Original", image)
# cv2.imshow("Perspective", paper)
# cv2.imshow("Processed", edge)
# cv2.imshow("Processed + Perspective", warped)
cv2.waitKey(0)
cv2.destroyAllWindows
The contour just needed a bit of dilating and then it was able to capture the paper in itself. Here is the code:
In the above code, I went through a standard canny edge detection. Then, I got the approximation of the contour:
Plotting, I got the following results:
Maybe think also a bit about stretching to make the aspect ratio a bit better. This is a nice tutorial as well
V2.0:Using imutils
As you can see from the function, all you require for the function are the image itself and the coordinates of the detected corner. Hence, here is the adjusted code:
Here is the result, the nice addition is that the imutils function additionally scales the results.