Python + Django + face_recognition 实现人脸识别+在线识别接口+在线比对接口

前段时间,公司人工智能平台关于人脸识别授权到期,与某公司续签续期合同,私有化部署居然需要二十多万,不禁咂舌。

以此为背景想到,前段时间学习Python+人工智能,了解到有很多的第三方开源项目,可以不必亲自写高深莫测的算法,直接使用既能实现人脸识别。

于是,选择face_recognition人脸识别开源库,实现一个强大、简单、易上手的人脸识别系统案例;

废话不多说,先上设计思路:

1.设计思路

总体按照人脸识别、人脸比对以及识别记录,最后实现在线识别API接口。

2.模块设计 models

首先简单设计一下数据库模块;

两个表IMG、faceImg,分别保存原始图片和识别到的人脸图片;from dja

from django.db import models

# Create your models here.

class IMG(models.Model):
    img = models.ImageField(upload_to='img')
    name = models.CharField(max_length=20)

class faceImg(models.Model):
    parentid = models.ForeignKey(IMG,on_delete=models.CASCADE,verbose_name='来源',default=0)
    img = models.CharField(max_length=200,verbose_name='文件名',default='')
    name = models.CharField(max_length=20)

3.功能代码

views

核心代码

#获取上传照片信息,切取人脸
def uploadImg(request):
    """
    图片上传
    :param request:
    :return:
    """
    if request.method == 'POST':
        mdl = request.POST.get('mdl','hog')
        new_img = getImageFromRequest(request,img='img')
        if new_img != None :
            new_img.save()
            print(new_img.id)
            start = datetime.now()
            face_locations = recognition(new_img.img,mdl)
            end = datetime.now()
            print(end - start)

            # 遍历每个人脸,并切出单独人脸保存
            faceNum = len(face_locations)

            urls = []
            for i in range(0, faceNum):
                top = face_locations[i][0]
                right = face_locations[i][1]
                bottom = face_locations[i][2]
                left = face_locations[i][3]
                box = (left, top,right,bottom)
                im = Image.open(new_img.img)
                face_img = im.crop(box)

                f = datetime.now().strftime('%Y%m%d%H%M%S%f') + str(i) + '.jpg'
                print(f)
                face_img.save( os.path.join(settings.MEDIA_ROOT, 'face/') + f,'jpeg')

                face1 = faceImg(
                    parentid = new_img,
                    img = os.path.join(settings.MEDIA_URL, 'face/') + f ,
                    name= f
                )
                face1.save()

                urls.append(os.path.join(settings.MEDIA_URL, 'face/') + f)

            print(faceNum)
            return render(request, 'uploading.html',{
                'source':new_img.img.url,'faceNum':faceNum,'urls': urls,'useTime':end - start
            })
        else:
            return render(request, 'uploading.html',{'faceNum':'请选择图片'})
    else:
        return render(request, 'uploading.html')

#调用人脸识别,获取人脸位置
def recognition(object,modal):
    img = face_recognition.load_image_file(object)
    face_locations = face_recognition.face_locations(img,1,modal)
    print(face_locations)
    return face_locations


#通过request获取image file
def getImageFromRequest(request,img):
    try:
        return IMG(
                img=request.FILES.get(img),
                name=request.FILES.get(img).name
            )
    except Exception as e:
        return None

#两个照片比对
def image_compare_image(img1,img2,threshold):
    im1 = face_recognition.load_image_file(img1.img)
    im2 = face_recognition.load_image_file(img2.img)
    try:
        img1_encoding = face_recognition.face_encodings(im1)[0]
        img2_encoding = face_recognition.face_encodings(im2)[0]
        known_faces = [img1_encoding]
        sort = face_recognition.face_distance(known_faces, img2_encoding)
        # sort = 1 - sort
        print('sort = %f' % sort)
        result = face_recognition.compare_faces(known_faces, img2_encoding, tolerance=float(threshold))
        print(result)
        return sort, result
    except Exception as e:
        print(e)
        return -1,False


#人脸比对
def compare(request):
    if request.method == 'POST':
        urls = []
        sort = 0
        result = False
        t = request.POST.get('t',0.6)
        print('t = %s'%t)
        img1 = getImageFromRequest(request,img='img1')
        img2 = getImageFromRequest(request, img='img2')
        start = datetime.now()
        if img1 != None and img2 != None:
            sort,result = image_compare_image(img1,img2,t)

        end = datetime.now()
        print('use time : %s' %str(end - start))

        return render(request, 'compare.html',{'urls':urls,'sort':sort ,'result':result,'useTime':end-start})
    else:
        return render(request, 'compare.html',{})


#Web api 接口,返回人脸位置json
@csrf_exempt
def getFaceLocation(request):
    if request.method == 'POST':
        new_img = getImageFromRequest(request,img='img')
        if new_img != None:
            mdl = request.POST.get('mdl', 'hog')
            start = datetime.now()
            face_locations = recognition(new_img.img,mdl)
            end = datetime.now()

            print('use time : %s' % str(end - start))
            # 遍历每个人脸,并标注
            faceNum = len(face_locations)
            return  JsonResponse({'result':faceNum,'locations':face_locations,'useTime':end-start})

    return JsonResponse({'result':0,'locations':[]})


#Web api 接口,返回人脸比对分数
@csrf_exempt
def getCompare(request):
    if request.method == 'POST':
        sort = 0
        result = False
        t = request.POST.get('t',0.6)
        img1 = getImageFromRequest(request,img='img1')
        img2 = getImageFromRequest(request, img='img2')
        start = datetime.now()
        if img1 != None and img2 != None:
            sort, result = image_compare_image(img1, img2, t)
        end = datetime.now()
        print('use time : %s' %str(end - start))

        return JsonResponse({'sort':sort,'result':result})

    return None

4.测试报告,识别率说明

本项目,有2中模式,CPU和GPU,两种模式都要求高质量的照片;
经过测试N多的照片,单人多人的都有的情况下:
cpu模式中,速度快,但受到戴帽子、图片质量差的、背景太亮、逆光、人脸相对较小、人脸角度较大等因素的影响,识别率可达到90%左右;

gpu模式中,速度慢,对戴帽子的、人脸相对较小、人脸角度较大、识别率较高;但背景太亮、逆光、图片质量差的,识别较差,识别率可达98%;

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值