计算两种人像之间的相似度

通过调研,目前存在几种能够计算两个人脸相似度的方法:

1.使用结构相似性计算人脸之间的相似度

  • 结构准确性生成的图片是否保留了原图足够多细节。

    • (1)结构准确性衡量指标:SSIM/MMSSIM

      • SSIM(结构相似性指标)、MMSIM(多尺度结构相似性指数):一种用于比较两张图像结构相似性的方法。与像PSNR和MSE这样基于差异的方法不同,SSIM/MMSIM试图模拟人类视觉系统的特性,更准确地反映图像的视觉质量。SSIM/MMSIM的通过比较两张图像在图像的亮度、对比度和结构三个方面的的相似性来计算它们的整体相似性,可以用于侧面衡量两张图片的结构相似性。

      • SSIM的计算公式如下:SSIM(x, y) = [l(x, y)*c(x, y)*s(x, y)]^β其中,x和y是两张图像,l(x, y)、c(x, y)和s(x, y)分别衡量了它们在亮度、对比度和结构上的相似性,β是一个调节三个部分相对重要性的参数。

    • (2)SSIM和MMSIM的取值范围都为:0~1

    • (3)取值意义:其中1表示两张图像结构层面完全相同,0表示它们结构完全不同

    • (4)不同生图类型的合格((SSIM+MMSSIM) /2)阈值参考

      • All >=0.4 ((SSIM+MMSSIM) /2)

由于ssim和mmsim都是基于对两张图片同一同一位置的像素点进行比较来判断 亮度、对比度和结构这三个方面最终得到结果,所以我们在调用方法之前必须将两张图片转化为同一大小,具体代码如下:
 

def calculate_mmssim(src,img):
    msssimValue = msssim(src, img).real
    return msssimValue
def calculate_psnr(src,img):
    psnrValue = psnr(src, img)
    return  psnrValue
# 打开图片并将图片转化为同一大小
src_image = Image.open(src_file_path_name)
make_image = Image.open(make_file_path_name)
srcimg = np.array(src_image.resize((268,372)))
makeimg = np.array(make_image.resize((268,372)))

但是如果那这样两张图片来比较人脸的相似度,显然是不够的,因为这种方法是总体上比较两张图片的相似度,想要实现人脸相似度的比较,则需要将人脸单独提取出来,并转化为同一大小,之后再比较人脸的相似度:

import cv2
from deepface import DeepFace
from PIL import Image
from tqdm import tqdm
import os
output_path = "./heads"
input_path = "./Newoutputimages_2"
if not os.path.isdir(output_path):
    os.mkdir(output_path)
# 读取origin里的所有图片
imgs = os.listdir(input_path)
for img in tqdm(imgs):
    if("_head_"in img):
        continue
    if not img.endswith((".png",".jpg",".jpeg")):
        continue
    # 组装所有的文件名
    path_fileName = os.path.join(input_path,img)
    print(path_fileName)
    #cv2读取其中的图片
    img_num = cv2.imread(path_fileName)
    results = DeepFace.extract_faces(path_fileName,detector_backend="retinaface",enforce_detection=False,align=False)
    for result in results:
        face_area = result['facial_area']
        img_new = Image.open(path_fileName)
        #result_file_num = Image.fromarray(img_num[face_area['y']:face_area['y']+face_area['h'],face_area['x']:face_area['x']+face_area['w']])
        print("imgimgigmgi",os.path.splitext(img))
        # cv2.imshow("face",img_num)
        # cv2.waitKey(0)
        img_crop = img_new.crop((face_area['x'],face_area['y'],face_area['x']+face_area['w'],face_area['y']+face_area['h']))
        path_real = os.path.join(output_path, "{}_head_.png".format(os.path.splitext(img)[0]))
        img_crop.save(path_real)
        #result_file_num.save(os.path.join(output_path,"{}_head_.png".format(os.path.splitext(img)[0])))

2.使用dlib算法标识68个人脸的特征位,然后根据68个特征点的位置,使用欧式距离算法,计算两张图片同一特征点之间的距离,最终通过不同特征点位赋予不同的比重计算最终的结果(结果越小说明越相似)

欧式距离(Euclidean distance)是最常用的距离测量方式之一,用于衡量多维空间中两点之间的直线距离。它的计算原理基于勾股定理,适用于二维、三维乃至更高维的空间。欧式距离的计算公式如下:

因此,欧式算法最终的结果主要与两个因素有关:1.两张图片不同特征点之间的距离2.识别的特征点在人脸中的位置(所以为了增加最终结果的准确性,必须对两张图片的人脸进行对齐)

from deepface import DeepFace
import os
import openpyxl
import time
from tqdm import tqdm
import re
import dlib
import numpy as np
import cv2
from scipy.spatial import distance
pypath = os.path.dirname(__file__)
def get_landmarks(image):
    faces = detector(image, 1)
    if len(faces) > 0:
        landmarks = predictor(image, faces[0])
        return np.array([[p.x, p.y] for p in landmarks.parts()])
    return None
def get_results(img1,img2):
    image1 = dlib.load_rgb_image(img1)
    image2 = dlib.load_rgb_image(img2)
    image1_gray = dlib.as_grayscale(image1)
    image2_gray = dlib.as_grayscale(image2)
    image1_gray_np = np.array(image1_gray).astype(np.uint8)
    image2_gray_np = np.array(image2_gray).astype(np.uint8)
    # 调整图像大小到新的尺寸
    resized_image1 = cv2.resize(image1_gray_np, (268, 372), interpolation=cv2.INTER_AREA)
    resized_image2 = cv2.resize(image2_gray_np, (268, 372), interpolation=cv2.INTER_AREA)

    # 如果你需要将调整大小后的图像转换回dlib的array2d类型
    # resized_image_dlib1 = dlib.array(resized_image1)
    # resized_image_dlib2 = dlib.array(resized_image2)
    # 提取两个图像的特征点
    landmarks1 = get_landmarks(resized_image1)
    landmarks2 = get_landmarks(resized_image2)

    # 如果两张图片中都检测到了面部,那么计算相似度
    if landmarks1 is not None and landmarks2 is not None:
        # 分别定义眼睛、鼻子、嘴巴和其他特征点的索引
        eyes_indices = list(range(36, 48))
        nose_indices = list(range(27, 36))
        mouth_indices = list(range(48, 68))
        # other_indices = list(range(0, 27)) + list(range(68, 68))
        other_indices = list(range(0, 36)) + list(range(48, 68))

        # 计算每个部分的相似度
        eyes_similarity = np.mean([distance.euclidean(landmarks1[i], landmarks2[i]) for i in eyes_indices])
        nose_similarity = np.mean([distance.euclidean(landmarks1[i], landmarks2[i]) for i in nose_indices])
        mouth_similarity = np.mean([distance.euclidean(landmarks1[i], landmarks2[i]) for i in mouth_indices])
        other_similarity = np.mean([distance.euclidean(landmarks1[i], landmarks2[i]) for i in other_indices])

        # 应用权重
        weighted_similarity = (
                0.6 * eyes_similarity +0.4*other_similarity
                # 0.2 * nose_similarity +
                # 0.2 * mouth_similarity +
                # 0.2 * other_similarity
        )
        return weighted_similarity
excel_output_file = os.path.join(pypath, "calculte_model_simi_dlib{}.xlsx".format(
    time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))))

img_path1 = ""
img_path2 = ""
input_file_path = "/Users/liujianlei/pycharmProjects/day1/AITest/dlibtest/testHeads"
# 初始化dlib的面部检测器和特征点预测器
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
wb = openpyxl.Workbook()
ws =wb.active
ws.append(["img_name","simi_value"])
#wb.save(excel_output_file)
imgs_names = os.listdir(input_file_path)
for img_name in tqdm(imgs_names):
    real_file_path = os.path.join(input_file_path,img_name)
    pattern = re.compile(r"^\d+")
    src_file_path = pattern.match(img_name)
    print("imgde name wei ", img_name)
    src_file_name = src_file_path.group()
    src_file_path_name = os.path.join(input_file_path, src_file_name + ".png")
    # 提取当前的图片名
    make_file_path_name = os.path.join(input_file_path, img_name)
    # 判断是否是原图
    if src_file_path_name == make_file_path_name:
        continue
    result = get_results(src_file_path_name,make_file_path_name)
    # results = DeepFace.verify(src_file_path_name,make_file_path_name,model_name="ArcFace",enforce_detection=False,align=True)
    ws.append([img_name,result])
    #wb.save(excel_output_file)
# 遍历结束后保存
wb.save(excel_output_file)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/780708.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

纯前端低代码开发脚手架 - daelui/molecule

daelui/molecule低代码开发脚手架:分子组件开发、预览、打包 页面代码示例、大屏代码示例预览 可开发页面组件 可开发大屏组件 项目git地址:https://gitee.com/daelui/molecule 在线预览:http://www.daelui.com/daelui/molecule/app/index.…

STM32第十六课:WiFi模块的配置及应用

文章目录 需求一、WiFi模块概要二、配置流程1.配置通信串口,引脚和中断2.AT指令3.发送逻辑编写 三、需求实现代码总结 需求 完成WiFi模块的配置,使其最终能和服务器相互发送消息。 一、WiFi模块概要 本次使用的WiFi模块为ESP-12F模块(安信可&#xf…

聚类分析方法(一)

目录 一、聚类分析原理(一)聚类分析概述(二)聚类的数学定义(三)簇的常见类型(四)聚类框架及性能要求(五)簇的距离 二、划分聚类算法(一&#xff0…

车载测试之-CANoe创建仿真工程

在现代汽车工业中,车载测试是确保车辆电子系统可靠性和功能性的关键环节。而使用CANoe创建仿真工程,不仅能够模拟真实的车辆环境,还能大大提升测试效率和准确性。那么,CANoe是如何实现这些的呢? 车载测试中&#xff0…

PXIe-7976【K410T】

起售价 RMB 152,880.00 块RAM(BRAM): 28620 kbit 动态RAM(DRAM): 2 GB FPGA: Kintex-7 410T PXI背板链路: PCI-Express Gen2 x 8 FPGA片: 63550 DSP片: 1540

敏感词匹配DFA算法

算法简介与场景介绍 DFA算法,中文全称为确定性有穷自动机。它的基本思想是构建一个有穷自动机,当用户输入文本时,通过自动机的状态转换来快速匹配敏感词。具体特征是,有一个有效状态的集合和一些从一个状态通向另一个状态的边&am…

并发处理 优先图和多重图

优先图(Precedence Graph)视图可串性多重图(Polygraph) 优先图(Precedence Graph) 优先图用于冲突可串性的判断。 优先图结构&#xff1a; 结点 (Node)&#xff1a;事务&#xff1b;有向边 (Arc): Ti → Tj &#xff0c;满足 Ti <s Tj&#xff1b; 存在Ti中的操作A1和Tj…

利用redis Zset实现 排行榜功能 配合xxl-job持久化每一个赛季的排行榜

zset 可以排序 使用xxl-job实现定时任务 对历史排行榜持久化到数据库 排行榜有当前赛季排行版和历史排行榜 当前赛季排行榜利用redis 中的SortSet 数据结构 获取 每个月的 月初 利用xxl-job的定时任务持久化化上一个月的排行榜信息 并删除redis中的数据 当排行榜数据量巨大时…

【5G VoNR】VoNR流程简述

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G技术研究。 博客内容主要围绕…

移动校园(5):课程表数据获取及展示

首先写下静态页面&#xff0c;起初打算做成一周的课表&#xff0c;由于是以小程序的形式展现&#xff0c;所以显示一周的话会很拥挤&#xff0c;所以放弃下面的方案&#xff0c;改作一次显示一天 改后结果如下&#xff0c;后期还会进行外观优化 真正困难的部分是数据获取 大家大…

拆分Transformer注意力,韩国团队让大模型解码提速20倍|大模型AI应用开始小规模稳步爆发|周伯文:大模型也有幻觉,全球AI创新指数公布

拆分Transformer注意力&#xff0c;韩国团队让大模型解码提速20倍AI正在颠覆AI上市不到两年&#xff0c;蜗牛游戏可能要退市了&#xff1f;世界人工智能大会结束了&#xff0c;百花齐放&#xff0c;但也群魔乱舞“串联OLED”被苹果带火了&#xff0c;比OLED强在哪里&#xff1f…

文化财经macd顶底背离幅图指标公式源码

DIFF:EMA(CLOSE,12) - EMA(CLOSE,26); DEA:EMA(DIFF,9); MACD:2*(DIFF-DEA),COLORSTICK; JC:CROSS(DIFF,DEA); SC:CROSSDOWN(DIFF,DEA); N1:BARSLAST(JC)1; N2:BARSLAST(SC)1; HH:VALUEWHEN(CROSSDOWN(DIFF,DEA),HHV(H,N1));//上次MACD红柱期间合约最大值 HH2:VALUEWHE…

MySQL:视图、用户管理、C/C++/图形化界面链接访问数据库、网页逻辑

文章目录 1.视图1.1 视图的基本使用1.2 视图的基本规则 2.用户管理2.1 创建、删除、修改用户2.2 数据库权限 3.C/C/图形化界面链接访问数据库3.1 准备工作及常用接口介绍3.2 图形化界面访问MySQL 4.用户逻辑(注册&&登录) 1.视图 视图是一个虚拟表&#xff0c;其内容由…

springboot苏桦旅游管理系统-计算机毕业设计源码02123

摘要 旅游业在全球范围内不断发展&#xff0c;为了提供高效的旅游管理和服务&#xff0c;开发一个旅游管理系统具有重要意义。本文旨在设计和实现该旅游管理系统&#xff0c;以满足用户和管理员的需求。该系统采用Spring Boot作为后端框架&#xff0c;利用其简化的开发流程和强…

ComfyUI如何高效率使用多Lora

Efficient 工作流 {"last_node_id": 29,"last_link_id": 56,"nodes": [{"id": 26,"type": "LoRA Stacker","pos": [540,270],"size": {"0": 320,"1": 322},"flag…

如何让代码兼容 Python 2 和 Python 3?Future 库助你一臂之力

目录 01Future 是什么? 为什么选择 Future? 安装与配置 02Future 的基本用法 1、兼容 print 函数 2、兼容整数除法 3、兼容 Unicode 字符串 03Future 的高级功能 1. 处理字符串与字节 2. 统一异常处理…

STM32-TIM定时器

本内容基于江协科技STM32视频内容&#xff0c;整理而得。 文章目录 1. TIM1.1 TIM定时器1.2 定时器类型1.3 基本定时器1.4 通用定时器1.4 高级定时器1.5 定时中断基本结构1.6 预分频器时序1.7 计数器时序1.8 计数器无预装时序1.9 计数器有预装时序1.10 RCC时钟树 2. TIM库函数…

路径跟踪算法之PID、PP、Stanley详细理解

一、前言 今天又来补作业了&#xff01; 在跟踪控制领域&#xff0c;PID&#xff08;Proportional-Integral-Derivative, 分别为比例、积分、微分&#xff09;、PP&#xff08; Pure-Puresuit, 纯跟踪&#xff09;、Stanley&#xff08;前轮反馈控制&#xff09;是三种最为常见…

02STM32软件安装新建工程

STM32软件安装&新建工程 1.软件安装&#xff1a;1.1Keil5 MDK安装1.2安装器件支持包离线安装支持包在线安装支持包 1.3软件注册&#xff1a;1.4安装驱动STLINK驱动JLink驱动在此文件夹下USB转串口 2开发方式&新建工程步骤&架构2.1STM32开发方式&#xff1a;库函数压…

线性系统理论及应用GUI设计及仿真

目录 1.控制系统的状态空间模型 1.1.状态空间模型 1.2 传递函数模型 1.3 传递函数转换为状态空间模型 1.4.状态空间模型转换为传递函数 1.5.状态空间模型转化为约当标准型 2.线性系统的时域分析 2.1.矩阵指数函数的计算 2.2.线型定常连续系统的状态空间模型求解 3.线…