简介这份资源聚焦虹膜识别中的特征提取环节面向正在学习生物特征识别、图像处理或准备相关课程设计的学生与开发者帮助理解如何用2D-Gabor滤波器从归一化虹膜图像中提取二进制特征编码。压缩包共10个文件约939KB包含6个m脚本、2个txt说明、1个mat数据文件和1个bmp示例图像脚本覆盖Gabor滤波器构造、编码生成与系数计算等核心流程mat与bmp文件则提供可运行的实验数据与样本。已有965人学习下载说明其在入门与实操层面具有一定参考价值。读者可借助这些代码与数据完整走通从滤波器设计、响应图计算到特征编码输出的链路并对照说明文档理解各步骤参数含义为后续模板匹配与识别实验打下基础。1. 从一张眼睛照片到身份判定matlab虹膜识别到底在做什么你手头有一张人眼特写瞳孔周围那圈像纹理一样的环状结构就是虹膜。matlab虹膜识别要干的事是把这张图变成一串可比较的特征码再拿它跟库里已有的码做距离比对判断“是不是同一个人”。它不依赖深度学习大模型核心链路是定位、归一化、特征提取、匹配四步全程用 MATLAB 的矩阵运算和图像工具箱就能跑通。适合谁做课程设计的学生、想快速验证生物特征算法可行性的工程师、以及需要在嵌入式或 PC 端做轻量身份核验的开发者。我见过太多人一上来就调imfindcircles然后发现瞳孔边缘根本找不准这篇就把这条链路拆开把参数和翻车点讲清楚。2. 虹膜定位先找到圆再谈特征2.1 为什么直接对整图做边缘检测会翻车虹膜定位是整个流程里最玄学的一步。很多人拿到眼睛图第一反应是edge加imfindcircles结果要么找到睫毛的弧线要么把眼睑当成圆。原因在于虹膜外边界和巩膜眼白的灰度差并不总是明显尤其是深色虹膜。常见做法是分两步先定位瞳孔因为瞳孔和虹膜的灰度差通常最大再以瞳孔圆心为基准向外做径向梯度搜索找外边界。MATLAB 里可以用imbinarize配合regionprops先粗定位瞳孔再用imfindcircles限定半径范围精修。% 读入并转灰度 img imread(eye_sample.jpg); gray rgb2gray(img); % 瞳孔粗定位自适应二值化后取最大暗区 bw imbinarize(gray, adaptive, Sensitivity, 0.5); bw ~bw; % 反转让暗区变白 bw bwareaopen(bw, 50); % 去掉小噪点 stats regionprops(bw, Centroid, Area, BoundingBox); [~, idx] max([stats.Area]); pupilCenter stats(idx).Centroid; % 以瞳孔中心为基准限定半径搜索虹膜外圆 rMin 60; rMax 120; % 根据图像分辨率调整 [centers, radii] imfindcircles(gray, [rMin rMax], ... ObjectPolarity, dark, Sensitivity, 0.92, ... EdgeThreshold, 0.1);这段代码的逻辑是先通过二值化把最暗的瞳孔区域抠出来拿到一个粗略圆心再用imfindcircles在限定半径范围内找外圆。参数说明Sensitivity调到 0.9 以上能提高检出率但会引入假圆EdgeThreshold降低到 0.1 是为了容忍模糊边缘。如果imfindcircles返回多个圆按圆心与瞳孔中心的距离排序取最近的那个。2.2 用径向梯度替代霍夫变换的实操霍夫变换在虹膜外边界上经常失灵因为外边界不是完整圆上边被眼睑遮、下边被下眼睑挡。我一般会改用径向梯度法从瞳孔中心出发沿 360 个角度方向各取一条射线计算灰度沿射线的梯度梯度最大值对应的半径就是边界。MATLAB 里用interp2做极坐标采样再对每一列求diff找峰值。angles linspace(0, 2*pi, 360); rRange 60:120; [theta, rho] meshgrid(angles, rRange); % 极坐标转笛卡尔采样 x pupilCenter(1) rho .* cos(theta); y pupilCenter(2) rho .* sin(theta); sampled interp2(double(gray), x, y, linear, 0); % 沿半径方向求梯度 gradMag abs(diff(sampled, 1, 1)); [~, maxIdx] max(gradMag, [], 1); outerRadii rRange(maxIdx); outerRadius median(outerRadii); % 取中位数抗噪这里的关键是interp2的采样精度linear够用追求更稳可以换cubic。median比mean更抗噪因为个别角度会被睫毛干扰。得到外半径后虹膜环带就是瞳孔圆和外圆之间的区域。3. 归一化与增强把环带拉成矩形3.1 橡皮片模型从极坐标到矩形展开虹膜在不同人、不同拍摄距离下大小不一直接比对像素没意义。Daugman 的橡皮片模型把虹膜环带沿半径方向线性拉伸、沿角度方向展开成固定尺寸的矩形。MATLAB 实现就是构造一个 64×512 的网格行对应半径从瞳孔边缘到外边缘列对应角度0 到 2π再用interp2从原图采样。normW 512; normH 64; thetaNorm linspace(0, 2*pi, normW); rNorm linspace(pupilRadius, outerRadius, normH); [thetaGrid, rGrid] meshgrid(thetaNorm, rNorm); xNorm pupilCenter(1) rGrid .* cos(thetaGrid); yNorm pupilCenter(2) rGrid .* sin(thetaGrid); irisNorm interp2(double(gray), xNorm, yNorm, linear, 0); irisNorm uint8(irisNorm);参数选择宽度 512 是经验值能保留足够角度细节高度 64 对应半径方向再高会引入插值模糊。pupilRadius需要从瞳孔二值化结果里用regionprops的EquivDiameter除二得到。这一步做完你得到一张横向纹理图后续特征提取都在它上面做。3.2 用 CLAHE 和直方图均衡把纹理拉出来归一化后的图往往对比度低尤其是深色虹膜。直接做全局直方图均衡会放大噪声我一般用 CLAHE限制对比度自适应直方图均衡。MATLAB 里adapthisteq就是干这个的。irisEnhanced adapthisteq(irisNorm, ... ClipLimit, 0.02, ... NumTiles, [8 8], ... Distribution, uniform);ClipLimit控制对比度增强上限0.02 比较温和NumTiles设成 8×8 意味着把图分成 64 块各自均衡能保留局部纹理。如果发现增强后出现块状伪影把NumTiles降到 4×4。这一步之后虹膜的卷缩纹理crypts和放射状纹路会明显很多。4. 特征提取与匹配Gabor 滤波和汉明距离4.1 用 Gabor 滤波器组提取相位特征虹膜特征的核心是纹理的相位信息Daugman 用 2D Gabor 滤波器组来提取。MATLAB 没有内置 Gabor 函数但可以用imgaborfiltR2016b 之后或者自己构造。我一般用 4 个尺度、6 个方向共 24 个滤波器对归一化图滤波后取实部和虚部的符号量化为二进制码。wavelength [4 8 16 32]; orientation 0:pi/6:pi-pi/6; featureCode []; for w wavelength for o orientation gaborBank gabor(w, o); [mag, phase] imgaborfilt(irisEnhanced, gaborBank); % 取相位符号量化为1比特 bitPlane phase 0; featureCode [featureCode, bitPlane(:)]; end end featureCode logical(featureCode);wavelength选 4 到 32 覆盖不同粗细纹理orientation每 30 度一个方向。每个滤波器输出一个相位图取符号得到 1 比特。最终特征码长度是 64×512×24实际用的时候会降采样常见做法是每 8×8 块取一个代表值压到 2048 比特左右。注意imgaborfilt要求输入是灰度图且为 double 类型。4.2 汉明距离匹配与旋转对齐两个虹膜码比对用归一化汉明距离异或后数 1 的个数除以总位数。但虹膜在归一化时角度起点可能不一致直接比会偏高。常见做法是把其中一个码循环移位若干列取最小距离。function dist hammingDist(code1, code2) minDist 1; for shift -10:10 shifted circshift(code2, shift, 2); d sum(xor(code1, shifted), all) / numel(code1); if d minDist minDist d; end end dist minDist; endshift范围取 ±10 列对应角度偏移约 ±7 度覆盖大多数头部倾斜。判定阈值一般设 0.32 到 0.35低于此判为同一人。这个阈值不是绝对的得根据你的数据集做 ROC 曲线调。如果误拒率高就往上调误识率高就往下调。5. 避坑与排查那些让我重跑一整天的细节5.1 瞳孔定位偏移导致特征码全错现象匹配距离普遍在 0.45 以上同人不同图也对不上。原因瞳孔二值化时把反光点当成了瞳孔一部分圆心偏了。解决在二值化前先做imfill填孔或者用strel(disk, 3)做形态学闭运算。更稳的做法是用imfindcircles在瞳孔附近小范围搜索半径限制在 20 到 50 像素。5.2 归一化宽度选太小导致纹理混叠现象不同人的特征码区分度低汉明距离分布重叠。原因normW设成 128 或 256角度方向采样不足高频纹理被混叠。解决宽度至少 512如果原图分辨率高可以到 1024。代价是特征码变长匹配变慢但准确率提升明显。5.3 Gabor 滤波后直接取模值丢失相位现象同人不同图的距离波动大。原因只用了幅值幅值对光照敏感。解决一定用相位符号相位对光照变化更鲁棒。如果imgaborfilt返回的相位在边界处跳变可以先做unwrap再取符号。5.4 匹配时忘记做旋转对齐现象同人距离 0.4不同人 0.45阈值没法设。原因归一化时角度起点是图像坐标的 0 度但每次拍摄头部旋转不同。解决加circshift循环移位取最小距离。移位范围根据你的采集条件定一般 ±10 列够用。5.5 用 RGB 三通道分别提特征再拼接现象特征码维度爆炸匹配慢且没提升。原因虹膜纹理在灰度上已经足够三通道信息冗余。解决统一转灰度rgb2gray之后再做后续处理。如果原图是近红外本身就是单通道省去这步。6. 进阶技巧把等错误率压到 2% 以下的三个习惯第一个习惯是给归一化图做掩膜。眼睑和睫毛遮挡的区域不该参与匹配否则噪声会拉高距离。做法是在归一化图上根据灰度阈值生成一个二值掩膜匹配时只统计掩膜为 1 的位。MATLAB 里就是mask irisNorm threshold然后sum(xor(code1, code2) mask) / sum(mask)。这个改动通常能把等错误率降 1 到 2 个百分点。第二个习惯是特征码降采样时用块均值而不是块中心。64×512 的相位图直接每 8×8 取一个点会丢掉块内的一致性信息。改成对每个 8×8 块取符号的多数投票抗噪能力更强。代码上就是reshape成[8, 64, 8, 64]再对第 1、3 维求均值最后 0.5量化。第三个习惯是匹配时同时算掩膜距离。如果两张图的掩膜重叠率低于 60%直接判为不可比不输出距离。这能避免因遮挡严重导致的误识。实现上就是maskOverlap sum(mask1 mask2) / sum(mask1 | mask2)低于阈值就返回NaN。验证方法上我一般把数据集按 7:3 拆成注册集和测试集注册集每人留 3 张取平均码测试集逐张比对画 ROC 曲线找等错误率点。如果等错误率高于 5%先回头查瞳孔定位八成是圆心偏了。这个链路我在不同分辨率的数据上跑过十几轮最深的教训是虹膜识别里定位占七成特征提取只占三成别在 Gabor 参数上死磕先把圆找稳。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?