前端(液化滤镜) 后台DJANGO

本文介绍使用Django和dlib库实现的人脸检测及68个面部特征点的标注方法,通过单例模式优化预测器加载,确保高效运行。同时,文章提供了处理base64编码图像并调整分辨率的方法,以优化移动设备上的图像处理性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

安装的模块版本:

  • Django (1.11)
  • dlib (19.7.0)
  • python(3.6)

效果演示图:

dlib安装可参考:https://blog.youkuaiyun.com/ezhchai/article/details/79087046

Anaconda python3.6 安装下载:https://www.anaconda.com/download/

代码项目下载:https://download.youkuaiyun.com/download/u012434961/10826509

项目目录结构:

dlibUint.py

简单采用单例模式,避免68个人脸标注点预测器重复训练。

import dlib
import numpy as np
import cv2
import os

def singleton(cls):
    instances = {}
    def wrapper(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return wrapper

@singleton
class dlibUint(object):
    def __init__(self):
        #项目路径
        self.baseDir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
        #获取人脸分类器
        self.detector = dlib.get_frontal_face_detector()
        #获取人脸预测器
        self.predictor = dlib.shape_predictor(self.baseDir  + '\\Code\\shape_predictor_68_face_landmarks.dat')

views.py

上传的图片是base64字节码,需要转化成np序列

def facedetect(request):
    if request.method=='POST':
        try:
            detector = dlibUint().detector
            predictor = dlibUint().predictor
            imgBase64 = request.POST.get('imgdata')
            img_b64decode = base64.b64decode(imgBase64)
            img_array = np.fromstring(img_b64decode,np.uint8) # 转换np序列
            img=cv2.imdecode(img_array,cv2.COLOR_BGR2GRAY)  # 转换Opencv格式
            rects = detector(img, 1)
            if( len(rects)<1):
                raise Exception("未识别到人脸")
            if len(rects)> 1 :
                raise Exception("请上传个人照片")
            array = np.array([[p.x, p.y] for p in predictor(img, rects[0]).parts()])
            json_dict = \
                {"StatusCode": 1,
                 "message": '',
                 "result": array.tolist()
                 }
        except Exception as e:
            json_dict = \
                {"StatusCode": -1,
                 "message": str(e),
                 "result": ''
                }
            return JsonResponse(json_dict)
    return JsonResponse(json_dict)

index.html 

滑动条低于50% 是缩小,高于则进行放大。

上传图片时对图片的分辨率进行适度改小,(不然后面处理图片手机会变得很卡)。

    //图片显示
    var compressPicture = function (imgId, blob) {
        
        var maxH = 800;
        var maxW = 800;
        var quality = 0.5, image = new Image();
        image.src = blob;
        image.onload = function () {
            var that = this;
            // 生成比例
            var width = that.width, height = that.height;
            //判断上传图片是否超过最大值
            if (width > maxW || height > maxH) {
                if (width > height) {
                    height = height * maxW / width;
                    width = maxW;
                } else {
                    width = width * maxH / height;
                    height = maxH;
                }
            }

            canvas.width = parseInt(width);
            canvas.height = parseInt(height);
            ctx.drawImage(that, 0, 0, parseInt(width), parseInt(height));
            // 生成base64,兼容修复移动设备需要引入mobileBUGFix.js
            var imgurl = canvas.toDataURL('image/jpeg', quality);
            // 修复IOS兼容问题
            if (navigator.userAgent.match(/iphone/i)) {
                var mpImg = new MegaPixImage(image);
                mpImg.render(canvas, {
                    maxWidth: width,
                    maxHeight: height,
                    quality: quality
                });
                imgurl = canvas.toDataURL('image/jpeg', quality);
            }
            $('#' + imgId).attr("src", imgurl);
            oFaceDat = ctx.getImageData( 0, 0, that.width, that.height );
            oImg.width = oFaceDat.width;
            oImg.height = oFaceDat.height;
            oImg.data = oFaceDat.data.slice(0);
        };
    };

图片处理用canvas进行处理

重点: faceFilter.js 是处理人脸器官缩放的。

下巴的缩放我采用该扇形区域内的像素点以蓝色的中心点,按滤镜的公式进行 像素点的挪移。

ScaleFactor = 1 - XY / PowRadius;
ScaleFactor = 1 - eyeStrength / 100 * ScaleFactor; //按照这种关系计算取样点的位置\
var PosX = parseInt(OffsetX * ScaleFactor + PointX);
var PosY = parseInt(OffSetY * ScaleFactor + PointY);

 

 

 

 

 

附上:比较好用的视频转gif:https://www.aconvert.com/cn/video/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值