代码拉取完成,页面将自动刷新
同步操作将从 mynameisi/doc_scanner_homework 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
'''
"doc_scanner.py" 文件中的 DocScanner 类提供了文档扫描的核心功能,功能包括
- 加载图片
- 找到文档的角落
- 裁剪图片
- 通过将文档扫描功能封装在一个独立的类中,我们可以将其作为一个模块,方便在其他项目中重用。
- 这种模块化的设计使得代码更加模块化、可扩展和可测试。
- 它可以独立于其他部分进行开发、测试和维护,而不会对其他组件产生影响。
- 此外,将文档扫描功能单独放在一个文件中,使得代码结构更清晰、易于理解和维护。
- 通过将不同的功能分割到不同的文件中,我们可以更好地组织代码,减少文件的复杂性,并促进团队合作开发。
'''
import cv2 as cv
import numpy as np
class DocScanner:
def __init__(self):
pass
def load_image(self, file_path):
"""加载图片并找到文档的四个角落。"""
img = cv.imread(file_path)
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
thresh, binary_img = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY)
contours, hierarchy = cv.findContours(binary_img, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
max_area = 0
extreme_pnts = None
for contour in contours:
peri = cv.arcLength(contour, True)
approx = cv.approxPolyDP(contour, 0.02 * peri, True)
if len(approx) == 4:
area = cv.contourArea(approx)
if area > max_area:
max_area = area
extreme_pnts = approx
corners = self.order_points(extreme_pnts.reshape(4, 2))
return img, corners
def order_points(self, pts):
"""对给定的四个点进行排序,返回排序后的点。"""
rect = np.zeros((4, 2), dtype="float32")
s = pts.sum(axis=1)
rect[0] = pts[np.argmin(s)]
rect[2] = pts[np.argmax(s)]
diff = np.diff(pts, axis=1)
rect[1] = pts[np.argmin(diff)]
rect[3] = pts[np.argmax(diff)]
print(f"0:左上角:{rect[0]},因为x,y的坐标和是: np.min(s)={np.min(s)}")
print(f"1:右上角:{rect[1]},因为x,y的坐标差是: np.min(diff)={np.min(diff)}")
print(f"2:右下角:{rect[2]},因为x,y的坐标和是: np.max(s)={np.max(s)}")
print(f"3:左下角:{rect[3]},因为x,y的坐标差是: np.max(diff)={np.max(diff)}")
return rect
def crop_image(self, img, corners):
"""根据四个角落裁剪图片。"""
top_left_corner = corners[0]
top_right_corner = corners[1]
bottom_right_corner = corners[2]
bottom_left_corner = corners[3]
width, height = self.get_image_dimensions((top_left_corner, top_right_corner, bottom_right_corner, bottom_left_corner))
dst_points = np.array([
[0, 0],
[width - 1, 0],
[width - 1, height - 1],
[0, height - 1]
], dtype="float32")
matrix = cv.getPerspectiveTransform(corners.astype("float32"), dst_points)
dst = cv.warpPerspective(img, matrix, (width, height))
return dst
def get_image_dimensions(self, corners):
"""计算图片的宽度和高度。"""
top_left_corner, top_right_corner, bottom_right_corner, bottom_left_corner = corners
top_width = np.linalg.norm(top_right_corner - top_left_corner)
bottom_width = np.linalg.norm(bottom_right_corner - bottom_left_corner)
left_height = np.linalg.norm(bottom_left_corner - top_left_corner)
right_height = np.linalg.norm(bottom_right_corner - top_right_corner)
width = int(max(top_width, bottom_width))
height = int(max(left_height, right_height))
return width, height
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。