人脸识别对齐,向量搜索

2023-11-08

人脸对齐的概念

1 查找人脸

我们可以使用dlib来查找人脸,也就是所谓的侦测人脸,可以从下面github的地址去拿到models:人脸查找的models

dnnFaceDetector = dlib.cnn_face_detection_model_v1("./mmod_human_face_detector.dat")
faceRects = dnnFaceDetector(frameDlibHogSmall, 0)
for faceRect in faceRects:
    x1 = faceRect.rect.left()
    y1 = faceRect.rect.top()
    x2 = faceRect.rect.right()
    y2 = faceRect.rect.bottom()

dlib c++ 的代码如下所示:

String mmodModelPath = "./mmod_human_face_detector.dat";
net_type mmodFaceDetector;
deserialize(mmodModelPath) >> mmodFaceDetector;
 
// Convert OpenCV image format to Dlib's image format
cv_image<bgr_pixel> dlibIm(frameDlibMmodSmall);
matrix<rgb_pixel> dlibMatrix;
assign_image(dlibMatrix, dlibIm);
 
// Detect faces in the image
std::vector<dlib::mmod_rect> faceRects = mmodFaceDetector(dlibMatrix);
 
for ( size_t i = 0; i < faceRects.size(); i++ )
{
  int x1 = faceRects[i].rect.left();
  int y1 = faceRects[i].rect.top();
  int x2 = faceRects[i].rect.right();
  int y2 = faceRects[i].rect.bottom();
  cv::rectangle(frameDlibMmod, Point(x1, y1), Point(x2, y2), Scalar(0,255,0), (int)(frameHeight/150.0), 4);
}

当然我们也可以用opencv的人脸检测模块来做,如果我们有GPU, 可以使用dlib的mmod来做,如果我们只有cpu,那就简单使用opencv的级联检测,不过,对于侧脸等等,检测得不是很多,不要紧,我们假定可以检测到。

假定我们已经检测到多张人脸,把图片存起来,然后去调用对齐是比较好的,以下是一个女演员图片,我们只示例来对齐
在这里插入图片描述
对齐的代码如下所示:

import align.detector as dt
import align.align_trans as at
import cv2
from PIL import Image
import numpy as np
#path = "./0.jpg"
path = "./b.png"
image = cv2.imread(path)
#cv2.convert

crop_size = 112
scale = crop_size / 112.0
reference = at.get_reference_facial_points(default_square=True) * scale


#img = Image.open(path)
img = Image.open(path).convert('RGB')
try:  # Handle exception
    _, landmarks = dt.detect_faces(img)
except Exception:
   print("{} is discarded due to exception!".format(path))
if (len(landmarks) == 0):  # If the landmarks cannot be detected, the img will be discarded
    print("{} is discarded due to non-detected landmarks!".format(path))

else:
    facial5points = [[landmarks[0][j], landmarks[0][j + 5]] for j in range(5)]
    warped_face = at.warp_and_crop_face(
                    np.array(img),
                    facial5points,
                    reference,
                    crop_size=(crop_size, crop_size),
                )
    cv2.imshow("test",cv2.cvtColor(warped_face,cv2.COLOR_RGB2BGR))
    #cv2.imshow("test",)
    img_warped = Image.fromarray(warped_face)
    img_warped.save("test.jpg")
    cv2.waitKey(0)

可以看到结果是把人脸旋转了到了正脸,这个对于人脸识别是有作用得,也可以用在跨境追踪得reid上面,以图搜图上面。在这里插入图片描述

向量搜索

    向量搜索可以将多个点得向量从图中抽取出来,这个和reid 抽取特张向量一样,我们可以使用向量数据库来存储这些数据,也可以直接在内存中查找
    下面我们假定所有图片已经被我们截取,例如使用1400协议截取得图片,我们使用上面得方法进行人脸截取,对齐,再从网络中抽取向量,我们可以使用任何一种arc face, 去建立网络训练数据,并抽取向量出来。

import os
import cv2
import numpy as np
import torch
import torch.utils.data as data
import torchvision.datasets as datasets
import torch.nn.functional as F
import torchvision.transforms as transforms
from backbone import Backbone
from tqdm import tqdm


def get_feature(data_root, model_root, input_size=[112, 112], embedding_size=512):

    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

    # check data and model paths
    assert os.path.exists(data_root)
    assert os.path.exists(model_root)
    print(f"Data root: {data_root}")

    # define image preprocessing
    transform = transforms.Compose(
        [
            transforms.Resize(
                [int(128 * input_size[0] / 112), int(128 * input_size[0] / 112)],
            ),  # smaller side resized
            transforms.CenterCrop([input_size[0], input_size[1]]),
            transforms.ToTensor(),
            transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]),
        ],
    )

    # define data loader
    dataset = datasets.ImageFolder(data_root, transform)
    loader = data.DataLoader(
        dataset, batch_size=1, shuffle=False, pin_memory=True, num_workers=0,
    )
    print(f"Number of classes: {len(loader.dataset.classes)}")

    # load backbone weigths from a checkpoint
    backbone = Backbone(input_size)
    backbone.load_state_dict(torch.load(model_root, map_location=torch.device("cpu")))
    backbone.to(device)
    backbone.eval()

    # get embedding for each face
    embeddings = np.zeros([len(loader.dataset), embedding_size])
    with torch.no_grad():
        for idx, (image, _) in enumerate(
            tqdm(loader, desc="Create embeddings matrix", total=len(loader)),
        ):
            embeddings[idx, :] = F.normalize(backbone(image.to(device))).cpu()

    # get all original images
    images = []
    for img_path, _ in dataset.samples:
        img = cv2.imread(img_path)
        images.append(img)

    return images, embeddings

抽取完了以后,我们可以再使用比较排序等方法进行搜索,当然,可以使用向量数据库等等方法,这里假定都在内存里面,我们使用一下函数来搜索相似度,也可以使用各种排序方法。这里只是示例。

def visualize_similarity(tag, input_size=[112, 112]):
    images, embeddings = get_feature(
        data_root=f"data/{tag}_aligned",
        model_root="checkpoint/backbone_ir50_ms1m_epoch120.pth",
        input_size=input_size,
    )

    # calculate cosine similarity matrix
    cos_similarity = np.dot(embeddings, embeddings.T)
    cos_similarity = cos_similarity.clip(min=0, max=1)
    # plot colorful grid from pair distance values in similarity matrix
    similarity_grid = plot_similarity_grid(cos_similarity, input_size)

    # pad similarity grid with images of faces
    horizontal_grid = np.hstack(images)
    vertical_grid = np.vstack(images)
    zeros = np.zeros((*input_size, 3))
    vertical_grid = np.vstack((zeros, vertical_grid))
    result = np.vstack((horizontal_grid, similarity_grid))
    result = np.hstack((vertical_grid, result))

    if not os.path.isdir("images"):
        os.mkdir("images")

    cv2.imwrite(f"images/{tag}.jpg", result)


def plot_similarity_grid(cos_similarity, input_size):
    n = len(cos_similarity)
    rows = []
    for i in range(n):
        row = []
        for j in range(n):
            # create small colorful image from value in distance matrix
            value = cos_similarity[i][j]
            cell = np.empty(input_size)
            cell.fill(value)
            cell = (cell * 255).astype(np.uint8)
            # color depends on value: blue is closer to 0, green is closer to 1
            img = cv2.applyColorMap(cell, cv2.COLORMAP_WINTER)

            # add distance value as text centered on image
            font = cv2.FONT_HERSHEY_SIMPLEX
            text = f"{value:.2f}"
            textsize = cv2.getTextSize(text, font, 1, 2)[0]
            text_x = (img.shape[1] - textsize[0]) // 2
            text_y = (img.shape[0] + textsize[1]) // 2
            cv2.putText(
                img, text, (text_x, text_y), font, 1, (255, 255, 255), 2, cv2.LINE_AA,
            )
            row.append(img)
        rows.append(np.concatenate(row, axis=1))
    grid = np.concatenate(rows)
    return grid


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--tags",
        help="specify your tags for aligned faces datasets",
        default="test",
        nargs='+',
        required=True
    )
    args = parser.parse_args()
    tags = args.tags

    for tag in tags:            
        visualize_similarity(tag)

其他小伙伴如果有需要,我可以把代码发一下,给我留言即可。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

人脸识别对齐,向量搜索 的相关文章

随机推荐

  • 区块链架构-fabric集群版安装(centos7版本)

    书接上回 配置多机器多节点集群模式 服务器选择说明 暂不考虑高可用 也不考虑kafka 所以先使用三台机器 3M 3台服务器 1O 1 Order 2P 2 Org2Peer 3 1 2证书加密 证书与加密暂时不采用CA 直接使用官方提供的
  • Ai实现FPS游戏自动瞄准 yolov5fps自瞄

    大家好 我是毕加锁 锁 今天来分享一个Yolov5 FPS跟枪的源码解析和原理讲解 代码比较粗糙 各位有什么优化的方式可以留言指出 可以一起交流学习 需要了解的东西和可能会遇到的问题1 xy坐标点与当前鼠标的xy坐标点距离计算 2 获取窗口
  • 两个串口之间传输文件

    一 串口连接 将两个USB TO TTL用两根杜邦线连接 将两个USB TO TTL的RX TX引脚交叉连接 然后将两个USB TO TTL接口接在电脑上 二 传输文件 1 打开两个串口助手 波特率是115200 数据位8 停止位1 无校验
  • el-table合并列&同时在分页时不被割裂开

    核心思想 合并大表格 留出空间给到slot 插槽 在插槽内使用小表格 效果图 具体实现
  • 学生信息管理系统中遇到的一些问题

    学生信息管理系统虽然已经让师父验收了 但感觉还是有很多不足之处 主要是全心全意为客户服务的宗旨有好多地方没有注意到 除了光标的默认输入位置 修改密码时自动默认输入并选中旧密码 师父还提醒我把所有的有关信息的增 删 改 查的窗体都要设为主窗体
  • 访谈,智能座舱开发中的人机交互与人机工程布置

    Mixlab无界社区 跨学科 智能座舱 HCI 前沿知识 N1 智能座舱开发中的人机交互与人机工程布置 丰田部分车型的多媒体系统上的Apple CarPlay 今天是汽车HMI设计师 我最喜欢苹果的UI啦 IOS的UI风格 meta sha
  • Nacos 快速上手

    Nacos 快速上手 文章目录 Nacos 快速上手 准备工作 部署 Spring Boot 集成 配置说明 Spring Cloud Nacos Dubbo Nacos 公共 API 包 服务提供者 服务消费者 问题 微服务现在越来火 有
  • php奇偶数怎么求,php奇偶数循环

    根据表单提交的数据用户在浏览器生成图一示例的图形 图形参数说明 大小 图形中最长那一行的字符数 奇数行 偶数行 最长那一个行为奇数行 紧邻的两行算偶数行 以此类推 案例效果图 应用了for循环 还应用了一个php函数 str repeat
  • 初级算法-12-实现 strStr()

    描述 实现 strStr 函数 给你两个字符串 haystack 和 needle 请你在 haystack 字符串中找出 needle 字符串出现的第一个位置 下标从 0 开始 如果不存在 则返回 1 说明 当 needle 是空字符串时
  • Android Context 上下文 你必须知道的一切

    转载请标明出处 http blog csdn net lmj623565791 article details 40481055 本文出自 张鸿洋的博客 本文大多数内容翻译自 http www doubleencore com 2013 0
  • maven(四):一个基本maven项目的pom.xml配置

    继续之前创建的test项目 一个基本项目的pom xml文件 通常至少有三个部分 第一部分 项目坐标 信息描述等
  • Python爬虫从入门到精通:(27)scrapy框架04_scrapy数据解析_Python涛哥

    scrapy数据解析 这节课 我们来看下scrapy中的数据解析 创建工程 爬取内容 爬取段子网中的段子 https duanzixing com 段子 回顾上节课所学的知识 创建scrapy 我们先来创建工程和爬虫文件 1 scrapy
  • asp.net 根据url获取参数值

    以下是 根据url获取参数值 Uri myUri new Uri http 10 0 0 75 7003 SitePages t1 aspx CurrentFolder http 10 0 0 75 7003 test docs 人力资源部
  • 实现基于SSL的主从复制

    准备 两台主机 1 在主服务器上生成证书 mkdir etc my cnf d ssl cd etc my cnf d ssl openssl genrsa 2048 gt cakey pem openssl req new x509 ke
  • Web安全之中间件安全

    中间件 中间件 英语 Middleware 又译中间件 中介层 是一类提供系统软件和应用软件之间连接 便于软件各部件之间的沟通的软件 应用软件可以借助中间件在不同的技术架构之间共享信息与资源 中间件位于客户机服务器的操作系统之上 管理着计算
  • Conda安装及使用手册

    Conda 是一个开源的软件包管理系统和环境管理系统 用于安装和管理多个软件包及其依赖项 它可以帮助用户创建虚拟环境 使得不同的项目可以使用不同的软件包和版本 从而避免版本冲突和不兼容性问题 下面是 Conda 的安装和使用步骤 安装 Co
  • 鳄鱼笔记(一) --> C#_入门<--[认识C#]

    c 语言和特点 c 语言及其特点 一 特性 二 认识 net Framework net core 三 个人理解 End c 语言及其特点 一 特性 c 是微软发布的 运行于 net Framework 和 net core 之上的高级语言
  • 面向对象设计的SOLID原则

    S O L I D是面向对象设计和编程 OOD OOP 中几个重要编码原则 Programming Priciple 的首字母缩写 SRP The Single Responsibility Principle 单一责任原则 OCP The
  • matlab练习程序(图像滤波时的边界处理)

    我们在写滤波程序时一般会用矩阵模板与原图像做卷积 这时候在做图像边界的处理是一般都选择忽略边缘 不过要是模板比较大 那么处理的效果就不好了 图像四周就会是原图像 中间才是滤波后的结果 虽然用Matlab的imfilter就能解决 不过还是自
  • 人脸识别对齐,向量搜索

    人脸对齐的概念 1 查找人脸 我们可以使用dlib来查找人脸 也就是所谓的侦测人脸 可以从下面github的地址去拿到models 人脸查找的models dnnFaceDetector dlib cnn face detection mo