从零开始 C# + OpenCV 实现视网膜比对

107 阅读5分钟

前言

在日常的开发中,我们时常遇到需要图像处理和模式识别的场景。今天,我们就来聊聊如何使用C#结合OpenCV进行视网膜比对。

效果

实现步骤:

1、图形加载、预处理管道;

2、血管分割;

3、特征检测与提取(这里用的是ORB与SIFT检测器)

4、特征匹配(这里用的是BFMatcher暴力匹配和FLANN(其中如果是SIFT用的是KD树匹配,如果是ORB则用的是  LSH匹配 ))。

本篇介绍openCV使用与图形预处理。

openCV使用

open cv主要是C++库,我们不直接使用open cv,使用C# 对open cv的封装库emgu cv,不适用opencv sharp(不解释):

因为我们是windows系统,不考虑其它系统,在nuget中搜索emgu,如下:

安装好后,我们来做图形处理:

在预处理管道中,我们需要如下处理:

1、转换Lab颜色空间;

2、分离通道处理;

3、CLAHE增强对比度(重点处理L通道);

4、替换L通道;

5、中值滤波去噪。

在图像处理中,使用Emgu CV(OpenCV的C#封装库)进行预处理是关键的步骤。

首先,图像被加载并转换为Lab颜色空间,以便更好地处理亮度和颜色信息。

接着,分离Lab通道,重点对L通道进行CLAHE(对比度受限的自适应直方图均衡化)处理,以增强对比度。处理后的L通道替换回原图像,最后通过中值滤波去除噪声。

这些步骤为后续的血管分割、特征检测与提取(如ORB和SIFT)以及特征匹配(如BFMatcher和FLANN)奠定了坚实的基础。

视网膜匹对

来说说把视网膜匹对的描述符如何保存、添加、导入、匹对。

创建一个FeatureDatabase类:

属性AllDescriptors是视网膜的描述符,相当于换成视网膜的二进制数据;

字段ImageID是保存图像的Id以及它的起始、结束描述符范围;

字段_detector是检测器,目前支持SIFT、ORB两种;

方法AddSample是添加单张图像到AllDescriptors;

方法GetImageID是根据描述符Id获取图像Id;

方法SaveBinary是将AllDescriptors描述符内存保存到二进制文件;

方法LoadBinary是将二进制文件内容加载到AllDescriptors。

AddSample方法:

SaveBinary方法:

该方法分为保存描述符和图像Id,都是保存到二进制文件。

保存图像Id信息:

保存描述符信息:

如果二进制内容少的话就无所谓,如果内容非常的庞大,那么需要优化,下面我们利用数组池以及分块来优化:

那么LoadBinary方法我也同样采用这中方式优化。

值得说的是GetImageID方法,为了加速检索,我们采用二分法:

到此我们的描述符功能就此结束,它的作用用户视网膜匹配时获取对应的图像Id以及置信度等:

总结

文章中,我们详细介绍了如何使用EmguCV进行图像预处理,并重点讨论了视网膜匹配描述符的保存、添加、导入和匹配功能。

我们创建了一个名为FeatureDatabase的类,该类包含了多个属性和方法,用于管理和操作视网膜的描述符数据。

首先,AllDescriptors属性存储了视网膜的描述符,这些描述符以二进制数据的形式存在。

ImageID字段用于保存图像的ID及其描述符的起始和结束范围。

_detector字段则用于指定当前支持的检测器类型,如SIFT和ORB。

AddSample方法用于将单张图像的描述符添加到AllDescriptors中,而GetImageID方法则通过描述符ID快速检索对应的图像ID。

为了高效地保存和加载大量描述符数据,SaveBinaryLoadBinary方法分别将描述符和图像ID信息保存到二进制文件或从二进制文件加载到内存中。为了优化性能,我们使用了数组池和分块处理技术。

最后,GetImageID方法通过二分法加速检索过程,确保在大规模数据集上也能快速获取图像ID。

这些功能共同构成了一个强大的视网膜匹配系统,用户可以通过该系统获取匹配图像的ID、置信度等信息,从而实现高效的图像匹配和检索。

最后

如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。

也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!

优秀是一种习惯,欢迎大家留言学习!

作者:码上dotNet

出处:mp.weixin.qq.com/s/svyhCdyNa77nGBGZTbQYYQ

声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!