最终调用的方法,可以直接测试:
  
1、打开地址:http://81.68.242.86:8000/upload
   
    

   
2、选择并上传图片,完成后回显地址(需要消耗一定时间):
   
      

   
   
3、需要手工粘贴,而后显示处理后的结果。
   
比如上图就改为
   
“ http://81.68.242.86:8000/medias/111038jzs1zz11sx11snj6.jpg.result.jpg”,注意由upload改为medias
      

   
   
一、Django环境构建
   
1、在管理员权限下,直接可以使用pip进行安装。
pip3 install django
     
      

     
     
如果网络正常,那么可以通过
pip3 show django
查看django版本和django安装路径:
     
      

     
       
     
2、创建一个django project
在空文件夹下,使用以下命令创建django project
django-admin.py startproject mysites
     
      

     
     
我们可以使用vscode来查看,其中较为关键的几成都项:
| 
 | manage.py ----- Django项目里面的工具,通过它可以调用django shell和数据库等。 settings.py ---- 包含了项目的默认设置,包括数据库信息,调试标志以及其他一些工作的变量。 urls.py ----- 负责把URL模式映射到应用程序。 | 
需要注意的是,这里的几个py都是行使管理权限的。
3、在mysites目录下创建应用(app)
python3 manage.py startapp goApp
     
      

     
这新建一个goApp的实际项目,这个实际的项目是可以被启动的。
4、启动django项目
python3 manage.py runserver 8080
这样,我们的django就启动起来了。当我们访问http://127.0.0.1:8080/时,可以看到
     
      

     
         
     
       

     
如果以上工作全部能够成功,那么证明Django的下载安装是成功的,下面我们来具体理解其相关内容。
这里需要注意,如果需要外部IP访问,这样设置:python manage.py runserver 0.0.0.0:8000
如果再出现“Invalid HTTP_HOST header”
解决方法:
修改settings.py
     
ALLOWED_HOSTS = ['192.168.2.157','127.0.0.1']
     
值为'*',可以使所有的网址都能访问Django项目了,失去了保护的作用,可以用于测试
     
ALLOWED_HOSTS = [ ' * ' ]
     
比如,这样运行
     
python3 manage.py runserver 0.0.0.0:8080
     
二、文件结构和各种作用
manage.py文件位于整个项目的最外层,是该项目的项目管理器,通过不指定命令运行,可以发现它具备以下功能。
     
      

     
     
比如,我们在上面使用过的:
     
创建应用:python3 manage.py startapp goApp
启动项目:python3 manage.py runserver 8080
     
wsgi.py:全称 webserver getway interface,即Web服务器的网关接口
     
      

     
     
urls.py:即路由配置
django下所有的页面都需要urls文件中配置一下,否则在访问的时候会找不到该文件。
     
      

     
     
settings.py:
配置文件,各种路径、国际化、debug、模版等均在此文件中配置。
2.3、简单示例
我了进一步加速对相关知识的理解,我们创建一个最为简单的程序,它能够实现的就是读取并显示当前系统OpenCV版本。我们需要改写以下文件:
url控制器 url.py
     
from
django.contrib
import
admin
from
django.urls
import
path
from goApp import
urlpatterns
=
[
path(
'admin/'
, admin.
site
.urls),
path('index/',views.index),
       
      
视图 view.py
      
from
django.shortcuts
import
render
from django.http import HttpResponseimport cv2def index(request): return HttpResponse(cv2.__version__
      
     
以上代码中,标红的部分代表是新添加的,代码修改后,djangon会自动更新。运行结果如下:
      
       

      
需要注意到,goApp是我们新创建的app的名称,这里相当于在主目录中,引用我们的新编模块。
      
如果能够运行到这一步,那么证明OpenCV相关的引入工作已经没有问题。
   
三、算法融合,构建 django服务构建
    
我们从最简单的情况,一步一步来实现。(需要进一步总计当前的算法细节)
   
3.1 添加新路由,修改url.py
   
from django.contrib import admin
      
from django.urls import path,register_converter,re_path
      
from django.conf.urls import url
      
from goApp import views
      
from django.conf import settings
      
from django.conf.urls.static import static
      
from django.views.static import serve
      
urlpatterns = [
      
path( 'admin/', admin.site.urls),
      
path( 'index/',views.index),
      
path( 'upload/', views.upload), # 上传图片
      
path( 'process/',views.process),
      
url( r '^process_detail/(.+ )/$',views.process_detail),
      
url( r '^medias/( ?P<path> .* )$', serve, { 'document_root': '/root/mysites/goApp/upload/'}),
      
]
   
其中,upload是显示界面;process_detail是单图片处理页面,medias是图片显示页面。
   
3.2 算法主要在goApp中实现
   
       

   
   
主要算法,实现在view.py中
   
from django.shortcuts import render
     
from django.http import HttpResponse
     
from django.conf import settings
     
from django.shortcuts import redirect, reverse
     
#from .models import User,Article
     
from datetime import datetime
     
import argparse
     
import cv2
     
import datetime
     
import grpc
     
import numpy as np
     
import os
     
import sys
     
import hashlib
     
from tensorflow import make_tensor_proto, make_ndarray
     
from tensorflow_serving.apis import predict_pb2
     
from tensorflow_serving.apis import prediction_service_pb2_grpc
     
sys.path.append( '/root/mysites/goApp')
     
from client_utils import print_statistics
     
classes_color_map = [
     
( 150, 150, 150),
     
( 58, 55, 169),
     
( 211, 51, 17),
     
( 157, 80, 44),
     
( 23, 95, 189),
     
( 210, 133, 34),
     
( 76, 226, 202),
     
( 101, 138, 127),
     
( 223, 91, 182),
     
( 80, 128, 113),
     
( 235, 155, 55),
     
( 44, 151, 243),
     
( 159, 80, 170),
     
( 239, 208, 44),
     
( 128, 50, 51),
     
( 82, 141, 193),
     
( 9, 107, 10),
     
( 223, 90, 142),
     
( 50, 248, 83),
     
( 178, 101, 130),
     
( 71, 30, 204)
     
]
     
def load_image(file_path):
     
img = cv2.imread(file_path) # BGR color format, shape HWC
     
img = cv2.resize(img, ( 2048, 1024))
     
img = img.transpose( 2, 0, 1).reshape( 1, 3, 1024, 2048)
     
return img
     
def index(request):
     
#users = User.objects.all()
     
#article = Article.objects.all()
     
return render(request, 'index.html')
     
def upload(request):
     
if request.method == 'GET':
     
return render(request, 'upload.html')
     
else:
     
name = request.POST.get( 'name')
     
pic = request.FILES.get( 'avator')
     
#media_root = settings.MEDIA_ROOT # media
     
media_root = '/root/mysites/goApp'
     
allow_upload = settings.ALLOW_UPLOAD # ALLOW_UPLOAD
     
#path = 'upload/{}_{}_{}/'.format(datetime.datetime.now().year,'{:02d}'.format(datetime.datetime.now().month), '{:02d}'.format(datetime.datetime.now().day))
     
path = 'upload/'
     
full_path = media_root + '/' + path
     
if not os.path.exists(full_path): # 判断路径是否存在
     
os.makedirs(full_path) # 创建此路径
     
# 要不要改图片的名字 生成hash
     
# 这块要不要判断图片类型 .jpg .png .jpeg
     
# '/../../../myviews/setting.py'
     
print(pic)
     
print(full_path)
     
print(full_path+pic.name)
     
if pic.name.split( '.')[- 1] not in allow_upload:
     
return HttpResponse( 'fail')
     
with open(full_path + '/' + pic.name, 'wb') as f:
     
for c in pic.chunks(): # 相当于切片
     
f.write(c)
     
#User.objects.create(name=name, avator=path + pic.name)
     
#return redirect('index.html')
     
#return HttpResponse(full_path+pic.name)
     
return process_detail(request,full_path+pic.name)
     
def process(request):
     
options = [( 'grpc.max_receive_message_length', 100 * 1024 * 1024),( 'grpc.max_send_message_length', 100 * 1024 * 1024)]
     
channel = grpc.insecure_channel( "{}:{}".format( 'localhost', 9000),options = options)
     
stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)
     
batch_size = 1
     
# TODO
     
files = os.listdir( '/root/mysites/goApp/images')
     
print(files)
     
imgs = np.zeros(( 0, 3, 1024, 2048), np.dtype( '<f'))
     
for i in files:
     
img = load_image(os.path.join( '/root/mysites/goApp/images', i))
     
imgs = np.append(imgs, img, axis= 0) # contains all imported images
     
iteration = 0
     
for x in range( 0, imgs.shape[ 0] - batch_size + 1, batch_size):
     
iteration += 1
     
request = predict_pb2.PredictRequest()
     
request.model_spec.name = "semantic-segmentation-adas"
     
img = imgs[x:(x + batch_size)]
     
#print("\nRequest shape", img.shape)
     
request.inputs[ "data"].CopyFrom(make_tensor_proto(img, shape=(img.shape)))
     
start_time = datetime.datetime.now()
     
result = stub.Predict(request, 10.0) # result includes a dictionary with all model outputs print(img.shape)
     
output = make_ndarray(result.outputs[ "4455.1"])
     
for y in range( 0,img.shape[ 0]): # iterate over responses from all images in the batch
     
img_out = output[y,:,:,:]
     
print( "image in batch item",y, ", output shape",img_out.shape)
     
img_out = img_out.transpose( 1, 2, 0)
     
print( "saving result to",os.path.join( '/root/mysites/goApp/results',str(iteration)+ "_"+str(y)+ '.jpg'))
     
out_h, out_w,_ = img_out.shape
     
#print(out_h)
     
#print(out_w)
     
for batch, data in enumerate(output):
     
classes_map = np.zeros(shape=(out_h, out_w, 3), dtype=np.int)
     
for i in range(out_h):
     
for j in range(out_w):
     
if len(data[:, i, j]) == 1:
     
pixel_class = int(data[:, i, j])
     
else:
     
pixel_class = np.argmax(data[:, i, j])
     
classes_map[i, j, :] = classes_color_map[min(pixel_class, 20)]
     
output_str = os.path.join( '/root/mysites/goApp/results',str(iteration)+ "_"+str(batch)+ '.jpg')
     
cv2.imwrite(output_str,classes_map)
     
return HttpResponse(output_str)
     
def process_detail(request,param1):
     
options = [( 'grpc.max_receive_message_length', 100 * 1024 * 1024),( 'grpc.max_send_message_length', 100 * 1024 * 1024)]
     
channel = grpc.insecure_channel( "{}:{}".format( 'localhost', 9000),options = options)
     
stub = prediction_service_pb2_grpc.PredictionServiceStub(channel)
     
batch_size = 1
     
# TODO filepath
     
output_str= 'filepath'
     
imgfile = os.path.join( '/root/mysites/goApp/images',param1)
     
print(imgfile)
     
img = load_image(imgfile)
     
imgs = np.zeros(( 0, 3, 1024, 2048), np.dtype( '<f'))
     
imgs = np.append(imgs, img, axis= 0)
     
request = predict_pb2.PredictRequest()
     
request.model_spec.name = "semantic-segmentation-adas"
     
print( "\nRequest shape", img.shape)
     
img = imgs[ 0: 1]
     
request.inputs[ "data"].CopyFrom(make_tensor_proto(img, shape=(img.shape)))
     
result = stub.Predict(request, 10.0) # result includes a dictionary with all model outputs print(img.shape)
     
output = make_ndarray(result.outputs[ "4455.1"])
     
for y in range( 0,img.shape[ 0]): # iterate over responses from all images in the batch
     
img_out = output[y,:,:,:]
     
print( "image in batch item",y, ", output shape",img_out.shape)
     
img_out = img_out.transpose( 1, 2, 0)
     
print( "saving result to",os.path.join( '/root/mysites/goApp/results',param1+ '.result.jpg'))
     
out_h, out_w,_ = img_out.shape
     
print(out_h)
     
print(out_w)
     
for batch, data in enumerate(output):
     
classes_map = np.zeros(shape=(out_h, out_w, 3), dtype=np.int)
     
for i in range(out_h):
     
for j in range(out_w):
     
if len(data[:, i, j]) == 1:
     
pixel_class = int(data[:, i, j])
     
else:
     
pixel_class = np.argmax(data[:, i, j])
     
classes_map[i, j, :] = classes_color_map[min(pixel_class, 20)]
     
output_str = os.path.join( '/root/mysites/goApp/results',param1+ '.result.jpg')
     
cv2.imwrite(output_str,classes_map)
     
return HttpResponse(output_str)
   
3.3 在template 中添加两段html用于界面显示
   
    

   
<! DOCTYPE html >
      
< html lang= "en" >
      
< head >
      
< meta charset= "UTF-8" >
      
< title >OpenVINO Model Server的服务化部署(天空分割模型) </ title >
      
</ head >
      
< body >
      
< form action= "/upload/" method= "post" enctype= "multipart/form-data" >
      
{% csrf_token %}
      
图片: < input type= "file" name= "avator" >< br >
      
< input type= "submit" value= "提交" >
      
</ form >
      
</ body >
      
</ html >
   
前段编写的时候,细节很多,这里无法一一重复。
   
四、服务器标准重启命令
   
1 、启动docker [root@VM - 0 - 13 - centos / ] # docker run -d -v /models:/models:ro -p 9000:9000 openvino/model_server:latest --model_path /models/model2 --model_name semantic-segmentation-adas --port 9000 --log_level DEBUG --shape auto 2 、启动django [root@VM -
0
-
13
-
centos mysites]
# python3 manage.py runserver 0.0.0.0:8000
3
、浏览器中输入:http
:
/
/
81
.
68
.
242
.
86
:
8000
/
index
/
进行测试
也可以输入 http
:
/
/
81
.
68
.
242
.
86
:
8000
/
process_detail
/
sky20.jpg
/
   
 
 
附件列表
  











