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

news2025/1/9 16:48:29

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

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.coloradmin.cn/o/1905428.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

昇思MindSpore学习笔记5-01生成式--LSTM+CRF序列标注

摘要: 记录昇思MindSpore AI框架使用LSTMCRF模型分词标注的步骤和方法。包括环境准备、score计算、Normalizer计算、Viterbi算法、CRF组合,以及改进的双向LSTMCRF模型。 一、概念 1.序列标注 标注标签输入序列中的每个Token 用于抽取文本信息 分词(Word Segment…

3-5 提高模型效果:归一化

3-5 提高模型效果:归一化 主目录点这里 举例 1. 批量归一化 (Batch Normalization, BN) 应用场景: 通常用于图像分类任务,它在训练期间对每个批次的数据进行归一化,以加速收敛并稳定训练过程。 代码示例: import torch import torch.…

【实践分享】深度学习远程连接GPU

目录 前言 一、创建实例 二、上传文件 三、服务器上传 四、运行代码文件 前言 1、使用平台:恒源云 2、教程总结自B站大佬Larry同学发布的教程视频 一、创建实例 通俗:租用一台临时的电脑,电脑可自选GPU型号等,按照项目需…

Linux基础:一. 简单的命令

文章目录 一. 简单的命令1.1 关机1.2 重启1.3 控制台打印工作目录1.4 切换当前目录1.5 列出当前目录中的目录和文件1.6 列出指定目录中的目录和文件1.7 控制台清屏1.8 查看和设置时间1.8.1 查看时间1.8.2 设置时间,需要管理员权限 一. 简单的命令 1.1 关机 comman…

FairJob:促进在线广告系统公平性研究

在人工智能(AI)与人类动态的交汇处,既存在机遇也存在挑战,特别是在人工智能领域。尽管取得了进步,但根植于历史不平等中的持续偏见仍然渗透在我们的数据驱动系统中,这些偏见不仅延续了不公平现象&#xff0…

PingCAP 成为全球数据库管理系统市场增速最快的厂商

近日,Gartner 发布的《Market Share Analysis: Database Management Systems, Worldwide, 2023》(2024 年 6 月)报告显示:“2023 年全球数据库管理系统(DBMS)市场的增长率为 13.4%,略低于去年的…

排序 -- 计数排序以及对排序的总结

到了这篇文章就说明常见的排序我们就快要讲完了,那这篇文章我们就讲一下非比较排序--计数排序。 一、非比较排序 1.基本思想 计数排序又称为鸽巢原理,是对哈希直接定址法的变形应用。 操作步骤: 统计相同元素出现次数 根据统计的结果将序列…

LaTeX教程(014)-LaTeX文档结构(14)

LaTeX教程(014)- LaTeX \LaTeX LATE​X文档结构(14) 2.3.3 multitoc - 将目录设置为多栏 multitoc包的使用方法相当简单,只需要调用这个包,并将要设置为多栏(默认是双栏)的目录指定到包选项中即可。如\usepackage[toc]{multitoc},设置的就是…

25_嵌入式系统总线接口

目录 串行接口基本原理 串行通信 串行数据传送模式 串行通信方式 RS-232串行接口 RS-422串行接口 RS-485串行接口 RS串行总线总结 RapidIO高速串行总线 ARINC429总线 并行接口基本原理 并行通信 IEEE488总线 SCSI总线 MXI总线 PCI接口基本原理 PCI总线原理 PC…

jmeter-beanshell学习4-beanshell截取字符串

再写个简单点的东西,截取字符串,参数化文件统一用csv,然后还要用excel打开,如果是数字很容易格式就乱了。有同事是用双引号把数字引起来,报文里就不用加引号了,但是这样beanshell处理起来,好像容…

MATLAB中的SDPT3、LMILab、SeDuMi工具箱

MATLAB中的SDPT3、LMILab、SeDuMi工具箱都是用于解决特定数学优化问题的工具箱,它们在控制系统设计、机器学习、信号处理等领域有广泛的应用。以下是对这三个工具箱的详细介绍: 1. SDPT3工具箱 简介: SDPT3(Semidefinite Progra…

Nacos服务注册总流程(源码分析)

文章目录 服务注册NacosClient找看源码入口NacosClient服务注册源码NacosServer处理服务注册 服务注册 服务注册 在线流程图 NacosClient找看源码入口 我们启动一个微服务&#xff0c;引入nacos客户端的依赖 <dependency><groupId>com.alibaba.cloud</groupI…

Science Robotics 麻省理工学院最新研究,从仿真中学习的精确选择、定位和抓放物体的视触觉方法

现有的机器人系统在通用性和精确性两个性能目标上难以同时兼顾&#xff0c;往往会陷入一个机器人解决单个任务的情况&#xff0c;缺乏"精确泛化"。本文针对精准和通用的同时兼顾提出了解决方法。提出了SimPLE(Pick Localize和placE的仿真模拟)作为精确拾取和放置的解…

C# 如何获取属性的displayName的3种方式

文章目录 1. 使用特性直接访问2. 使用GetCustomAttribute()方法通过反射获取3. 使用LINQ查询总结和比较 在C#中&#xff0c;获取属性的displayName可以通过多种方式实现&#xff0c;包括使用特性、反射和LINQ。下面我将分别展示每种方法&#xff0c;并提供具体的示例代码。 1.…

【Spring Cloud】一个例程快速了解网关Gateway的使用

Spring Cloud Gateway提供了一个在Spring生态系统之上构建的API网关&#xff0c;包括&#xff1a;Spring 5&#xff0c;Spring Boot 2和Project Reactor。Spring Cloud Gateway旨在提供一种简单而有效的路由方式&#xff0c;并为它们提供一些网关基本功能&#xff0c;例如&…

轻松驾驭开发之旅:Maven配置阿里云CodeUp远程私有仓库全攻略

文章目录 引言一、为什么选择阿里云CodeUp作为远程私有仓库&#xff1f;二、Maven配置阿里云CodeUp远程私有仓库的步骤准备工作配置Maven的settings.xml文件配置项目的pom.xml文件验证配置是否成功 三、使用阿里云CodeUp远程私有仓库的注意事项 引言 在软件开发的世界里&#…

【Linux进程】命令行参数 环境变量(详解)

目录 前言 1. 命令行参数 什么是命令行参数? 2. 环境变量 常见的环境变量 如何修改环境变量? 获取环境变量 环境变量的组织方式 拓展问题 导入环境变量 3. 本地变量* 总结 前言 在使用Linux指令的时候, 都是指令后边根命令行参数, 每个指令本质都是一个一个的可执行程…

数学系C++ 排序算法简述(八)

目录 排序 选择排序 O(n2) 不稳定&#xff1a;48429 归并排序 O(n log n) 稳定 插入排序 O(n2) 堆排序 O(n log n) 希尔排序 O(n log2 n) 图书馆排序 O(n log n) 冒泡排序 O(n2) 优化&#xff1a; 基数排序 O(n k) 快速排序 O(n log n)【分治】 不稳定 桶排序 O(n…

Kaggle网站免费算力使用,深度学习模型训练

声明&#xff1a; 本文主要内容为&#xff1a;kaggle网站数据集上传&#xff0c;训练模型下载、模型部署、提交后台运行等教程。 1、账号注册 此步骤本文略过&#xff0c;如有需要可以参考其他文章。 2、上传资源 不论是上传训练好的模型进行预测&#xff0c;还是训练用的…

2024组装一台能跑AI大模型的电脑

title: 2024组装一台能跑AI大模型的电脑 tags: [组装电脑, AI大模型] categories: [其他, 电脑, windows] 这里不写组装步骤&#xff0c;哪里接线&#xff0c;购买什么品牌网上一大堆。 这里只写如何根据你自己的需求&#xff0c;选择合适的、兼容的配件。 概述 需求&#xff…