一段代码,用于提取照片中的A4纸,拉升铺满为一A4大小的PDF
注意传入的图片需要提前将图片旋转角度,使之上下窄边,左右为纸张的宽边。因为最后的PDF拉升就是按照这样的A4比例去啦,如果传入的照片里的纸张是横的,就会使最终的PDF被拉伸失真。。。
import cv2 import numpy as np from fpdf import FPDF import os def correct_perspective(image_path, output_pdf_path): # 读取图像 image = cv2.imread(image_path) if image is None: print("无法读取图像,请检查路径是否正确。") return # 转换为灰度图 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 高斯模糊 blurred = cv2.GaussianBlur(gray, (5, 5), 0) # 边缘检测 edged = cv2.Canny(blurred, 50, 150) # 查找轮廓 contours, _ = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) contours = sorted(contours, key=cv2.contourArea, reverse=True)[:5] # 找到文档的轮廓 for contour in contours: peri = cv2.arcLength(contour, True) approx = cv2.approxPolyDP(contour, 0.02 * peri, True) if len(approx) == 4: doc_contour = approx break # 如果没有找到四边形轮廓,直接保存原图 if 'doc_contour' not in locals(): print("未找到文档轮廓,保存原图。") cv2.imwrite(output_pdf_path.replace('.pdf', '.jpg'), image) return # 透视变换 def order_points(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)] return rect def four_point_transform(image, pts): rect = order_points(pts) (tl, tr, br, bl) = rect widthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2)) widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2)) maxWidth = max(int(widthA), int(widthB)) heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2)) heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2)) maxHeight = max(int(heightA), int(heightB)) dst = np.array([ [0, 0], [maxWidth - 1, 0], [maxWidth - 1, maxHeight - 1], [0, maxHeight - 1]], dtype="float32") M = cv2.getPerspectiveTransform(rect, dst) warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight)) return warped warped = four_point_transform(image, doc_contour.reshape(4, 2)) # 保存矫正后的图像 corrected_image_path = output_pdf_path.replace('.pdf', '.jpg') cv2.imwrite(corrected_image_path, warped) # 将图像转换为PDF并铺满A4纸张 pdf = FPDF(format='A4') # 设置PDF为A4尺寸 pdf.add_page() # 获取A4纸张的尺寸(单位:毫米) a4_width = 210 a4_height = 297 # 将图像铺满A4纸张 pdf.image(corrected_image_path, x=0, y=0, w=a4_width, h=a4_height) # 保存PDF pdf.output(output_pdf_path, "F") # 删除临时图像文件 os.remove(corrected_image_path) print(f"PDF文件已保存到:{output_pdf_path}") # 使用示例 image_path = "path_to_your_image.jpg" # 替换为你的图片路径 output_pdf_path = os.path.join(os.path.expanduser("~"), "Desktop", "corrected_document.pdf") correct_perspective(image_path, output_pdf_path)