| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 52 人关注过本帖
标题:一段代码,用于提取照片中的A4纸,拉升铺满为一A4大小的PDF
只看楼主 加入收藏
书生牛犊
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:星夜征程
等 级:贵宾
威 望:10
帖 子:1102
专家分:5265
注 册:2015-10-27
结帖率:93.75%
收藏
 问题点数:0 回复次数:0 
一段代码,用于提取照片中的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)






搜索更多相关主题的帖子: 保存 图像 照片 PDF image 
6 天前 20:53
快速回复:一段代码,用于提取照片中的A4纸,拉升铺满为一A4大小的PDF
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.027677 second(s), 9 queries.
Copyright©2004-2025, BC-CN.NET, All Rights Reserved