基于指纹识别浅谈基本的图像预处理技术(一)

指纹识别技术应该是目前应用最为广泛的一种生物体特征识别技术,离我们最近且最为常用的就是手机上的指纹解锁功能。相较于其他的生物体特征识别,如掌纹、虹膜、面部等,指纹虽因其更易被仿照安全性稍逊于其他生物体特征,但与之对应的指纹识别技术因其易操作性、时间成本、开发成本都远优于其他特征识别技术而普及最广。同时也由于其是一项相对成熟、完善和简单的技术,且包含较为综合的图像处理技术,所以是图像算法学习与入门的不二之选。

图片及其格式

一张常规的图片通过行与列可将其分为多个像素点,每个像素点对应各自的色彩便可构成我们所看到的图片。这种图片也就是我们常见的点阵式图片(JPG、BMP等),这种类型的图片文件对应的就是一个典型的矩阵。

  • JPEG格式
    JPEG格式的图片有着极高的压缩率,它可以抛弃许多冗余的色彩数据,以达到极小的磁盘占用率,但这也意味着每次的压缩保存图片都会失真,这也被认为是我们时常发现在网络上被许多人多次保存和转发的图片变模糊变绿的原因之一(变绿被认为还同RGB与YCbCr色彩空间的相互转换有关)。
  • BMP格式
    BMP是bitmap的缩写是Windows系统中标准的一种图像格式,相对于JPEG而言它拥有更为丰富的色彩信息,且几乎不存在压缩,所以BMP格式的图片也更占磁盘空间。出于其图片的保真率较高图片信息储存较为完整,它也是机构发布的指纹识别标准的图片指定格式。

以下是Windows给出的BMP文件头结构体定义,其中包含了文件类型、文件大小、文件头到实际图像数据偏移量以及两个保留位。

typedef struct tagBITMAPFILEHEADER 
{  
   UINT16     bfType;    
   DWORD      bfSize; 
   UINT16     bfReserved1; 
   UINT16     bfReserved2; 
   DWORD      bfOffBits;
} BITMAPFILEHEADER; 

以下是Windows给出的BMP文件的信息头,其中包括图片大小、图片像素宽高、颜色索引以及是否压缩等信息。

typedef struct tagBITMAPINFOHEADER {
   DWORD     biSize;
   LONG      biWidth;
   LONG      biHeight;
   WORD      biPlanes;
   WORD      biBitCount;
   DWORD     biCompression;
   DWORD     biSizeImage;
   LONG      biXPelsPerMeter;
   LONG      biYPelsPerMeter;
   DWORD     biClrUsed;
   DWORD     biClrImportant;
} BITMAPINFOHEADER;

了解到图片的基本文件格式后,我们可以从文件中提取我们需要的信息进行操作,理论上讲通过设置各个像素点的色彩我们甚至可直接用代码作画。

灰度图及图像二值化

显然,就指纹的图像信息而言,是否有颜色对我们而言没有意义,我们所需要的指纹信息本质上其纹理走向,其他色彩信息反而会影响我们的判断。
所以需要将采集到的含有彩色信息的图片转化为灰度图,即黑白图像。若是YCbCr色彩空间我们只需要保留亮度信息Y,而将另外的两个颜色分量Cb、Cr丢掉就好了。对于RGB色彩空间,有一个经典的灰度转换公式:
G r a y = R ∗ 0.299 + G ∗ 0.587 + B ∗ 0.114 Gray = R*0.299 + G*0.587 + B*0.114 Gray=R0.299+G0.587+B0.114
一般在硬件设计,如FPGA设计中,为提高运算速度与效率,需避免含小数的运算,所以就有:
G r a y = ( R ∗ 299 + G ∗ 587 + B ∗ 114 ) / 100 Gray = (R*299 + G*587 + B*114)/100 Gray=(R299+G587+B114)/100
当然除法运算也是需要避免的,除法运算本质也是乘法运算这之间的转化也相当耗时,所以可以通过移位代替,通常会采用等比例扩大乘法的系数,一般选用2的整数次幂,再通过移位消除掉所乘的系数:
2 16 = 65536 2^{16} = 65536 216=65536
0.299 ∗ 65536 = 19595.264 ≈ 19595 0.299 * 65536 = 19595.264 ≈ 19595 0.29965536=19595.26419595
0.587 ∗ 65536 + ( 0.264 ) = 38469.632 + 0.264 = 38469.896 ≈ 38469 0.587 * 65536 + (0.264) = 38469.632 + 0.264 = 38469.896 ≈ 38469 0.58765536+(0.264)=38469.632+0.264=38469.89638469
0.114 ∗ 65536 + ( 0.896 ) = 7471.104 + 0.896 = 7472 0.114 * 65536 + (0.896) = 7471.104 + 0.896 = 7472 0.11465536+(0.896)=7471.104+0.896=7472
G r a y = ( R ∗ 19595 + G ∗ 38469 + B ∗ 7472 ) > > 16 Gray = (R*19595 + G*38469 + B*7472) >> 16 Gray=(R19595+G38469+B7472)>>16

上面的步骤中将每一步舍掉的小数点后面的误差部分,都加到了下一步的计算中而保留了误差。0.299、0.587、0.114之和为1,所以最后舍掉的部分之和也为1,所以加到最后一步刚好得到的是一个整数。

对于真实所采集到指纹图像的彩色信息较少本就与灰度化较为接近,所以还可以用近似的计算:
G r a y = ( R + G + B ) / 3 Gray = (R + G + B)/3 Gray=(R+G+B)/3

至此,应当可以较为容易的得到了一张灰度图,但这一步还并没有结束。对于一个仅需要纹理存在的指纹图像,比较完美的就是得到一张只有黑白两色的图片,所以还需要进行二值化,顾名思义就是将现在已经得到的灰度图只转化为只有两个颜色。非常简单的我们只需要通过设置阈值来实现,即将小于某一阈值的数据都直接置为纯白色0,大于某一阈值的数据置为纯黑色255。这样我们就可以得到一张视觉上线条非常清晰的指纹图片。

你可能感兴趣的:(图像处理)