当前位置:   article > 正文

基于django的人脸检测web平台搭建(Python3+Opencv,windows平台,内含代码)_django框架ai检测

django框架ai检测

现在很多“大厂”均提供基于AI的开放平台,以web的形式对外提供AI服务(人脸识别、OCR识别、语音识别等)。以人脸检测为例,用户通过特定的api接口上传需要检测的照片,然后web服务器对照片进行人脸检测,并将检测结果返回给用户。采用这种web部署人工智能产品的好处在于AI算法往往需要较多的配置、较高的服务器性能才能进行算法推演,这种方式使得管理员只需要管理和配置服务器即可,不需要再关注用户PC的配置和性能。另外,AI算法的更新也只需要在服务器上进行即可,适合生产环境的快速部署(小步快跑,快速迭代)。

本教程拟模仿上述流程,通过django框架搭建一个人脸检测web平台,以api接口形式对外提供服务。这里为了简单,只使用opencv提供的现成的人脸检测算法来进行检测,实际情况下可以根据服务器配置(GPU性能)采用更高级的人脸检测算法(例如基于深度学习的MTCNN人脸检测算法等)来提高检测精度。

开发环境

python 3.6  (安装教程:https://blog.csdn.net/qianbin3200896/article/details/81098498)

额外的python包和库:

pip install numpy
pip install django==1.11.14
pip install requests

另外,还需要安装opencv来进行人脸检测。opencv安装包下载地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/#opencv

这里由于使用的是python3.6版本,主机为64位win7系统,因此选择opencv_python‑3.4.5‑cp36‑cp36m‑win_amd64.whl进行下载和安装:

pip install opencv_python-3.4.5-cp36-cp36m-win_amd64.whl

开发

1.创建项目和应用

django-admin startproject facedetection

然后cd到项目根目录:

cd facedetection

下面创建一个应用:

python manage.py startapp app

最后,将新添加的app应用添加到项目中,打开facedetection子文件夹下的settings.py文件,找到其中的INSTALLED_APPS字段,再该字段末尾添加app应用:

  1. INSTALLED_APPS = [
  2. 'django.contrib.admin',
  3. 'django.contrib.auth',
  4. 'django.contrib.contenttypes',
  5. 'django.contrib.sessions',
  6. 'django.contrib.messages',
  7. 'django.contrib.staticfiles',
  8. 'app',#添加新的app应用
  9. ]

新添加的应用下面有多个文件,包括views.py、models.py等。由于我们需要开发基于rest-api的接口,因此大部分代码都会在views.py文件中编写。

2.  编写后台api接口

首先在views.py文件中导入一些库:

  1. from django.shortcuts import render # django的模板渲染包
  2. ### Initializing the imports
  3. import numpy as np # 矩阵运算
  4. import urllib # url解析
  5. import json # json字符串使用
  6. import cv2 # opencv包
  7. import os # 执行操作系统命令
  8. from django.views.decorators.csrf import csrf_exempt # 跨站点验证
  9. from django.http import JsonResponse # json字符串返回

为了能够进行人脸检测,需要使用特定的人脸检测器,一般情况下需要运用机器学习算法进行训练得到,幸运的是Opencv自带高效的人脸检测器,可以无需训练直接拿来使用。在Opencv的安装目录中找到haarcascade_frontalface_default.xml,也可以从本教程最后提供的代码链接中获取得到。该xml文件定义了训练好的人脸特征检测器,只需要在Opencv中导入该文件即可进行人脸检测。为了方便项目使用,将该xml文件放置在项目根目录下(与manage.py文件同一目录)。

继续编辑views.py文件,添加代码如下:

  1. face_detector = "haarcascade_frontalface_default.xml" # 默认放置在项目根目录下
  2. @csrf_exempt #用于规避跨站点请求攻击
  3. def facedetect(request):
  4. default = {"safely executed": False} #初始未执行
  5. #规定客户端使用POST请求上传检测图片
  6. if request.method == "POST":
  7. if request.FILES.get("image", None) is not None: #请求中包含图像则以流形式读取图像
  8. image_to_read = read_image(stream = request.FILES["image"])
  9. else: # 以URL形式读取图像
  10. url_provided = request.POST.get("url", None)
  11. if url_provided is None:
  12. default["error_value"] = "未提供URL路径"
  13. return JsonResponse(default)
  14. image_to_read = read_image(url = url_provided) #以url形式读取图像
  15. image_to_read = cv2.cvtColor(image_to_read, cv2.COLOR_BGR2GRAY) #彩色图像转灰度
  16. detector_value = cv2.CascadeClassifier(face_detector) #生成人脸检测器
  17. #进行人脸检测
  18. values = detector_value.detectMultiScale(image_to_read,
  19. scaleFactor=1.1,
  20. minNeighbors = 5,
  21. minSize=(30,30),
  22. flags = cv2.CASCADE_SCALE_IMAGE)
  23. #将检测得到的人脸检测关键点坐标封装
  24. values=[(int(a), int(b), int(a+c), int(b+d)) for (a,b,c,d) in values]
  25. default.update({"#of_faces": len(values),
  26. "faces":values,
  27. "safely_executed": True })
  28. return JsonResponse(default)

上述代码以POST请求方式处理请求,同时提供两种文件上传方式,一种就是以url形式提供,还有就是将图像内容封装在request的FILES中,然后解析得到。因此,也就需要两种读取图片的方式,这里额外编写了read_image函数用于处理,具体代码为:

  1. def read_image(stream=None, url=None):
  2. if url is not None:
  3. response = urllib.request.urlopen(url)
  4. data_temp = response.read()
  5. elif stream is not None:
  6. data_temp = stream.read()
  7. image = np.asarray(bytearray(data_temp), dtype="uint8")
  8. image = cv2.imdecode(image, cv2.IMREAD_COLOR)
  9. return image

至此,视图函数已经处理完毕。接下来添加访问路由,打开facedetection子文件夹下的urls.py文件,添加路由:

  1. from django.conf.urls import url
  2. from django.contrib import admin
  3. from app.views import facedetect #导入人脸检测视图函数
  4. urlpatterns = [
  5. url(r'^admin/', admin.site.urls),
  6. url(r'^facedetect/$', facedetect, name='facedetect'), #添加对应的路由
  7. ]

最后启动项目:

python manage.py runserver

默认当前服务器运行在 http://127.0.0.1:8000/ 上。

3.  编写本地调用demo

下面以一个简单的python脚本为例,将本地的图片上传至服务器进行人脸检测,图片名为:temp.jpg。新建脚本test_run.py,代码如下:

  1. import cv2, requests
  2. url = "http://localhost:8000/facedetect/" # web地址(http://localhost:8000)+访问接口(facedetect)
  3. # 上传图像并检测
  4. #tracker = {"url": "https://image.ibb.co/cPrdgS/image5.jpg"}
  5. tracker = None
  6. files = {
  7. "image":("filename2", open("temp.jpg", "rb"), "image/jpeg"),
  8. }
  9. req = requests.post(url,data=tracker,files=files).json()
  10. print("temp.jpg: {}".format(req))
  11. # 将检测结果框显示在图像上
  12. image_to_read = cv2.imread("temp.jpg")
  13. for (w,x,y,z) in req["faces"]:
  14. cv2.rectangle(image_to_read,(w,x), (y,z), (0, 255, 0), 2)
  15. cv2.imshow("检测图像", image_to_read)
  16. cv2.waitKey(0)

运行脚本:

python test_run.py

结果如下图所示:

上面代码提供了两种上传方式,一种是本地图片上传的方式,也是代码中使用的方式。还有一种就是直接传输图片的url路径,此时只需要将 requests.post中的files参数设置为None即可。

3.web在线调用

上面提供了一种本地调用接口的方式。本节讲解一种在线web调用的方式,即用户在网页上上传一张照片,然后单击提交即可在网页上实现人脸检测。这种方式可以方便的让用户无需编写任何脚本代码即可体验功能。首先来编写网页,在app文件夹下创建templates文件夹(不要修改该文件夹名字,因为django有自动搜索模板机制,以templates命名),然后在templates文件夹下创建一个index.html文件。编辑index.html文件如下:

  1. {% load staticfiles %}
  2. <!DOCTYPE html>
  3. <html>
  4. <head>
  5. <title>人脸检测平台</title>
  6. <script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
  7. <script type="text/javascript">
  8. function ProcessFile(e) {
  9. var file = document.getElementById('file').files[0];
  10. if (file) {
  11. var reader = new FileReader();
  12. reader.onload = function (event) {
  13. var txt = event.target.result;
  14. var img = document.createElement("img");
  15. img.src = txt; //将图片base64字符串赋值给img的src
  16. document.getElementById("result").appendChild(img);
  17. };
  18. }
  19. reader.readAsDataURL(file);
  20. }
  21. function contentLoaded() {
  22. document.getElementById('file').addEventListener('change',
  23. ProcessFile, false);
  24. }
  25. window.addEventListener("DOMContentLoaded", contentLoaded, false);
  26. </script>
  27. </head>
  28. <body>
  29. 请选取一个图像文件: <input type="file" id="file" name="file" />
  30. <div id="result"></div>
  31. <div id="result_new"></div>
  32. <img id="ewmtp" src="https://img-blog.csdnimg.cn/2022010618314630403.png" alt="Red dot" />
  33. <div>
  34. <button type="button" class="btn btn-primary btn-lg" id="lgbut_compute">提交</button>
  35. </div>
  36. <script>
  37. function ShowResult(data) {
  38. var v = data['img64'];
  39. var img = document.createElement("img_new");
  40. img.src = "data:image/jpeg;base64, " + v;
  41. document.getElementById("result_new").appendChild(img);
  42. ewmtp.src = "data:image/jpeg;base64, " + v;
  43. }
  44. </script>
  45. <script>
  46. $('#lgbut_compute').click(function () {
  47. formdata = new FormData();
  48. var file = $("#file")[0].files[0];
  49. formdata.append("image", file);
  50. $.ajax({
  51. url: '/facedetectDemo/', //调用django服务器计算函数
  52. type: 'POST', //请求类型
  53. data: formdata,
  54. dataType: 'json', //期望获得的响应类型为json
  55. processData: false,
  56. contentType: false,
  57. success: ShowResult //在请求成功之后调用该回调函数输出结果
  58. })
  59. })
  60. </script>
  61. </body>
  62. </html>

该文件提供了输入组件让用户上传照片,当用户单击“提交”按钮时通过ajax技术将照片发送至服务器,然后根据回调函数ShowResult接收服务器返回的检测结果,最后将检测结果图像进行显示。在该过程中尤其需要注意图像的base64编码和使用。

接下来,为了管理方便,额外的编写后端接口,在views.py文件中添加代码如下:

  1. def home(request):
  2. return render(request, 'index.html')
  3. import base64
  4. @csrf_exempt #用于规避跨站点请求攻击
  5. def facedetectDemo(request):
  6. default = {"safely executed": False} #初始未执行
  7. #规定客户端使用POST请求上传检测图片
  8. if request.method == "POST":
  9. if request.FILES.get('image') is not None: #请求中包含图像则以流形式读取图像
  10. image_to_read = read_image(stream = request.FILES["image"])
  11. else: # 返回错误说明
  12. default["error_value"] = "提交格式错误,无法解析到image图像"
  13. return JsonResponse(default)
  14. imgGray = cv2.cvtColor(image_to_read, cv2.COLOR_BGR2GRAY) #彩色图像转灰度
  15. detector_value = cv2.CascadeClassifier(face_detector) #生成人脸检测器
  16. #进行人脸检测
  17. values = detector_value.detectMultiScale(imgGray,
  18. scaleFactor=1.1,
  19. minNeighbors = 5,
  20. minSize=(60,60),
  21. flags = cv2.CASCADE_SCALE_IMAGE)
  22. #将检测得到的人脸检测关键点坐标封装
  23. values=[(int(a), int(b), int(a+c), int(b+d)) for (a,b,c,d) in values]
  24. #将检测框显示在原图上
  25. for (w,x,y,z) in values:
  26. cv2.rectangle(image_to_read,(w,x), (y,z), (0, 255, 0), 2)
  27. retval, buffer_img= cv2.imencode('.jpg', image_to_read) #在内存中编码为jpg格式
  28. img64 = base64.b64encode(buffer_img) #base64编码转换用于网络传输
  29. img64=str(img64, encoding='utf-8') #bytes转换为str类型
  30. default["img64"] = img64 #json封装
  31. return JsonResponse(default)

其中home函数用来显示首页,通过django的render函数将index.html模板文件进行渲染。接下来重点需要关注facedetectDemo函数,该函数是为了在线web调用而进行的人脸检测接口简化版本,其中大部分代码与facedetect函数一致,但是在返回结果时需要注意图像的编解码问题,即先将图像压缩编码成jpg格式,然后转化成base64方便网络传输,最后再转化成str类型封装成json字符串返回。

最后,添加对应的路由,打开urls.py文件,编辑代码如下:

  1. from django.conf.urls import url
  2. from django.contrib import admin
  3. from app.views import facedetect,home,facedetectDemo
  4. urlpatterns = [
  5. url(r'^admin/', admin.site.urls),
  6. url(r'^facedetect/$', facedetect, name='facedetect'),
  7. url(r'^$', home, name='home'),
  8. url(r'^facedetectDemo/$', facedetectDemo, name='facedetectDemo'),
  9. ]

运行项目:

python manage.py runserver

在页面上上传图像,然后单击“提交”进行测试,最终效果图如下:

4.代码下载

最后给出部分代码链接:https://download.csdn.net/download/qianbin3200896/11094507

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/498351
推荐阅读
相关标签
  

闽ICP备14008679号