基于OpenCV的掌纹提取:噪点去除与主掌纹提取技术求助
掌纹提取:噪点去除与核心掌纹提取方案
你的现有实现步骤
步骤1:预处理(灰度化与高斯除法)
import cv2 img = cv2.imread('palm.png', -1) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) smooth = cv2.GaussianBlur(gray, (95, 95), 0) division = cv2.divide(gray, smooth, scale=192) cv2.imshow('division', division) cv2.waitKey(0) cv2.destroyAllWindows()
输出:完成灰度化与高斯模糊除法运算后的图像,初步突出掌纹区域
步骤2:生成黑白掩码
import numpy as np import cv2 img = cv2.imread('gray.png') image = cv2.cvtColor(img, cv2.COLOR_BGR2HLS) # 白色区域掩码 lower_white = np.uint8([0, 185, 0]) upper_white = np.uint8([255, 255, 255]) white_mask = cv2.inRange(image, lower_white, upper_white) # 灰色区域掩码 lower_gray = np.uint8([169, 169, 169]) upper_gray = np.uint8([198, 198, 198]) gray_mask = cv2.inRange(image, lower_gray, upper_gray) # 合并掩码 mask = cv2.bitwise_or(white_mask, gray_mask) cv2.imshow("mask", mask) cv2.waitKey(0) cv2.destroyAllWindows()
输出:生成的黑白掩码存在大量细碎噪点(尤其拇指周围),无法清晰提取目标掌纹
解决方案:分三步去除噪点并提取核心掌纹
1. 形态学操作清理掩码噪点
针对掩码中的细碎噪点,用开运算先消除小噪点,再用闭运算填补掌纹线条的微小断裂:
# 定义结构元素(椭圆核更贴合掌纹形态) kernel_open = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)) kernel_close = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)) # 开运算:先腐蚀后膨胀,去除小噪点 mask_clean = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel_open, iterations=2) # 闭运算:先膨胀后腐蚀,修复掌纹线条断裂 mask_clean = cv2.morphologyEx(mask_clean, cv2.MORPH_CLOSE, kernel_close, iterations=1)
2. 手掌区域分割,排除拇指周边无关区域
通过轮廓检测提取手掌主体,过滤掉拇指附近的孤立噪点:
# 提取掩码中的外部轮廓 contours, _ = cv2.findContours(mask_clean, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 筛选面积最大的轮廓(即手掌主体) max_contour = max(contours, key=cv2.contourArea) # 创建手掌区域掩码 palm_mask = np.zeros_like(mask_clean) cv2.drawContours(palm_mask, [max_contour], -1, 255, cv2.FILLED) # 保留手掌区域内的掌纹,过滤外部噪点 final_mask = cv2.bitwise_and(mask_clean, palm_mask)
3. 骨架细化与核心掌纹筛选
将掌纹线条细化为单像素,再通过霍夫直线检测筛选出长度达标核心掌纹:
# 骨架细化函数 def skeletonize(img): skel = np.zeros(img.shape, np.uint8) element = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3)) while True: opened = cv2.morphologyEx(img, cv2.MORPH_OPEN, element) temp = cv2.subtract(img, opened) eroded = cv2.erode(img, element) skel = cv2.bitwise_or(skel, temp) img = eroded.copy() if cv2.countNonZero(img) == 0: break return skel # 对最终掩码进行骨架细化 skel = skeletonize(final_mask) # 霍夫直线检测提取核心掌纹(调整阈值适配你的图像) min_line_len = 200 max_line_gap = 20 lines = cv2.HoughLinesP(skel, 1, np.pi/180, 50, minLineLength=min_line_len, maxLineGap=max_line_gap) # 绘制核心掌纹 core_lines = np.zeros_like(skel) if lines is not None: for x1, y1, x2, y2 in lines[:, 0]: cv2.line(core_lines, (x1, y1), (x2, y2), 255, 1)
效果说明
- 经过上述处理后,
final_mask可输出清晰的主掌纹(匹配你目标中的主掌纹效果) core_lines可提取出三条核心掌纹(匹配你目标中的核心掌纹效果)
内容的提问来源于stack exchange,提问作者JamXscape
相关产品推荐
相关产品推荐

