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

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

作者头像
码客说
发布2022-06-15 11:30:06
1.6K0
发布2022-06-15 11:30:06
举报
文章被收录于专栏:码客

前言

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

接口

一般接口

接口使用FastAPI框架

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

注意

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

环境变量中添加

KEY

VALUE

Path

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

另外要注意

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

安装

代码语言:javascript
复制
pipenv install fastapi
pipenv install uvicorn[standard]

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

代码语言:javascript
复制
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
复制
pipenv run uvicorn main:app --reload

使用浏览器访问

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

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

对接的接口文档地址

http://127.0.0.1:8000/docs

静态文件

代码语言:javascript
复制
from fastapi.staticfiles import StaticFiles
app.mount("/web", StaticFiles(directory="web"), name="web")

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

文件上传

一般文件上传

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

代码语言:javascript
复制
pipenv install python-multipart

代码

代码语言:javascript
复制
# -*- 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
复制
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
复制
pipenv install cmake
pipenv install dlib
pipenv install face_recognition

使用

代码语言:javascript
复制
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
复制
pipenv install deepface

使用

代码语言:javascript
复制
from deepface import DeepFace
result = DeepFace.verify(img1_path = "img1.jpg", img2_path = "img2.jpg")
print(result)

注意

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

接口对接人脸识别

代码语言:javascript
复制
# -*- 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
复制
<!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
复制
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 删除。

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 接口
    • 一般接口
      • 静态文件
        • 文件上传
          • 一般文件上传
            • Base64图片上传
            • 人像识别
              • face_recognition
                • deepface
                • 接口对接人脸识别
                • WEB获取摄像头做识别
                相关产品与服务
                人脸识别
                腾讯云神图·人脸识别(Face Recognition)基于腾讯优图强大的面部分析技术,提供包括人脸检测与分析、比对、搜索、验证、五官定位、活体检测等多种功能,为开发者和企业提供高性能高可用的人脸识别服务。 可应用于在线娱乐、在线身份认证等多种应用场景,充分满足各行业客户的人脸属性识别及用户身份确认等需求。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档