• FastAPI Python照片打马赛克API


    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


    前言

    现代社会大家对于自己的隐私越来越注重,我们平时在外拍摄风景照片的时候难免会有其他人入镜。在发朋友圈或者微博的时候,为了保证这些人的肖像权我一般都会做马赛克处理。
    使用python库加fastapi可以做一个快速处理的webapi,具体介绍如下。


    一、FastAPI是什么?

    FastAPI 是一个用于构建 API 的现代、快速(高性能)的 web 框架,使用 Python 3.6+ 并基于标准的 Python 类型提示。它具有快速,高效,简单及标准化的特点。

    二、使用步骤

    1.安装FastAPI及Uvicorn

    命令如下:

    pip install fastapi
    pip install "uvicorn[standard]"
    
    • 1
    • 2

    2.编写马赛克核心代码

    代码如下:

    from fastapi import HTTPException
    import cv2
    import os
    
    def do_mosaic(frame, x, y, w, h, neighbor=9):
        fh, fw = frame.shape[0], frame.shape[1]
        if (y + h > fh) or (x + w > fw):
            return
        for i in range(0, h - neighbor, neighbor): 
            for j in range(0, w - neighbor, neighbor):
                rect = [j + x, i + y, neighbor, neighbor]
                color = frame[i + y][j + x].tolist()
                left_up = (rect[0], rect[1])
                right_down = (rect[0] + neighbor - 1, rect[1] + neighbor - 1)
                cv2.rectangle(frame, left_up, right_down, color, -1)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    3.编写照片上传接口

    代码如下:

    from fastapi import FastAPI, UploadFile, Form, File, HTTPException, Request
    from model import PicItem, PicReq
    import time
    import os
    import mosaic
    import logging
    import pickle
    
    app = FastAPI()
    
    # setup loggers
    logger = logging.getLogger("uvicorn.access")
    logger.setLevel(logging.INFO)
    handler = logging.handlers.RotatingFileHandler("api.log",mode="a",maxBytes = 100*1024, backupCount = 5)
    handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))
    logger.addHandler(handler)
    
    @app.get("/")
    async def hello():
        logger.info("enter hello")
        logger.error("error test")
        return {"message":"hello world!"}
    
    @app.post("/uploadfile/")
    async def create_upload_file(file: UploadFile = File(), uid: str = Form()):
        logger.info("enter create_upload_file uid:%s" % uid)
        #check
        if uid == "":
            logger.error("create_upload_file 未获取到UID")
            raise HTTPException(status_code=500, detail="未获取到UID")
        if not file:
            logger.error("create_upload_file 未获取到文件")
            raise HTTPException(status_code=500, detail="未获取到文件")
        mime = file.content_type
        if mime != "image/jpeg":
            logger.error("create_upload_file 只允许图片格式文件")
            raise HTTPException(status_code=500, detail="只允许图片格式文件")
    
        #set file save path and name
        data = await file.read()
        timestr = time.strftime("%Y%m%d%H%M%S",time.localtime())
        fname = file.filename.split('.')
        folderpath = "files/" + uid
        newfname = "%s.%s" % (timestr, fname[1])
    
        try:
            if not os.path.exists(folderpath):
                    os.makedirs(folderpath)
            filepath = "%s/%s" % (folderpath, newfname)
            with open(filepath,"wb") as f:#save file
                f.write(data)
                f.close()
        except e:
            raise HTTPException(status_code=500, detail= e)
    
        #set result body
        result = PicItem()
        result.uid = uid
        result.filename = newfname
        #resultstr = pickle.dumps(result).decode('UTF-8','ignore')
        #logger.info("return create_upload_file uid:%s response:%s" % (uid, resultstr))
        return result
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    4.编写马赛克处理接口

    代码如下:

    @app.post("/go/")
    async def mosaic_pic(picReq: PicReq):
        logger.info("enter go request:%s" % picReq)
        savedname =  mosaic.use_mosaic(picReq.uid, picReq.filename)
        logger.info("return go savedname:%s" % savedname)
        return savedname
    
    
    def use_mosaic(uid, fname):
        print("enter use_mosaic")
        filepath = "files/%s/%s" % (uid, fname)
        if not os.path.exists(filepath):
            raise HTTPException(status_code=500, detail="文件不存在")
        img = cv2.imread(filepath)
        fixsize = 128 # declare fix size
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # convert to grey
        print("read file success")
        # laod opencv schema
        classifier = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
        color = (0, 255, 0)
        # begin to identify face
        faceRects = classifier.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=3, minSize=(32, 32))
        print(faceRects)
        if len(faceRects):  # get faces if above zero
            print("get faces")
            for faceRect in faceRects:  # loop each face
                x, y, w, h = faceRect
                do_mosaic(img, x, y, w, h)
                print("finish use_mosaic")
        
        sfname = fname.split(".")
        donename = "%s_done.%s" % (sfname[0], sfname[1])
        cv2.imwrite("files/%s/%s" % (uid, donename) , img)
        return donename
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    三、测试

    原照片:
    在这里插入图片描述

    处理后的照片:
    在这里插入图片描述

    总结

    以上就是今天要讲的内容,本文仅仅简单介绍了python是如何将照片马赛克化的,然后使用fastapi开发接口暴露给用户使用。

  • 相关阅读:
    OGG-00918 映射中缺少键列 id.
    洛谷题单 Part 2.5 贪心
    用Java来实现elasticsearch的查询,如何用log在后台打印出对应的查询语句
    Mybatis-plus插件的一次完美实践
    实测 ubuntu 20.04 使用 lidar_imu_calib 功能包 进行 激光雷达与imu标定
    学习记忆——宫殿篇——记忆宫殿——数字编码——三十六计
    C++学习笔记——类与对象(六个默认成员函数)
    Day5力扣打卡
    SpringCloud-Ribbon和Feign快速上手
    嵌入式软件架构设计-消息交互
  • 原文地址:https://blog.csdn.net/gxiangzi/article/details/133311718