| import cv2 import imutils from imutils.perspective import four_point_transform import matplotlib.pyplot as plt import numpy as np
# 读入图片 image = cv2.imread("/Users/xxx/Downloads/56112723-6a82-462c-96ad-df832a31f039.png")
mask = np.zeros(image.shape, dtype=np.uint8) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) blur = cv2.GaussianBlur(gray, (5, 5), 0) thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
# 检测水平直线 horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (50, 1)) detect_horizontal = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2) cnts = cv2.findContours(detect_horizontal, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = imutils.grab_contours(cnts) for c in cnts: cv2.drawContours(mask, [c], -1, (255, 255, 255), 3)
# 检测垂直直线 vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 50)) detect_vertical = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, vertical_kernel, iterations=2) cnts = cv2.findContours(detect_vertical, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = imutils.grab_contours(cnts) for c in cnts: cv2.drawContours(mask, [c], -1, (255, 255, 255), 3)
mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
# 寻找轮廓 cnts = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = imutils.grab_contours(cnts)
= None # 确保至少有一个轮廓被找到 if len(cnts) > 0: # 将轮廓按大小降序排序 cnts = sorted(cnts, key=cv2.contourArea, reverse=True)
# 对排序后的轮廓循环处理 for c in cnts: # 获取近似的轮廓 peri = cv2.arcLength(c, True) approx = cv2.approxPolyDP(c, 0.02 * peri, True)
# 如果我们的近似轮廓有四个顶点,那么就认为找到了答题卡 if len(approx) == 4: doc_cnt = approx break
# 对原始图像和灰度图都进行四点透视变换 paper = four_point_transform(image, doc_cnt.reshape(4, 2)) warped = four_point_transform(gray, doc_cnt.reshape(4, 2))
plt.figure('paper') plt.imshow(imutils.opencv2matplotlib(paper)) plt.show()
|