项目简介
这是一个基于 Python 和 OpenCV 的手写签名自动提取工具。能够从图片中智能识别签名区域,去除背景,生成透明背景的 PNG 图片。支持单张处理、批量处理和实时摄像头拍照三种模式。
技术架构
核心依赖
- OpenCV (cv2): 图像处理核心库,负责图像读取、处理和计算机视觉操作
- NumPy: 数值计算库,用于高效的数组和矩阵运算
项目结构
bash
bio-signature/
├── signature_extractor.py # 核心实现代码
├── demo_signature_test.py # 测试脚本
├── requirements.txt # 依赖配置
├── test_images/ # 测试图片目录
└── extracted_signatures/ # 输出目录(自动创建)
核心算法原理
1. 图像预处理(Preprocessing)
目的:将彩色图像转换为便于处理的灰度图,并降噪。
python
def preprocess_image(self, image):
# 步骤1:转换为灰度图
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 步骤2:高斯模糊降噪(5x5核)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
return blurred
技术要点:
- 灰度化:将 RGB 三通道简化为单通道,减少计算量
- 高斯模糊:使用 5×5 的高斯核平滑图像,去除小噪点,保留主要结构
2. 二值化处理(Binarization)
目的:将图像转换为黑白二值图,区分前景(签名)和背景。
提供两种模式:
模式A:自适应阈值(推荐)
python
binary = cv2.adaptiveThreshold(
processed, 255, # 输入图像,最大值
cv2.ADAPTIVE_THRESH_GAUSSIAN_C, # 自适应方法:高斯加权
cv2.THRESH_BINARY_INV, # 反转二值化
21, # 邻域大小:21×21
10 # 常数C:阈值调整参数
)
优势:能够自动适应不同光照条件,处理光照不均匀的图片
模式B:固定阈值
python
_, binary = cv2.threshold(
processed, threshold_value, 255, # 输入图像,阈值,最大值
cv2.THRESH_BINARY_INV # 反转二值化
)
适用场景:光照均匀的图片,或需要精确控制效果时
关键技巧:
- 使用
THRESH_BINARY_INV(反转二值化),让签名变成白色(255),背景变成黑色(0) - 自适应阈值在每个局部区域计算不同阈值,效果更稳定
3. 形态学操作(Morphological Operations)
目的:去除噪点,平滑签名边缘。
python
kernel = np.ones((3, 3), np.uint8)
# 闭运算:先膨胀后腐蚀,填补签名内部的小孔
binary = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel, iterations=1)
# 开运算:先腐蚀后膨胀,去除背景中的小噪点
binary = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel, iterations=1)
原理解释:
- 闭运算(Close):连接断裂的笔画,填补签名内部的小白点
- 开运算(Open):消除背景中的小黑点(噪声)
- 使用 3×3 的结构元素(kernel),进行 1 次迭代
4. 轮廓检测与签名定位(Contour Detection)
目的:找到签名的精确位置,裁剪出签名区域。
python
# 步骤1:查找所有外部轮廓
contours, _ = cv2.findContours(
binary,
cv2.RETR_EXTERNAL, # 只检测外部轮廓
cv2.CHAIN_APPROX_SIMPLE # 压缩轮廓,节省内存
)
# 步骤2:过滤小噪声(面积 < 100 像素)
min_area = 100
valid_contours = [cnt for cnt in contours if cv2.contourArea(cnt) > min_area]
# 步骤3:计算所有有效轮廓的整体边界框
x_min, y_min = float('inf'), float('inf')
x_max, y_max = 0, 0
for contour in valid_contours:
x, y, w, h = cv2.boundingRect(contour)
x_min = min(x_min, x)
y_min = min(y_min, y)
x_max = max(x_max, x + w)
y_max = max(y_max, y + h)
# 步骤4:添加边距,让签名不贴边
margin = 20
x_min = max(0, x_min - margin)
y_min = max(0, y_min - margin)
x_max = min(image.shape[1], x_max + margin)
y_max = min(image.shape[0], y_max + margin)
技术亮点:
- 过滤面积过小的轮廓,避免把噪点当成签名
- 计算所有有效轮廓的联合边界框,确保完整包含签名
- 添加 20 像素边距,美化效果
5. 透明背景生成(Alpha Channel)
目的:生成带透明背景的 PNG 图片,方便后续使用。
python
# 裁剪签名区域
signature_region = binary[y_min:y_max, x_min:x_max] # 二值图
original_region = image[y_min:y_max, x_min:x_max] # 原图
# 分离原图的 BGR 三通道
b, g, r = cv2.split(original_region)
# 使用二值图作为 Alpha 通道(透明度)
alpha = signature_region.copy()
# 合并为 BGRA 四通道图像
signature_rgba = cv2.merge([b, g, r, alpha])
原理:
- Alpha 通道 :第四个通道,取值 0-255
- 0 = 完全透明(背景)
- 255 = 完全不透明(签名)
- 使用二值图的白色区域(签名)作为不透明区域
- 最终保存为 PNG 格式,支持透明度
核心技术特点
1. 智能阈值处理
- 自适应阈值:根据局部光照自动调整,适应复杂场景
- 手动调节 :支持用户实时调整阈值(
+/-键),满足不同需求
2. 鲁棒的噪声处理
- 高斯模糊预处理:降低图像噪声
- 形态学操作:去除小噪点,平滑签名边缘
- 面积过滤:过滤掉过小的轮廓
3. 精确的区域定位
- 外部轮廓检测:只关注主要形状,忽略内部细节
- 联合边界框:准确框选整个签名,不遗漏笔画
- 智能边距:自动添加留白,美化效果
4. 高质量输出
- 透明背景:RGBA 格式,背景完全透明
- 保留原色:保持签名的原始颜色
- PNG 格式:无损压缩,支持透明度
完整处理流程
markdown
原始图像(BGR彩色图)
↓
【1. 预处理】
→ 转灰度图
→ 高斯模糊降噪
↓
【2. 二值化】
→ 自适应阈值 / 固定阈值
→ 签名为白色,背景为黑色
↓
【3. 形态学处理】
→ 闭运算:填补签名内部小孔
→ 开运算:去除背景噪点
↓
【4. 轮廓检测】
→ 查找所有外部轮廓
→ 过滤小面积噪声
→ 计算整体边界框
↓
【5. 区域裁剪】
→ 添加边距
→ 裁剪签名区域
↓
【6. 透明背景生成】
→ 创建 Alpha 通道
→ 合并 BGRA 图像
↓
输出:透明背景 PNG 图片
扩展功能
实时摄像头模式
python
def realtime_capture(self, camera_index=0):
cap = cv2.VideoCapture(camera_index)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280) # 设置分辨率
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
while True:
ret, frame = cap.read()
# 实时预览
cv2.imshow('Camera', frame)
key = cv2.waitKey(1)
if key == ord('c'): # 拍照
signature = self.extract_signature(frame, threshold_value)
elif key == ord('s'): # 保存
self.save_signature(signature)
技术特点:
- 1280×720 高清分辨率
- 实时预览和反馈
- 支持阈值动态调节
参数调优建议
| 参数 | 默认值 | 说明 | 调优建议 |
|---|---|---|---|
| 高斯模糊核大小 | (5, 5) | 降噪强度 | 噪声大用 (7, 7),噪声小用 (3, 3) |
| 自适应阈值邻域 | 21 | 局部区域大小 | 必须为奇数,签名粗用 31,签名细用 11 |
| 常数 C | 10 | 阈值调整 | 背景深用较大值(15-20) |
| 最小面积 | 100 | 噪声过滤 | 高分辨率图像可增大到 500-1000 |
| 边距 | 20 | 签名留白 | 根据美观需求调整(10-50) |
局限性
- 极低对比度的签名(如浅灰色签名)
- 复杂背景(如花纹纸)可能需要手动调节
- 重叠文字场景需要额外处理
欢迎+Star🌟🌟