Skip to content

jphJack/plamprint-extraction

Repository files navigation

掌纹图像预处理与脉络提取

本项目提供了三种掌纹图像预处理和脉络提取方法,用于从掌纹图像中提取清晰的脉络特征。

项目概述

本项目包含三个Python脚本:

  1. palmprint_preprocessing.py - 基础掌纹预处理方法
  2. row_column_histogram_vein_extraction.py - 基于行列直方图的动态二值化方法
  3. palmprint_preprocessing2.py - 基于Gabor滤波和脊线检测的综合脉络提取方法

三种方法都支持批量处理,能够自动处理指定文件夹中的所有图像文件。


方法一:基础掌纹预处理 (palmprint_preprocessing.py)

原理说明

该方法采用传统的图像处理技术进行掌纹预处理,主要包括以下步骤:

1. 光照归一化

使用CLAHE(对比度受限的自适应直方图均衡化)处理图像:

  • 将图像分成8×8的小块
  • 在每个小块内进行直方图均衡化
  • 限制对比度增强幅度,避免噪声放大
  • 适应不同光照条件

2. 噪声降低

应用快速非局部均值去噪算法:

  • 通过搜索相似图像块进行去噪
  • 保留边缘细节
  • 参数:h=10, templateWindowSize=7, searchWindowSize=21

3. 主干脉络增强

使用形态学黑帽操作:

  • 提取比周围区域暗的特征(掌纹脉络)
  • 将提取的特征叠加到原图上
  • 增强脉络的可见性

4. 主干结构提取

通过形态学开运算和闭运算:

  • 开运算(先腐蚀后膨胀):去除细小噪声和细小分支
  • 闭运算(先膨胀后腐蚀):连接断裂的脉络,填充孔洞
  • 保留主要的主干脉络

5. 自适应阈值二值化

使用高斯自适应阈值方法:

  • 不是使用全局阈值,而是为每个像素点计算局部阈值
  • 使用11×11的邻域窗口
  • 通过高斯加权计算局部均值
  • 阈值 = 局部均值 - 2

处理流程

原始图像 → 灰度转换 → CLAHE增强 → 去噪 → 黑帽增强 → 形态学提取 → 自适应阈值 → 输出

输出文件

  • *_enhanced.jpg - 增强后的掌纹图像
  • *_binary.jpg - 二值化处理后的图像
  • *_structure.jpg - 提取的主干结构图像

示例输出

方法一示例输出


方法二:基于行列直方图的动态二值化 (row_column_histogram_vein_extraction.py)

原理说明

该方法利用掌纹脉络在图像中的分布特性(脉络线条在每行和每列中占比较小),通过行列直方图分析进行动态二值化。

1. 图像增强和去噪

与方法一相同,使用CLAHE和快速非局部均值去噪。

2. 基于列直方图的动态二值化

简单方法:

  • 对每一列像素计算直方图
  • 统计累积分布,找到使黑色像素比例达到15%的灰度值作为阈值
  • 将该列中灰度值≤阈值的像素设为黑色(脉络)

自适应窗口方法:(建议采用这种方法)

  • 以当前列为中心,取前后各5列(共11列)作为窗口
  • 对窗口内所有像素计算直方图
  • 根据窗口统计确定阈值
  • 用窗口阈值处理当前列
  • 提高统计稳定性,平滑阈值变化

3. 基于行直方图的动态二值化

与列处理完全相同,只是方向改为水平方向:

  • 对每一行像素进行直方图分析
  • 动态确定阈值(黑色像素比例为10%)
  • 自适应窗口方法使用11行的窗口

4. 行列结果合并

使用逻辑或(OR)操作合并两个二值化结果:

  • 只要列二值化或行二值化中任一判断为黑色,合并结果就是黑色
  • 更全面地提取脉络特征,避免遗漏

5. 形态学清理

使用3×3椭圆结构元素进行开运算:

  • 去除细小噪声
  • 保持主干脉络的完整性

6. 骨架化处理

将二值化的脉络转换为单像素宽的骨架:

  • 优先使用OpenCV的Zhang-Suen算法(cv2.ximgproc.thinning)
  • 如果不可用,自动回退到形态学方法
  • 提取脉络的中心线,便于特征提取和匹配

7. 骨架覆盖

将骨架以绿色覆盖到原始图像上:

  • 直观显示提取的脉络在原始图像中的位置
  • 便于验证提取效果

自适应窗口处理详解

核心思想: 用局部窗口的统计信息代替单列/单行的统计信息,在保持局部适应性的同时提高统计稳定性。

实现方式:

window_size = 11
start_col = max(0, col - window_size // 2)
end_col = min(width, col + window_size // 2 + 1)
window_pixels = image[:, start_col:end_col]

作用:

  • 提高统计稳定性:窗口包含11列,像素数量增加11倍
  • 平滑局部光照变化:平均邻近列的光照信息
  • 抗噪声干扰:噪声的影响被稀释
  • 保持局部适应性:窗口仍只覆盖局部区域

处理流程

原始图像 → 增强去噪 → 列方向动态二值化 → 行方向动态二值化 → 合并结果 → 形态学清理 → 骨架化 → 覆盖到原图

输出文件

  • *_denoised.jpg - 增强和去噪后的灰度图像
  • *_binary_col_adaptive.jpg - 基于列直方图的二值化结果
  • *_binary_row_adaptive.jpg - 基于行直方图的二值化结果
  • *_binary_merged_adaptive.jpg - 行和列二值化结果的合并
  • *_cleaned_adaptive.jpg - 形态学清理后的脉络图像
  • *_skeleton_adaptive.jpg - 骨架化后的脉络(单像素宽)
  • *_overlay_adaptive.jpg - 骨架覆盖到原始图像上的结果(绿色显示)

示例输出

方法二示例输出


方法三:基于Gabor滤波和脊线检测的综合脉络提取 (palmprint_preprocessing2.py)

原理说明

该方法采用多种图像处理技术的组合,通过Gabor滤波器和脊线检测相结合的方式提取掌纹脉络。

1. 图像预处理

使用CLAHE(对比度受限的自适应直方图均衡化)处理图像:

  • 将图像分成8×8的小块
  • 在每个小块内进行直方图均衡化
  • 限制对比度增强幅度,避免噪声放大
  • 适应不同光照条件

2. 多级降噪

采用两级降噪策略:

  • 高斯模糊降噪:使用5×5高斯核进行初步降噪
  • 非局部均值去噪:对保留细节效果更好
    • 参数:h=10, templateWindowSize=7, searchWindowSize=21
    • 通过搜索相似图像块进行去噪
    • 保留边缘细节

3. 脉络特征增强

使用形态学顶帽和黑帽变换组合增强:

  • 顶帽变换(MORPH_TOPHAT):提取比周围区域亮的特征
  • 黑帽变换(MORPH_BLACKHAT):提取比周围区域暗的特征(掌纹脉络)
  • 组合增强:将顶帽结果叠加到原图,减去黑帽结果
  • 增强脉络的可见性和对比度

4. Gabor滤波提取

使用多方向Gabor滤波器提取脉络:

  • Gabor滤波器参数
    • ksize=31:滤波器核大小
    • sigma=5.0:高斯标准差
    • lambd=10.0:正弦波长
    • gamma=0.5:空间纵横比
    • psi=0:相位偏移
  • 多方向处理:0°、45°、90°、135°四个方向
  • 最大响应融合:取所有方向的最大响应作为最终结果
  • 适应不同方向的脉络特征

5. 脊线检测

使用Sobel算子检测边缘和脊线:

  • Sobel算子:计算图像梯度
    • sobelx:水平方向梯度
    • sobely:垂直方向梯度
  • 梯度幅值计算:sqrt(sobelx² + sobely²)
  • 归一化处理:将梯度幅值映射到0-255范围
  • 检测脉络的边缘和脊线特征

6. 结果融合

将Gabor滤波和脊线检测结果进行加权融合:

  • 加权融合:cv2.addWeighted(gabor_result, 0.5, ridge_result, 0.5, 0)
  • 优势互补
    • Gabor滤波:对特定方向的脉络响应强
    • 脊线检测:对边缘和梯度变化敏感
  • 综合效果:结合两种方法的优势,提高提取准确性

7. 形态学处理和骨架化

通过形态学操作优化最终结果:

  • 二值化:使用Otsu方法自动确定阈值
  • 闭运算:连接断裂的脉络,使用3×3椭圆结构元素,迭代2次
  • 开运算:去除小噪点,使用2×2椭圆结构元素,迭代1次
  • 骨架化:使用迭代腐蚀方法提取单像素宽的骨架
    • 提取脉络的中心线
    • 便于特征提取和匹配

处理流程

原始图像 → 灰度转换 → CLAHE增强 → 多级降噪 → 形态学增强 → Gabor滤波 → 脊线检测 → 结果融合 → 形态学处理 → 骨架化 → 输出

输出文件

  • *_veins.png - 最终提取的掌纹脉络图像(骨架化结果)
  • *_process.png - 处理过程可视化图像(包含7个子图)

可视化结果

该方法提供完整的处理过程可视化,包含7个子图:

  1. 原始图像
  2. 预处理结果
  3. 降噪结果
  4. 增强结果
  5. Gabor滤波结果
  6. 脊线检测结果
  7. 融合结果
  8. 最终脉络

示例输出

方法三示例输出


环境要求

Python版本

  • Python 3.7 或更高版本

依赖库

  • opencv-python
  • numpy

使用方法

方法一:基础掌纹预处理

  1. 准备数据

    • 将掌纹图像放入 data 文件夹
    • 支持的格式:.jpg, .jpeg, .png, .bmp, .tiff
  2. 运行脚本

    python palmprint_preprocessing.py
  3. 查看结果

    • 处理结果保存在 output 文件夹
    • 每个输入图像生成3个输出文件

方法二:基于行列直方图的动态二值化

  1. 准备数据

    • 将掌纹图像放入 data 文件夹
    • 支持的格式:.jpg, .jpeg, .png, .bmp, .tiff
  2. 运行脚本

    python row_column_histogram_vein_extraction.py
  3. 查看结果

    • 处理结果保存在 output_row_column_histogram 文件夹
    • 每个输入图像生成7个输出文件

方法三:基于Gabor滤波和脊线检测的综合脉络提取

  1. 准备数据

    • 将掌纹图像放入 data 文件夹
    • 支持的格式:.jpg, .jpeg, .png, .bmp, .tiff
  2. 运行脚本

    python palmprint_preprocessing2.py
  3. 查看结果

    • 处理结果保存在 output_palmprint2 文件夹
    • 每个输入图像生成2个输出文件:
      • *_veins.png - 最终提取的掌纹脉络图像
      • *_process.png - 处理过程可视化图像

参数说明

方法一参数

palmprint_preprocessing.py 中可以调整的参数:

# CLAHE参数
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
# clipLimit: 对比度限制(默认2.0)
# tileGridSize: 网格大小(默认8×8)

# 去噪参数
cv2.fastNlMeansDenoising(enhanced, None, h=10, templateWindowSize=7, searchWindowSize=21)
# h: 去噪强度(默认10)
# templateWindowSize: 模板窗口大小(默认7)
# searchWindowSize: 搜索窗口大小(默认21)

# 形态学参数
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
# 结构元素大小(默认5×5)

# 自适应阈值参数
cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
# blockSize: 邻域窗口大小(默认11)
# C: 常数(默认2)

方法二参数

row_column_histogram_vein_extraction.py 中可以调整的参数:

# 列方向黑色像素比例阈值
binary_col = adaptive_dynamic_threshold_by_column(denoised, black_ratio_threshold=0.15, window_size=11)
# black_ratio_threshold: 黑色像素比例(默认0.15,即15%)
# window_size: 自适应窗口大小(默认11)

# 行方向黑色像素比例阈值
binary_row = adaptive_dynamic_threshold_by_row(denoised, black_ratio_threshold=0.1, window_size=11)
# black_ratio_threshold: 黑色像素比例(默认0.1,即10%)
# window_size: 自适应窗口大小(默认11)

# 形态学清理参数
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
# 结构元素大小(默认3×3)

# 骨架覆盖颜色
overlay = overlay_skeleton_on_image(image, skeleton, color=(0, 255, 0))
# color: BGR颜色值(默认绿色:(0, 255, 0))

方法三参数

palmprint_preprocessing2.py 中可以调整的参数:

# CLAHE参数
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
# clipLimit: 对比度限制(默认2.0)
# tileGridSize: 网格大小(默认8×8)

# 高斯模糊参数
denoised = cv2.GaussianBlur(image, (5, 5), 0)
# kernel_size: 高斯核大小(默认5×5)

# 非局部均值去噪参数
cv2.fastNlMeansDenoising(denoised, None, h=10, templateWindowSize=7, searchWindowSize=21)
# h: 去噪强度(默认10)
# templateWindowSize: 模板窗口大小(默认7)
# searchWindowSize: 搜索窗口大小(默认21)

# 形态学增强参数
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (15, 15))
# 结构元素大小(默认15×15)

# Gabor滤波器参数
ksize = 31  # 滤波器核大小
sigma = 5.0  # 高斯标准差
lambd = 10.0  # 正弦波长
gamma = 0.5  # 空间纵横比
psi = 0  # 相位偏移
angles = [0, 45, 90, 135]  # 滤波方向

# Sobel算子参数
ksize = 3  # Sobel核大小(默认3)

# 结果融合参数
cv2.addWeighted(gabor_result, 0.5, ridge_result, 0.5, 0)
# alpha: Gabor结果权重(默认0.5)
# beta: 脊线结果权重(默认0.5)

# 形态学处理参数
kernel_close = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
kernel_open = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (2, 2))
# 闭运算:结构元素大小(默认3×3),迭代次数(默认2)
# 开运算:结构元素大小(默认2×2),迭代次数(默认1)

参数调优建议

黑色像素比例阈值:

  • 较小值(0.05-0.10):更严格,只提取最暗的脉络,减少误检
  • 中等值(0.10-0.15):平衡,适合大多数情况
  • 较大值(0.15-0.20):宽松,提取更多细节,可能包含噪声

自适应窗口大小:

  • window_size = 1:等价于简单方法
  • window_size = 11:平衡局部性和稳定性(推荐)
  • window_size = 21:更稳定,但可能过度平滑
  • window_size = 51:接近全局阈值,失去局部适应性

方法对比

特性 方法一 方法二 方法三
核心思想 传统图像处理技术 行列直方图动态分析 Gabor滤波+脊线检测
二值化方法 全局自适应阈值 动态阈值(基于直方图) Otsu自动阈值
适应性 局部自适应 双向自适应(行+列) 多方向自适应
输出文件数 3个 7个 2个
骨架化
可视化 骨架覆盖 完整过程可视化
适用场景 快速预处理 精确脉络提取 高精度脉络提取

常见问题

1. 如何修改输入输出目录?

在脚本的主函数部分修改:

data_directory = "data"  # 输入目录
output_directory = "output"  # 输出目录

2. 如何选择方法?

  • 方法一:适合快速预处理,需要简单的脉络提取
  • 方法二:适合精确脉络提取,需要骨架化结果
  • 方法三:适合高精度脉络提取,需要完整过程可视化

3. 处理速度慢怎么办?

  • 减小图像尺寸
  • 减小自适应窗口大小
  • 使用简单方法而非自适应方法

4. 提取效果不理想?

  • 调整黑色像素比例阈值
  • 调整自适应窗口大小
  • 检查图像质量和光照条件

示例输出

方法一输出示例

找到 6 个图像文件
开始批量处理...
--------------------------------------------------
处理完成: 1
  - 增强图像: output\1_enhanced.jpg
  - 二值化图像: output\1_binary.jpg
  - 主干结构: output\1_structure.jpg
--------------------------------------------------
批量处理完成!共处理 6 个图像
结果保存在: output

方法二输出示例

基于行和列直方图的动态二值化掌纹脉络提取
==================================================

找到 6 个图像文件
使用方法: adaptive
开始批量处理...
--------------------------------------------------
处理完成: 1 (方法: adaptive)
  - 去噪图像: output_row_column_histogram\1_denoised.jpg
  - 列二值化图像: output_row_column_histogram\1_binary_col_adaptive.jpg
  - 行二值化图像: output_row_column_histogram\1_binary_row_adaptive.jpg
  - 合并二值化图像: output_row_column_histogram\1_binary_merged_adaptive.jpg
  - 清理后图像: output_row_column_histogram\1_cleaned_adaptive.jpg
  - 骨架图像: output_row_column_histogram\1_skeleton_adaptive.jpg
  - 覆盖图像: output_row_column_histogram\1_overlay_adaptive.jpg
--------------------------------------------------
批量处理完成!共处理 6 个图像
结果保存在: output_row_column_histogram

方法三输出示例

基于Gabor滤波和脊线检测的综合脉络提取
==================================================

找到 6 个图像文件
开始批量处理...
--------------------------------------------------
处理完成: 1
  - 脉络图像: output_palmprint2\1_veins.png
  - 处理过程: output_palmprint2\1_process.png
--------------------------------------------------
批量处理完成!共处理 6 个图像
结果保存在: output_palmprint2

许可证

本项目仅供学习和研究使用。

联系方式

如有问题或建议,欢迎提出Issue。

About

手掌掌纹提取,也可以用于其它物体表面的纹路识别和提取

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages