在人脸识别中,我们通常采用欧氏距离和余弦距离来衡量人脸特征的相似度,判别是否为同一个人。

欧氏距离

欧氏距离比较简单,采用欧氏公式直接计算两个点之间的距离,如下:

d(x, y) = \sqrt{\sum_{i=1}^{n}(x_{i}-y_{i})^{2}}

代码:

diff = np.subtract(feature1, feature2)
dist = np.sqrt(np.sum(np.square(diff)))

feature1.shape 和feature2.shape 为(n, )

余弦距离

\cos \Theta =\frac{\sum_{i=1}^{n}(Ai\times Bi)}{\sqrt{\sum_{i=1}^n(Ai^{2})}\times \sqrt{\sum_{i=1}^n(Bi^{2}){}}}

余弦距离,也称为余弦相似度,是用向量空间中两个向量夹角的余弦值作为衡量两个个体间差异的大小的度量。

当两个向量直接的夹角\Theta趋向0时,两个向量越接近,差异就越小。此时\cos 0 = 1,即越接近1值时,说明人脸越相似。

代码:

dot = np.sum(np.multiply(feature1, feature2), axis=1)
norm = np.linalg.norm(feature1, axis=1) * np.linalg.norm(feature2, axis=1)
dist = dot / norm

区别

欧氏距离计算的是空间中两个点的绝对距离,距离dist越小,特征越相似;

余弦距离衡量的是空间中两个向量的夹角,夹角\theta越靠近0,即dist越接近1,特征越相似。

阈值选取

以下是一段摘自facenet 的代码:

def distance(embeddings1, embeddings2, distance_metric=0):if distance_metric==0:# Euclidian distancediff = np.subtract(embeddings1, embeddings2)dist = np.sum(np.square(diff),1)elif distance_metric==1:# Distance based on cosine similaritydot = np.sum(np.multiply(embeddings1, embeddings2), axis=1)norm = np.linalg.norm(embeddings1, axis=1) * np.linalg.norm(embeddings2, axis=1)similarity = dot / normdist = np.arccos(similarity) / math.pielse:raise 'Undefined distance metric %d' % distance_metric return distdef calculate_roc(thresholds, embeddings1, embeddings2, actual_issame, nrof_folds=10, distance_metric=0, subtract_mean=False):assert(embeddings1.shape[0] == embeddings2.shape[0])assert(embeddings1.shape[1] == embeddings2.shape[1])nrof_pairs = min(len(actual_issame), embeddings1.shape[0])nrof_thresholds = len(thresholds)k_fold = KFold(n_splits=nrof_folds, shuffle=False)tprs = np.zeros((nrof_folds,nrof_thresholds))fprs = np.zeros((nrof_folds,nrof_thresholds))accuracy = np.zeros((nrof_folds))indices = np.arange(nrof_pairs)for fold_idx, (train_set, test_set) in enumerate(k_fold.split(indices)):if subtract_mean:mean = np.mean(np.concatenate([embeddings1[train_set], embeddings2[train_set]]), axis=0)else:mean = 0.0dist = distance(embeddings1-mean, embeddings2-mean, distance_metric)# Find the best threshold for the foldacc_train = np.zeros((nrof_thresholds))for threshold_idx, threshold in enumerate(thresholds):_, _, acc_train[threshold_idx] = calculate_accuracy(threshold, dist[train_set], actual_issame[train_set])best_threshold_index = np.argmax(acc_train)for threshold_idx, threshold in enumerate(thresholds):tprs[fold_idx,threshold_idx], fprs[fold_idx,threshold_idx], _ = calculate_accuracy(threshold, dist[test_set], actual_issame[test_set])_, _, accuracy[fold_idx] = calculate_accuracy(thresholds[best_threshold_index], dist[test_set], actual_issame[test_set])tpr = np.mean(tprs,0)fpr = np.mean(fprs,0)return tpr, fpr, accuracydef calculate_accuracy(threshold, dist, actual_issame):predict_issame = np.less(dist, threshold)tp = np.sum(np.logical_and(predict_issame, actual_issame))fp = np.sum(np.logical_and(predict_issame, np.logical_not(actual_issame)))tn = np.sum(np.logical_and(np.logical_not(predict_issame), np.logical_not(actual_issame)))fn = np.sum(np.logical_and(np.logical_not(predict_issame), actual_issame))tpr = 0 if (tp+fn==0) else float(tp) / float(tp+fn)fpr = 0 if (fp+tn==0) else float(fp) / float(fp+tn)acc = float(tp+tn)/dist.sizereturn tpr, fpr, acc
def evaluate(embeddings, actual_issame, nrof_folds=10, distance_metric=0, subtract_mean=False):# Calculate evaluation metricsthresholds = np.arange(0, 4, 0.01)embeddings1 = embeddings[0::2]embeddings2 = embeddings[1::2]tpr, fpr, accuracy = facenet.calculate_roc(thresholds, embeddings1, embeddings2,np.asarray(actual_issame), nrof_folds=nrof_folds, distance_metric=distance_metric, subtract_mean=subtract_mean)thresholds = np.arange(0, 4, 0.001)val, val_std, far = facenet.calculate_val(thresholds, embeddings1, embeddings2,np.asarray(actual_issame), 1e-3, nrof_folds=nrof_folds, distance_metric=distance_metric, subtract_mean=subtract_mean)return tpr, fpr, accuracy, val, val_std, far

从上面的代码,可以看到其实我们在实际的人脸识别中,可以对标准的欧氏距离和余弦距离做适当的放大,这样在更有利于阈值的比较,更精准。那么阈值我们怎么选值呢?在上面第二段代码中可以找到答案,可以看到最佳阈值是可以算出来的,代码 thresholds = np.arange(0, 4, 0.001) ,最佳阈值在(0, 4)之间进行查找,在acc_train 最高时的threshold来当中最佳阈值。

diff = np.subtract(embeddings1, embeddings2)
dist = np.sum(np.square(diff),1)

通过跑LFW数据集测试,facenet算法下,欧氏距离经过上面两个语句变形后的最佳阈值为1.21;在arcface算法,mobilefacenet模型下自己阈值为1.45,可见在选取阈值的时候要根据自己的model来计算一下才合适。


更新:2020.11.6

关于欧氏距离怎么转换为百分比的问题

我们在百度等AI开放平台会看到人脸相似度是一个百分比,我们要怎么把欧氏转换为百分比呢,今天就说一下自己的思路。

首先我们想到的是sigmoid函数,这个函数y的范围是(0, 1),对应的百分比范围0%~100%,我们同样可以通过sigmoid函数的变形来实现映射。

p(x) = \frac{1}{1+e^{\alpha x+\beta }}

通过上面的式子实现百分比的计算,我们只需要计算参数\alpha, \beta,就可以计算百分比了。

计算方法:我们在验证集里面跑一下,把欧氏距离最大的值x1记录下来,此时设定一个该值对应最大百分比(比如95%),然后在把欧氏距离最小的值x2也记录下来,对应最小百分比(比如5%),然后把x1, x2代入上式子,就可以算出\alpha\beta的值。


参考:

https://blog.csdn.net/liunian920305/article/details/73456736

https://blog.csdn.net/u014657795/article/details/85850891

https://www.zhihu.com/question/312564645?rf=403423583

人脸识别相似度计算方法相关推荐

  1. 人脸识别4-百度商用方案调研

    1. 基于人脸识别的实名认证方案 确保为真人:通过端云配合活体检测,确保操作者为真人,可有效抵御彩打照片.视频.3D建模等攻击.用户无需提交任何资料,或去网点柜台办理业务,高效方便. 确保为本人:基于 ...

  2. opencv python 人脸识别 相似度_OpenCV+Tensorflow实现实时人脸识别演示

    原标题:OpenCV+Tensorflow实现实时人脸识别演示 Facenet网络介绍 FaceNet是谷歌提出的人脸识别模型,它跟其他人脸识别模型最大的一个不同就是它不是一个中间层输出,而是直接在欧 ...

  3. 晒一晒娱乐圈父子脸在人脸识别相似度检测下的爆笑结果

    不多说~~来看看几对明星父子.父女测测相似度的结果! 友情提醒:喝水勿看,请小心手机屏幕~~ 1.郭涛VS石头:摁~~相似度一颗心 2.林志颖携Kimi:Kimi怎么看怎么像女娃,只是这么小,被拖去领 ...

  4. 视频美颜sdk代码分析与人脸识别精准度问题

    今天文章中想要分享的有关于精准度的问题,其实就是指视频美颜sdk在接入APP使用后,它所包含的美颜.美型.特效等功能在实现过程中可以更加精准的识别人脸,从而使这些功能所带来的效果更加精致和完美.那么视 ...

  5. 关于人脸识别滥用的十个可能的应对方案

    本文对此提供十项人脸识别政策建议,大致从人脸数据.测试技术.认证评估主体三个层面予以应对潜在的人脸识别风险. 十大建议核心提要: 限制数据存储期限 限制数据分享 公共场所设立人脸识别标识 提升人脸识别 ...

  6. 基于Emgu CV+百度人脸识别,实现视频动态 人脸抓取与识别

    背景 目前AI 处于风口浪尖,作为 公司的CTO,也作为自己的技术专研,开始了AI之旅,在朋友圈中也咨询 一些大牛对于AI 机器学习框架的看法,目前自己的研究方向主要开源的 AI 库,如:Emgu C ...

  7. 开源公告|更可信的人脸识别,腾讯优图TFace正式开源!

    继神经网络推理框架 ncnn.TNN,动作检测算法 DBG,通用目标检测算法 OSD,人脸检测算法 DSFD.人脸属性算法 FAN等众多优秀的框架.算法开源后,腾讯优图实验室又有一项人脸识别算法研究项 ...

  8. 腾讯优图TFace正式开源,更可信的人脸识别!

    本文转载自腾讯开源 继神经网络推理框架 ncnn.TNN,动作检测算法 DBG,通用目标检测算法 OSD,人脸检测算法 DSFD.人脸属性算法 FAN等众多优秀的框架.算法开源后,腾讯优图实验室又有一 ...

  9. 人脸识别技术在智慧城城市建设中的深度应用

    人脸识别技术在智慧城城市建设中的深度应用 本文由本人发表于<中国安防>第144期-2017年10月刊智慧城市栏目 佳都新太科技股份有限公司 徐建明 1.   人脸识别技术在智慧城市应用中的 ...

  10. 使用百度人脸识别实现人脸识别后端逻辑

    百度人脸识别API https://ai.baidu.com/ai-doc/FACE/yk37c1u4t 获取access_token 由于百度API的access_token会定期更新,所以每次请求 ...

最新文章

  1. linux的套接口和管道
  2. WCF技术剖析之二十一:WCF基本异常处理模式[中篇]
  3. AAAI 2020 | 北理工阿里文娱:你所看视频的介绍,可以用到这样的「图像描述」技术...
  4. tornado httpserver
  5. MATLAB中的曲线拟合
  6. Node.js 的Web 服务器--Fenix
  7. 泰山游记:厕所竟然没水,可想而知
  8. html颜色字体字符代码
  9. 工商银行支付接口开发Java
  10. python alpha通道_python – 使用matplotlib和alpha通道组合图片和绘图
  11. 数学模型 Lotka-Volterra
  12. 动画 + 大白话讲清楚React渲染原理
  13. Unity3D接入Android第三方SDK流程
  14. JAVA毕业设计公立医院绩效考核系统计算机源码+lw文档+系统+调试部署+数据库
  15. 前端自动化部署,基于scp2,ssh2
  16. 消费者物价指数CPI
  17. 基于asp.net816mvc汽车维修保养年检管理系统三层架构
  18. Apache Hadoop3.x 分布式集群配置安装
  19. 给HTML初学者的三十条最佳实践
  20. 无源测向与时差定位技术研究matlab,一种基于时差信息的无源多站多目标测向交叉定位方法与流程...

热门文章

  1. RGBA转换成RGB
  2. rgba 和 IE 的 filter数值转换
  3. linux密码忘记root密码,重置密码的方法
  4. Unity 根据文件路径批量修改图片格式
  5. java怎么做摇杆_DJI虚拟摇杆控制未正确应用
  6. 文后参考文献著录规则 GB/T 7714-2005
  7. 基于SSH保险业务管理系统的设计与实现
  8. 新一代工业系统集成控制软件平台—CODESYS
  9. 设计师配色宝典:教你从零开始学配色
  10. Dataformatstring属性设置(详解)