Python入门项目首选:打造个人卡证信息管理小工具

张开发
2026/4/8 12:25:56 15 分钟阅读

分享文章

Python入门项目首选:打造个人卡证信息管理小工具
Python入门项目首选打造个人卡证信息管理小工具想找个Python入门项目练手却总在“学生管理系统”和“爬虫”之间打转今天咱们换个思路做一个既实用又有趣还能让你把Python基础知识串起来的小工具——个人卡证信息管理工具。想象一下你有一堆身份证、银行卡、驾照的照片散落在手机相册里找起来麻烦信息也不安全。这个项目就是帮你解决这个问题的拍张照工具自动帮你把歪斜的卡片矫正、摆正然后把矫正后的图片和关键信息比如卡号、姓名整理好存到本地数据库里。整个过程你会用到图形界面GUI、调用AI模型API、处理数据、操作数据库几乎涵盖了Python入门后最想练手的几个核心技能。而且咱们从零开始一步步来保证你能跟着做出来获得满满的成就感。1. 项目预览我们要做出个什么东西在动手写代码之前先看看最终成品的样子和它的工作流程这样目标会更清晰。简单来说这个工具会有一个简洁的窗口界面。你点击一个按钮选择一张包含卡证比如身份证的图片。工具会把这图片发送给一个在线的“卡证检测矫正模型”这个模型就像个智能助手它能识别图片中的卡片并自动把它旋转、裁剪成端正的矩形图片。拿回来的矫正后的图片会显示在工具的窗口里。同时我们手动输入一些这张卡片的关键信息比如这是“身份证”持有人是“张三”。最后点击保存工具就会把矫正后的图片文件保存到本地文件夹并把图片的路径、以及你输入的信息一起记录到一个小型数据库里。以后你可以随时在这个工具里查看、管理所有保存过的卡证。整个项目的流程可以看下面这张图它展示了从一张拍摄歪斜的卡片照片到最终信息被结构化存储的全过程flowchart TD A[“开始一张歪斜的br卡证照片”] -- B[“图形界面br选择图片文件”] B -- C[“调用在线APIbr进行卡证检测与矫正”] C -- D{“矫正成功?”} D -- 是 -- E[“界面显示br矫正后图像”] D -- 否 -- F[“提示失败br返回上一步”] E -- G[“用户手动输入br卡证信息类型、姓名等”] G -- H[“保存数据”] H -- I[“保存矫正后的br图片文件至本地”] I -- J[“将图片路径与信息br存入SQLite数据库”] J -- K[“完成信息已结构化存储br便于后续查看与管理”]2. 动手前的准备安装环境与认识“新朋友”工欲善其事必先利其器。我们先把项目需要的“工具”准备好。2.1 搭建你的Python工作台首先确保你安装了Python。推荐使用Python 3.7或更高版本。你可以在命令行终端或CMD里输入python --version来检查。接下来我们需要安装几个关键的Python库。请打开你的命令行逐条执行下面的命令# 安装图形界面库我们选择更现代、文档更丰富的PyQt5 pip install PyQt5 # 安装发送网络请求的库用于调用模型API pip install requests # 安装Pillow这是Python里处理图片的“瑞士军刀” pip install Pillow安装过程就像下载手机APP一样稍等片刻即可。如果遇到网络慢的问题可以在命令后加上-i https://pypi.tuna.tsinghua.edu.cn/simple来使用国内的镜像源加速。2.2 认识一下我们的核心“外援”卡证矫正API我们这个项目的“智能”部分依赖于一个已经训练好的卡证检测矫正模型。对于初学者来说自己从零训练一个模型太复杂了所以我们会调用一个现成的在线API服务。你可以把它想象成一个云端的“图片矫正工厂”。我们只需要把图片打包通过网络请求送过去工厂里的模型工人就会帮我们处理好然后把矫正好的图片寄回来。为了完成本教程你需要一个能提供此类服务的API端点URL以及可能的认证密钥API Key。由于这类服务通常由专业的AI平台提供你需要自行搜索并注册一个例如在百度AI开放平台、阿里云、腾讯云等寻找“卡证检测”、“文档矫正”或“OCR”相关服务并获取你的测试用API Key和请求地址。请注意不同的服务商其API的调用方式请求头、请求体格式会略有不同。本教程将给出一个通用的、基于requests库的调用框架你需要根据你选择的服务商提供的官方文档来调整headers和data的具体内容。3. 第一步打造程序的“脸面”——图形界面让我们先从能看到的东西做起用PyQt5创建一个简单的窗口。创建一个新的Python文件比如叫做card_manager.py然后输入下面的代码import sys from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QLineEdit, QTextEdit, QFileDialog, QMessageBox) from PyQt5.QtGui import QPixmap from PyQt5.QtCore import Qt import requests from PIL import Image, ImageQt import sqlite3 from datetime import datetime import os # 我们暂时先定义一个空的函数后面再实现它 def correct_card_image(image_path, api_url, api_key): 调用API矫正图片返回矫正后的图片数据字节流或None # 预留位置第三步会填充这里 return None class CardManagerApp(QMainWindow): def __init__(self): super().__init__() self.initUI() self.current_corrected_image_data None # 用来存储当前矫正好的图片数据 self.db_connect() # 初始化时连接数据库 def initUI(self): 初始化用户界面 self.setWindowTitle(个人卡证信息管理工具) self.setGeometry(300, 300, 800, 600) # 设置窗口位置和大小 # 创建中心部件和主布局 central_widget QWidget() self.setCentralWidget(central_widget) main_layout QVBoxLayout(central_widget) # 1. 顶部图片选择与显示区域 top_layout QHBoxLayout() # 左侧原图/矫正图显示标签 self.image_label QLabel(图片预览区域) self.image_label.setFixedSize(400, 300) self.image_label.setStyleSheet(border: 2px dashed #aaa;) self.image_label.setAlignment(Qt.AlignCenter) top_layout.addWidget(self.image_label) # 右侧信息输入区域 info_layout QVBoxLayout() info_layout.addWidget(QLabel(卡证类型:)) self.type_input QLineEdit() self.type_input.setPlaceholderText(例如身份证、银行卡) info_layout.addWidget(self.type_input) info_layout.addWidget(QLabel(持有人:)) self.name_input QLineEdit() self.name_input.setPlaceholderText(请输入姓名) info_layout.addWidget(self.name_input) info_layout.addWidget(QLabel(卡号/关键信息:)) self.number_input QLineEdit() self.number_input.setPlaceholderText(例如身份证号、银行卡号) info_layout.addWidget(self.number_input) info_layout.addWidget(QLabel(备注:)) self.note_input QTextEdit() self.note_input.setMaximumHeight(80) info_layout.addWidget(self.note_input) top_layout.addLayout(info_layout) main_layout.addLayout(top_layout) # 2. 中部功能按钮区域 button_layout QHBoxLayout() self.select_btn QPushButton(选择图片并矫正) self.select_btn.clicked.connect(self.select_and_correct_image) button_layout.addWidget(self.select_btn) self.save_btn QPushButton(保存信息) self.save_btn.clicked.connect(self.save_card_info) self.save_btn.setEnabled(False) # 初始时不可用矫正成功后启用 button_layout.addWidget(self.save_btn) self.view_btn QPushButton(查看已存卡证) self.view_btn.clicked.connect(self.view_saved_cards) button_layout.addWidget(self.view_btn) main_layout.addLayout(button_layout) # 3. 底部状态或列表显示区域先留空查看功能会用到 self.info_display QTextEdit() self.info_display.setReadOnly(True) main_layout.addWidget(self.info_display) self.show() # 预留方法我们将在后续步骤中实现它们 def select_and_correct_image(self): pass def save_card_info(self): pass def view_saved_cards(self): pass def db_connect(self): pass if __name__ __main__: app QApplication(sys.argv) ex CardManagerApp() sys.exit(app.exec_())运行这段代码 (python card_manager.py)你应该能看到一个带有按钮和输入框的窗口了。虽然点击按钮还没反应但我们的界面骨架已经搭好了它分为三个部分顶部左边用来显示图片右边用来输入卡证信息。中部三个核心按钮——“选择图片并矫正”、“保存信息”、“查看已存卡证”。底部一个文本框用来显示操作信息或卡证列表。4. 第二步让工具“聪明”起来——调用矫正API现在我们来实现最核心的“智能”功能把选中的图片发送给API进行矫正。找到之前预留的correct_card_image函数和select_and_correct_image方法用下面的代码替换它们。重要提示你需要将YOUR_API_URL和YOUR_API_KEY替换成你从AI服务商那里获取的真实地址和密钥。同时根据该服务商的API文档调整headers和files/data的格式。def correct_card_image(image_path, api_url, api_key): 调用卡证矫正API :param image_path: 本地图片路径 :param api_url: API服务地址 :param api_key: 你的API密钥 :return: 成功则返回矫正后图片的二进制数据失败返回None try: # 以二进制方式打开图片文件 with open(image_path, rb) as f: image_data f.read() # 构建请求。这里是一个通用示例你需要根据具体API调整 # 常见的格式是使用 files 参数上传图片并在 headers 或 data 中传递密钥。 files {image: (os.path.basename(image_path), image_data, image/jpeg)} headers {Authorization: fBearer {api_key}} # 或者有些API要求将key放在data里 data {apikey: api_key} # 发送POST请求 print(f正在向API发送请求: {api_url}) response requests.post(api_url, filesfiles, headersheaders, timeout30) # 检查响应 if response.status_code 200: # 假设API直接返回矫正后的图片二进制流 corrected_image_data response.content # 简单验证一下返回的是否是图片数据 if corrected_image_data[:4] b\xff\xd8\xff\xe0 or corrected_image_data[:8] b\x89PNG\r\n\x1a\n: # JPEG或PNG文件头 print(图片矫正成功) return corrected_image_data else: # 有些API可能将图片以Base64编码形式放在JSON中 # 例如 result response.json(); image_data base64.b64decode(result[image]) print(API返回了数据但可能不是直接的图片流请检查API响应格式。) return None else: print(fAPI请求失败状态码: {response.status_code}, 响应: {response.text}) return None except FileNotFoundError: print(f错误找不到图片文件 {image_path}) return None except requests.exceptions.RequestException as e: print(f网络请求出错: {e}) return None except Exception as e: print(f处理图片时发生未知错误: {e}) return None class CardManagerApp(QMainWindow): # ... 之前的 __init__ 和 initUI 代码不变 ... def select_and_correct_image(self): 选择图片文件并调用矫正函数 # 1. 弹出文件选择对话框 file_path, _ QFileDialog.getOpenFileName( self, 选择卡证图片, , Image files (*.jpg *.jpeg *.png *.bmp) ) if not file_path: # 用户取消了选择 return # 2. 显示原图可选 pixmap QPixmap(file_path) # 缩放图片以适应标签大小 scaled_pixmap pixmap.scaled(self.image_label.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) self.image_label.setPixmap(scaled_pixmap) # 3. 调用矫正API (请替换成你自己的API_URL和API_KEY) API_URL YOUR_API_URL # 例如: https://api.xxx.com/v1/card/correct API_KEY YOUR_API_KEY QMessageBox.information(self, 提示, 正在调用AI模型矫正图片请稍候...) corrected_data correct_card_image(file_path, API_URL, API_KEY) # 4. 处理矫正结果 if corrected_data: # 将二进制数据转换为QPixmap显示 self.current_corrected_image_data corrected_data corrected_pixmap QPixmap() corrected_pixmap.loadFromData(corrected_data) scaled_corrected_pixmap corrected_pixmap.scaled(self.image_label.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) self.image_label.setPixmap(scaled_corrected_pixmap) self.save_btn.setEnabled(True) # 启用保存按钮 self.info_display.setText(图片矫正成功请在右侧填写信息后点击‘保存’。) QMessageBox.information(self, 成功, 图片矫正成功) else: self.current_corrected_image_data None self.save_btn.setEnabled(False) self.info_display.setText(图片矫正失败请检查图片或网络连接然后重试。) QMessageBox.warning(self, 失败, 图片矫正失败请重试。)现在你的“选择图片并矫正”按钮应该可以工作了选择一张包含卡证的图片程序会尝试调用API进行矫正并将结果显示在预览区域。如果成功“保存信息”按钮会亮起。5. 第三步构建“记忆库”——SQLite数据库操作矫正好的图片和信息我们需要把它们存起来。这里使用Python内置的sqlite3模块它不需要安装可以直接创建一个轻量级的本地数据库文件。首先我们在db_connect方法中创建数据库和表。class CardManagerApp(QMainWindow): # ... 之前的代码不变 ... def db_connect(self): 连接或创建SQLite数据库并建立数据表 self.conn sqlite3.connect(my_card_collection.db) # 数据库文件 self.cursor self.conn.cursor() # 创建表如果不存在的话 self.cursor.execute( CREATE TABLE IF NOT EXISTS cards ( id INTEGER PRIMARY KEY AUTOINCREMENT, card_type TEXT, holder_name TEXT, card_number TEXT, note TEXT, image_path TEXT UNIQUE, -- 图片本地路径设为唯一防止重复 created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ) self.conn.commit() print(数据库连接成功表已就绪。)然后实现保存功能的save_card_info方法。这个方法要做两件事1. 把矫正后的图片保存为本地文件2. 把文件路径和用户输入的信息存入数据库。def save_card_info(self): 将矫正后的图片和用户输入的信息保存到数据库 if not self.current_corrected_image_data: QMessageBox.warning(self, 警告, 没有可保存的矫正图片请先选择并矫正一张图片。) return # 1. 获取用户输入的信息 card_type self.type_input.text().strip() holder_name self.name_input.text().strip() card_number self.number_input.text().strip() note self.note_input.toPlainText().strip() if not card_type: QMessageBox.warning(self, 警告, 请输入卡证类型。) return # 2. 生成唯一的图片文件名并保存到本地 # 创建一个名为 corrected_images 的文件夹来存放图片 save_dir corrected_images os.makedirs(save_dir, exist_okTrue) timestamp datetime.now().strftime(%Y%m%d_%H%M%S) # 简单使用时间戳和卡证类型作为文件名 filename f{card_type}_{timestamp}.jpg file_path os.path.join(save_dir, filename) try: with open(file_path, wb) as f: f.write(self.current_corrected_image_data) print(f图片已保存至: {file_path}) except IOError as e: QMessageBox.critical(self, 错误, f保存图片文件失败: {e}) return # 3. 将信息插入数据库 try: self.cursor.execute( INSERT INTO cards (card_type, holder_name, card_number, note, image_path) VALUES (?, ?, ?, ?, ?) , (card_type, holder_name, card_number, note, file_path)) self.conn.commit() # 4. 保存成功后的清理与提示 self.info_display.setText(f信息保存成功\n卡证类型: {card_type}\n图片路径: {file_path}) # 清空输入框为下一张做准备 self.type_input.clear() self.name_input.clear() self.number_input.clear() self.note_input.clear() self.image_label.clear() self.image_label.setText(图片预览区域) self.current_corrected_image_data None self.save_btn.setEnabled(False) QMessageBox.information(self, 成功, 卡证信息已成功保存至数据库) except sqlite3.IntegrityError: QMessageBox.warning(self, 警告, 该图片路径已存在可能重复保存。) except Exception as e: QMessageBox.critical(self, 数据库错误, f保存数据到数据库时出错: {e})6. 第四步回顾与查询——查看已保存的卡证最后我们来实现“查看已存卡证”功能把我们“记忆库”里的内容读出来。def view_saved_cards(self): 从数据库查询所有已保存的卡证信息并显示 try: self.cursor.execute(SELECT id, card_type, holder_name, card_number, created_time FROM cards ORDER BY created_time DESC) records self.cursor.fetchall() if not records: self.info_display.setText(数据库中没有保存任何卡证信息。) return # 格式化显示信息 display_text 已保存的卡证列表 \n\n for record in records: card_id, card_type, holder_name, card_number, created_time record display_text fID: {card_id}\n display_text f类型: {card_type}\n display_text f持有人: {holder_name}\n display_text f卡号/信息: {card_number}\n display_text f保存时间: {created_time}\n display_text - * 30 \n self.info_display.setText(display_text) except Exception as e: QMessageBox.critical(self, 查询错误, f查询数据库时出错: {e}) self.info_display.setText(查询数据失败。)别忘了在程序关闭时我们应该优雅地关闭数据库连接。在CardManagerApp类中添加一个方法并重写关闭事件。class CardManagerApp(QMainWindow): # ... 之前的代码不变 ... def closeEvent(self, event): 重写窗口关闭事件确保数据库连接被关闭 if hasattr(self, conn): self.conn.close() print(数据库连接已关闭。) event.accept()7. 总结与后续玩法好了一个完整的个人卡证信息管理工具就完成了我们来回顾一下你在这个项目里都实践了哪些技能图形界面 (GUI)用 PyQt5 搭建了一个有按钮、输入框、图片显示的桌面窗口知道了如何布局和响应按钮点击。文件操作学会了用QFileDialog让用户选择文件以及用 Python 基本的文件读写操作来保存图片。网络请求使用了requests库这是 Python 里和网络服务器“对话”最常用的工具你用它成功调用了外部的 AI 模型 API。数据库操作接触了 SQLite 这个轻量级数据库学会了连接数据库、创建表、插入数据和查询数据这是管理结构化信息的基础。项目结构体验了如何将不同功能的代码界面、逻辑、数据组织在一个小项目里。这个工具现在是一个“单机版”所有数据都存在你电脑上的my_card_collection.db文件里。你可以随时打开它添加新的卡证或者查看已有的记录。想让这个项目变得更厉害这里有几个可以尝试的进阶方向美化界面PyQt5 支持样式表 (QSS)你可以试试给按钮换个颜色给窗口加个背景让工具看起来更漂亮。增加真·OCR功能现在的信息还需要手动输入。你可以再去寻找一个 OCR光学字符识别的 API在图片矫正成功后自动识别出卡片上的文字并填充到右边的输入框里那就更智能了加入搜索功能在查看列表时增加一个搜索框可以根据“持有人”或“卡证类型”来筛选记录。数据导出增加一个功能可以把数据库里的所有信息导出成一个 Excel 表格或者 CSV 文件方便用其他软件分析。编程最有意思的地方就是做出一个能解决自己实际问题的小工具。希望这个项目能成为你 Python 学习路上一个有趣的里程碑。动手去改它加功能把它变成你自己的专属工具吧获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。

更多文章