我的数据库中有一千个指纹存储在Byte []数组中,我试图对指纹进行1到N的验证,这意味着我需要比较传感器给出的指纹以及数组中的那些。
但是这个过程耗时太长,我使用forEach循环遍历数组中的所有指纹并调用验证方法来比较2个数组以找到匹配。
有没有办法让我更快地找到匹配的过程?在最坏的情况下,匹配是数组中的最后一项。或靠近底部。
指纹列表
List<Huellas> ListaHuellas = new List<Huellas>();
public class Huellas
{
public int idUsuario;
public Byte[] Huella;
}
搜索比赛
foreach (Huellas h in ListaHuellas) {
// Por cada huella... la almacenamos en un MemoryStream como arreglo de bytes.
MemoryStream fingerprintData = new MemoryStream(h.Huella);
// Creamos una plantilla a partir de esos bytes...
DPFP.Template templateIterando = new DPFP.Template(fingerprintData);
// Extraemos las caracteristicas de la plantilla
DPFP.FeatureSet features = ExtractFeatures(Sample, DPFP.Processing.DataPurpose.Verification);
// Verificamos que las caracteristicas sean buenas
if (features != null) {
// Compare the feature set with our template
DPFP.Verification.Verification.Result result = new DPFP.Verification.Verification.Result();
Verificator.Verify(features, templateIterando, ref result);
// Y vemos si el resultado es valido o no, (verified)
// Si es verified, significa que el dedo escaneado ya existia en la base de datos.
if (result.Verified) {
MessageBox.Show(new Form { TopMost = true }, "Usuario encontrado: ID " + h.idUsuario);
// Por ultimo se cierra el programa.
this.Invoke(new MethodInvoker(delegate { this.Close(); }));
}
}
}
对不起&#39;关于西班牙语的评论。
答案 0 :(得分:2)
你可以使用'Dictionary&lt;长,列表&lt; Huellas&GT;&GT;':
对于每个指纹,您从合适的哈希函数计算“长”值,并将指纹存储在与哈希值关联的列表中(如果您不能保证已知指纹之间不会发生冲突,则需要一个列表)。
如果要搜索指纹,可以计算哈希值,从字典中检索关联列表,然后可以按顺序搜索(或使用parallel.foreach)。
如果你使用一个不错的哈希函数,那么将会有很少的collisons,这些列表将主要包含一个元素或者最多只包含一个元素,因此顺序搜索不会花费很长时间。
注意:即使未知指纹的(散列)列表只包含一个结果,您仍然需要验证实际的字节数组(或提取的功能):指纹实际上总是存在的可能性新的,恰好产生与数据库中的一个指纹相同的哈希。
答案 1 :(得分:0)
删除那些永远不会匹配的项目,减少必须搜索的项目数。有很多方法可以做到这一点,但一个例子可能是:
这样,您不是在搜索整个数组,而是一次搜索一个字节并减少搜索项目的数量。
如果您想进一步减少这个时间,首先要对列表中的字节数组进行排序,然后按字典搜索它们。也就是说,仅与中间的项目进行比较,并将列表除以一半,只占用您认为匹配的一半。这样做直到你只有一个项目的一半。这与您尝试在物理字典中搜索单词时的操作相同。首先,您尝试在要查找的单词的第一个字母上打开字典;当你找到以这个字母开头的单词时,你会尝试只找到与你单词的第二个字母相匹配的单词,依此类推。为此,您需要首先对列表进行排序(在开始时使用{0,0,0,...}的字节数组,在结尾处使用{255,255,255,...}的字节数组) ;
例如,无论数组的长度如何,该算法都需要在列表中最多比较16个字节和65536个项目。这将非常快。
这只是一个没有任何代码的谈话示例,但我认为你有了这个想法。一个简单的方法,但没有完美匹配和更慢的保证将创建一个名为FingerPrint的类表示字节数组,覆盖其GetHashCode()和Equals()方法,只需使用 HashTable < / strong>实例执行搜索。
答案 2 :(得分:0)
我的问题是我每次迭代forEach循环时都会提取传感器给出的样本指纹的特征。感谢ainwood的评论,我将特征提取移到了循环外部,因为我只需要提取一次样本的特征,并与List中的指纹进行比较,并将最坏情况从15秒减少到2。 / p>