前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Python创建接口项目(FastAPI)及人脸识别

Python创建接口项目(FastAPI)及人脸识别

作者头像
码客说
发布于 2022-06-15 03:30:06
发布于 2022-06-15 03:30:06
1.9K00
代码可运行
举报
文章被收录于专栏:码客码客
运行总次数:0
代码可运行

前言

我们要实现一个人脸识别的功能,人脸识别的都是调用本地的图片,所以我们搭建一个接口服务来提供图片的上传。

接口

一般接口

接口使用FastAPI框架

https://fastapi.tiangolo.com/zh/#_4

注意

该框架需要Python 3.6 及更高版本

环境变量中添加

KEY

VALUE

Path

D:\Tools\Python310D:\Tools\Python310\Scripts

另外要注意

系统变量的优先级要比用户变量的优先级高,如果配置后还是2.x版本,就要看看是否系统变量中也配置了。 配置完成后要重启开发工具,不用重启电脑。

安装

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pipenv install fastapi
pipenv install uvicorn[standard]

创建一个 main.py 文件并写入以下内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from typing import Union

from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
    return {"item_id": item_id, "q": q}

通过以下命令运行服务器

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pipenv run uvicorn main:app --reload

使用浏览器访问

http://127.0.0.1:8000/items/5?q=somequery

这样我们的接口服务就搭建好了。

对接的接口文档地址

http://127.0.0.1:8000/docs

静态文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from fastapi.staticfiles import StaticFiles
app.mount("/web", StaticFiles(directory="web"), name="web")

所有以/web/开头的请求都会访问到web目录中。

文件上传

一般文件上传

要用 File,需要先安装这个库

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pipenv install python-multipart

代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# -*- coding:utf-8 -*-
import uuid
import uvicorn
import os

from fastapi import FastAPI, File, UploadFile

app = FastAPI()


@app.get("/")
def read_root():
    return {"code": 0, "msg": "请求成功"}


# file 参数类型是字节 bytes
@app.post("/upfile/")
async def upfile(file: bytes = File(...)):
    return {"file_size": len(file)}


@app.post("/uploadfile/")
async def uploadfile(image: UploadFile = File(...)):
    try:
        if not os.path.exists("images"):
            os.makedirs("images")
    except Exception as e:
        print(e)
    suffix_arr = image.filename.split(".")
    suffix = suffix_arr[len(suffix_arr) - 1]
    file_name = os.getcwd() + "/images/" + str(uuid.uuid1()) + "." + suffix

    with open(file_name, "wb+") as f:
        f.write(image.file.read())
        f.close()

    return {"filename": file_name}


if __name__ == "__main__":
    uvicorn.run(app="main:app", host="127.0.0.1", port=8000, reload=True, debug=True)

Base64图片上传

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import base64
from fastapi import Body

@app.post("/base64file")
async def uploadfile(image=Body(None), suffix=Body(None)):
    imgdata = base64.b64decode(image)
    file_name = os.getcwd() + "/images/" + str(uuid.uuid1()) + "." + suffix
    file = open(file_name, 'wb')
    file.write(imgdata)
    file.close()
    return {"code": 0, "obj": file_name}

人像识别

face_recognition

https://github.com/ageitgey/face_recognition

安装

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pipenv install cmake
pipenv install dlib
pipenv install face_recognition

使用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import face_recognition
image = face_recognition.load_image_file("your_file.jpg")
face_locations = face_recognition.face_locations(image)

deepface

https://github.com/serengil/deepface

安装

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pipenv install deepface

使用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from deepface import DeepFace
result = DeepFace.verify(img1_path = "img1.jpg", img2_path = "img2.jpg")
print(result)

注意

这个库主要用于对比人脸相似度,人脸的特征等功能。

接口对接人脸识别

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# -*- coding:utf-8 -*-
import uuid
import uvicorn
import os

from fastapi import FastAPI, File, UploadFile
from starlette.responses import RedirectResponse
import face_recognition

app = FastAPI()


@app.get("/")
def root():
    response = RedirectResponse(url="/docs")
    return response


@app.post("/uploadfile/")
async def uploadfile(image: UploadFile = File(...)):
    try:
        if not os.path.exists("images"):
            os.makedirs("images")
    except Exception as e:
        print(e)
    suffix_arr = image.filename.split(".")
    suffix = suffix_arr[len(suffix_arr) - 1]
    file_name = os.getcwd() + "/images/" + str(uuid.uuid1()) + "." + suffix

    with open(file_name, "wb+") as f:
        f.write(image.file.read())
        f.close()
    image = face_recognition.load_image_file(file_name)
    face_locations = face_recognition.face_locations(image)
    if len(face_locations) > 0:
        return {"code": 0, "obj": face_locations}
    else:
        return {"code": 1, "obj": face_locations}

if __name__ == "__main__":
    uvicorn.run(app="main:app", host="127.0.0.1", port=8000, reload=True, debug=True)

WEB获取摄像头做识别

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!doctype html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title></title>
</head>

<body>
  <div class="imgouter">
    <div class="left_div"><video id="v"></video></div>
    <canvas id="canvas" style="display:none;"></canvas>
    <img id="photo" alt="photo" class="right_div">
  </div>
  <div class="msg"></div>

</body>
<style>
  body {
    margin: 0;
    padding: 0;
  }

  .imgouter {
    display: flex;
    height: 90vh;
    width: 100vw;
  }

  .left_div,
  .right_div {
    width: 0;
    flex: 1;
  }

  #v {
    width: 100%;
    height: 100%;
    object-fit: fill;
  }

  .msg {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 10vh;
    font-size: 30px;
  }
</style>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
  function upload_img (imgstr) {
    let arr = imgstr.split(";base64,");
    let suffix = arr[0].split("/")[1];
    let base64str = arr[1];
    let para = {
      image: base64str,
      suffix: suffix
    };
    axios
      .post('/base64file', para)
      .then(function (response) {
        let data = response.data;
        if (data.code === 0) {
          document.querySelector(".msg").innerHTML = "发现人像:" + data.obj.length;
        } else {
          document.querySelector(".msg").innerHTML = "未发现人像";
        }
      })
      .catch(function (error) {
        console.log(error);
      });

  }
  !(function () {
    // 老的浏览器可能根本没有实现 mediaDevices,所以我们可以先设置一个空的对象
    if (navigator.mediaDevices === undefined) {
      navigator.mediaDevices = {};
    }
    if (navigator.mediaDevices.getUserMedia === undefined) {
      navigator.mediaDevices.getUserMedia = function (constraints) {
        // 首先,如果有getUserMedia的话,就获得它
        var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;

        // 一些浏览器根本没实现它 - 那么就返回一个error到promise的reject来保持一个统一的接口
        if (!getUserMedia) {
          return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
        }

        // 否则,为老的navigator.getUserMedia方法包裹一个Promise
        return new Promise(function (resolve, reject) {
          getUserMedia.call(navigator, constraints, resolve, reject);
        });
      }
    }
    const constraints = {
      video: true,
      audio: false
    };
    let videoPlaying = false;
    let v = document.getElementById('v');
    let promise = navigator.mediaDevices.getUserMedia(constraints);
    promise.then(stream => {
      // 旧的浏览器可能没有srcObject
      if ("srcObject" in v) {
        v.srcObject = stream;
      } else {
        // 防止在新的浏览器里使用它,应为它已经不再支持了
        v.src = window.URL.createObjectURL(stream);
      }
      v.onloadedmetadata = function (e) {
        v.play();
        videoPlaying = true;
        take_pic();
        setInterval(() => {
          take_pic();
        }, 3000);
      };
    }).catch(err => {
      console.error(err.name + ": " + err.message);
    });

    function take_pic () {
      if (videoPlaying) {
        let canvas = document.getElementById('canvas');
        canvas.width = v.videoWidth;
        canvas.height = v.videoHeight;
        canvas.getContext('2d').drawImage(v, 0, 0);
        let data = canvas.toDataURL("image/jpeg", 0.8);
        //console.info(data);
        upload_img(data);
        document.getElementById('photo').setAttribute('src', data);
      }
    }

  })();
</script>

</html>

web端只能传base64,后端也要处理base64

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import base64
import uuid
import os
from fastapi import Body

@app.post("/base64file")
async def uploadfile(image=Body(None), suffix=Body(None)):
    imgdata = base64.b64decode(image)
    file_name = os.getcwd() + "/images/" + str(uuid.uuid1()) + "." + suffix
    file = open(file_name, 'wb')
    file.write(imgdata)
    file.close()
    try:
        image = face_recognition.load_image_file(file_name)
        face_locations = face_recognition.face_locations(image)
        if os.path.exists(file_name):
            os.remove(file_name)
        if len(face_locations) > 0:
            return {"code": 0, "obj": face_locations}
        else:
            return {"code": 1, "obj": face_locations}
    except Exception as e:
        return {"code": 1, "obj": [], "msg": str(e)}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-06-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
本地存储条件下的热迁移
每个读者都可能会问这样一个问题,虚拟机用的好好的,为啥要迁移呀?也就是迁移的价值和目的在哪里。在数据中心的日常运维中,常常要处理下面几种场景和需求,了解了这些需求,这个问题也就有了答案。 需求 1:物理机器硬件系统的维护,故障修复和升级(upgrade),但运行在这台物理机器上的虚拟机不能关机,因为用户重要的服务跑在上面。 需求 2:物理机器软件系统升级,打补丁(patch),为了不影响上面跑的虚拟机,在升级和打补丁之前,需要把虚拟机迁移到别的物理机器上。 需求 3:一个物理机器上的负载太重,需要减少一些虚拟机来释放资源。 需求 4:在一个 cluster 里,有的物理机上的虚拟机太多,有的物理机上虚拟机太少,需要做一下资源平衡。
后端云
2018/10/24
2.3K0
本地存储条件下的热迁移
Aliyun Ubuntu离线迁移到腾讯云
1.离线迁移需要借助对象存储(COS)的支持,请先确保您所在地域在 COS 支持范围内,详见如下文档:
赵智勇
2020/08/26
6.1K0
Aliyun Ubuntu离线迁移到腾讯云
winserver离线迁移数据盘到腾讯云的云硬盘
在源端服务器内下载链接制作镜像工具,下载链接:https://download.sysinternals.com/files/Disk2vhd.zip
赵智勇
2020/08/26
9.5K0
winserver离线迁移数据盘到腾讯云的云硬盘
KVM虚拟机快照研究(一)
KVM虚拟机的快照用来保存虚拟机在某个时间点的内存、磁盘或者设备状态,如果将来有需要可以把虚拟机的状态回滚到这个时间点。
Laikee
2022/04/25
2.3K0
主机迁移实践分享
在云计算时代,不管是从IDC上云还是多云直接的迁移,都已经是常见的事宜。而在上云/迁移的方案中,也是有多种的方式能够将主机迁移到腾讯云中。
腾讯云计算产品团队
2018/07/14
17.2K1
只有一个ISO镜像文件如何导入到腾讯云
!!!如果你没有ARM 架构的本地虚拟机环境,只有一个ISO镜像文件,想要导入到腾讯云,可参考此文。
隔壁没老王
2024/11/22
4400
AWS-WinServer2012离线迁移到腾讯云
在桌面输入快捷键win+r打开运行窗口,然后输入 diskmgmt.msc,按 Enter,打开 “磁盘管理”。
赵智勇
2020/08/26
2.4K0
AWS-WinServer2012离线迁移到腾讯云
↔️OpenWRT从Hper-V迁移至PVE指引
本文原载于《OpenWRT从Hper-V迁移至PVE指引 | Deep Router》,同步更新至腾讯云创作者社区。
Yawata的技术报告
2025/03/07
3610
P2v, V2v 实践
p2v,就是physical machine to virtual machine,物理机转换成虚拟机,物理机有硬件和
全栈程序员站长
2022/09/17
2.5K0
P2v, V2v 实践
Windows平台使用QEMU搭建ARM+Linux开发环境
由于目前市面上很多模拟器诸如夜神,网易MUMU,基本上使用的是x86的架构,虽然运行ARM程序没有问题,但是如果想使用gdb对ARM程序进行调试的话,就显得力不从心了,各种问题层出不穷,
乱码三千
2021/08/24
11.9K0
Aliyun Centos离线迁移到腾讯云cvm
1.离线迁移需要借助对象存储(COS)的支持,请先确保您所在地域在 COS 支持范围内,详见如下文档:
赵智勇
2020/08/26
3.7K0
Aliyun Centos离线迁移到腾讯云cvm
本地windows2008R2镜像上腾讯云迁移解决方案--实践技术文档
【实践目的】实现本地的windows2008R2等镜像上云迁移,让迁移后的云机保持本地的业务环境。
TCS-F
2019/01/27
3.9K0
本地windows2008R2镜像上腾讯云迁移解决方案--实践技术文档
【图文】如何把其他服务商的服务器项目迁移到腾讯云服务器上?
离线迁移需要腾讯云对象存储(COS)的支持,获取目前 COS 支持的地域可参考 COS可用地域,请确保您所在地域在支持范围内。
云上云
2019/07/03
7.6K0
【图文】如何把其他服务商的服务器项目迁移到腾讯云服务器上?
从友商迁移数据至腾讯云 ES
3、从快照中恢复数据,注意:在源集群中全量备份数据,恢复的时候,会有索引冲突的现象
shanizeng
2022/05/25
3.3K2
VMware业务系统迁移上云方案
客户要将业务从自建的虚拟化数据中心迁移至UCloud,希望能够将多年前的VMware体系换到公有云体系。其中:
IT大咖说
2020/12/29
3.2K0
VMware业务系统迁移上云方案
腾讯云cvm-实例迁移实践
在实际使用腾讯云cvm的场景中会使用到cvm实例跨可用区迁移,跨地域迁移以及跨账号迁移去部署或迁移业务,目前在腾讯云官网没有直接针对上述三种实例迁移的方案,但读者可以参考如下方案间接的实现实例“迁移”,详见以下三种情况:
赵智勇
2020/11/22
8.7K5
腾讯云cvm-实例迁移实践
kvm qcow2,raw 磁盘格式、磁盘存储策略介绍
raw格式是原始镜像,直接将数据写入磁盘,没有额外的元数据或压缩,由于没有复杂的元数据处理,raw 格式通常比较快,适用于一些对性能要求较高的场景。相对于 qcow2,raw 格式通常不支持虚拟机的快照功能。每个虚拟机实例都需要完整的磁盘空间,不同虚拟机之间不能共享相同的基础数据。
Kevin song
2023/12/04
3.5K0
kvm qcow2,raw 磁盘格式、磁盘存储策略介绍
WinServer离线迁移到腾讯云
在桌面输入快捷键win+r打开运行窗口,然后输入 diskmgmt.msc,按 Enter,打开 “磁盘管理”。
赵智勇
2020/08/26
9.9K1
WinServer离线迁移到腾讯云
【最佳实践】基于SAP业务腾讯云安装SUSE(15 SP2)实操
在数字化转型的大浪潮下,企业业务上云是不可逆的趋势。目前SAP在国内大型企业占比非常高,云上资源对SAP业务适配迁移需求也非常多,SAP系统主流操作系统是SUSE Linux Enterprise Server for SAP Applications,该篇文章主要对腾讯云CVM进行SUSE系统安装实操。
开元
2023/03/03
2K0
【最佳实践】基于SAP业务腾讯云安装SUSE(15 SP2)实操
腾讯云花了30分钟,就把我的服务器"掏空"了
“刚在A云买了一台云服务器,腾讯云就开始打折了!原来环境好不容易搭好的,不能说没就没呀!” 都9102年了,云上的操作你了解了吗? 如何优雅而快速的“弃车保帅”, 完成服务器的华丽转身? 正解:服务迁移一下。 2017年的自建机房 - 2019年的云服务器 2017年的数据存储 - 2019年的云存储 2017年的数据迁移 - 2019年的服务迁移 终于, 不会在正打算拷贝数据的时候出现⬇️的疑惑了...  什么是服务迁移     「服务迁移」是腾讯云为方便用户上云而研发的免费迁
腾讯云计算产品团队
2020/06/05
1.9K0
推荐阅读
相关推荐
本地存储条件下的热迁移
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档