Python Web开发:在线人脸检测
来自CloudWiki
背景
在上一节基础上 提供一种在线Web调用的功能,
即用户在网页上上传一张照片,然后单击检测即可在网页上实现人脸检测并获取检测结果。
这种方式可以方便的让用户无须编写任何脚本代码即可体验功能
实训步骤
编写网页端功能
主要使用Bootstrap的模式对话框来实现图片的在线检测,
采用这种方式,可以方便的在页面中进行额外的界面操作 而不影响页面原有布局。
serviceApp/platform.html:
在<h3>一. 体验产品</h3></br>下面添加“模式对话框”代码:
<!-- 按钮触发模态框 --> <button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal"> 人脸检测 </button> <!-- 模态框(Modal) --> <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true"> × </button> <h4 class="modal-title" id="myModalLabel"> 在线人脸检测 </h4> </div> <div class="modal-body"> <img id="photoIn" src="{% static 'img/sample.png' %}" class="img-responsive" style="max-width:250px"> <input type="file" id="photo" name="photo" /> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">关闭 </button> <button type="button" id="compute" class="btn btn-primary"> 开始检测 </button> </div> </div><!-- /.modal-content --> </div><!-- /.modal --> </div> <script> $(function () { $('#photo').on('change', function () { var r = new FileReader(); f = document.getElementById('photo').files[0]; r.readAsDataURL(f); r.onload = function (e) { document.getElementById('photoIn').src = this.result; }; }); }); </script>
- 通过“人脸检测”的按钮来调用模式对话框,通过设定按钮的data-toggle和data-target参数来设定模式对话框,
- 模式对话框分为三部分功能:modal-header,modal-body 和modal-footer.
- 图像显示逻辑:模式对话框主体放置了两个组件:一个组件用于显示当前上传图片,另一个文件上传组件用于选择本地图片进行上传。当用户单击“浏览”时,会触发输入图片的change属性,待上传的图片实时显示在图片组件上。
图片发送和结果显示
接下来使用Ajax技术实现图片发送,将图片发送至服务器并进行人脸检测。
<script> $('#compute').click(function () { formdata = new FormData(); var file = $("#photo")[0].files[0]; formdata.append("image", file); $.ajax({ url: '/serviceApp/facedetectDemo/', // 调用Django服务器计算函数 type: 'POST', // 请求类型 data: formdata, dataType: 'json', // 期望获得的响应类型为json processData: false, contentType: false, success: ShowResult // 在请求成功之后调用该回调函数输出结果 }) }) </script> <script> function ShowResult(data) { var v = data['img64']; document.getElementById('photoIn').src = "data:image/jpeg;base64, " + v; } </script>
- 基于Ajax的图像发送,采用FormData的格式,即将上传的图片文件用formdata.append完成封装,
- 在ajax的data属性中嵌入formdata变量,以POST方式发送到地址/serviceApp/facedetectDemo/中。
- 如果成功,返回结果使用函数ShowResult显示。base64是网络上最常见的用于传输8位字节码的编码方式之一,为了能够在网络上正常传输图像数据,这里采用base64进行图像的解编码。
后台视图函数
后台视图函数 我们可以在Python Web开发:人脸识别后台搭建 代码的基础上修改,
在原代码的基础上增加人脸框划定功能。
serviceApp/views.py:
import base64 @csrf_exempt def facedetectDemo(request): result = {} if request.method == "POST": if request.FILES.get('image') is not None: # img = read_image(stream=request.FILES["image"]) else: result["#faceNum"] = -1 return JsonResponse(default) if img.shape[2] == 3: imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 彩色图像转灰度图像 else: imgGray = img #进行人脸检测 values = face_detector.detectMultiScale(imgGray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30), flags=cv2.CASCADE_SCALE_IMAGE) #将检测得到的人脸检测关键点坐标封装 values = [(int(a), int(b), int(a + c), int(b + d)) for (a, b, c, d) in values] # 将检测框显示在原图上 for (w, x, y, z) in values: cv2.rectangle(img, (w, x), (y, z), (0, 255, 0), 2) retval, buffer_img = cv2.imencode('.jpg', img) # 在内存中编码为jpg格式 img64 = base64.b64encode(buffer_img) # base64编码用于网络传输 img64 = str(img64, encoding='utf-8') # bytes转换为str类型 result["img64"] = img64 # json封装 return JsonResponse(result)
- 实现逻辑: 处理函数从POST请求中通过request.FILES.get('image')获取图像
- 然后根据定义的read_image来读取图像,转灰度,进行人脸检测
- 将检测到的矩形画在原图上,然后对图像进行jpg及base64转码 返回数据。
添加路由
serviceApp/urls.py:
from django.urls import path from . import views app_name = 'serviceApp' urlpatterns = [ path('download/', views.download, name='download'), # 资料下载 path('platform/', views.platform, name='platform'), # 人脸识别开放平台 path('getDoc/<int:id>/',views.getDoc,name='getDoc'), path('facedetect/',views.facedetect,name='facedetect'),#人脸检测API path('facedetectDemo/',views.facedetectDemo,name='facedetectDemo'),#人脸检测API ]