前置:
pip install flask
1.小栗子hello world。
W.py文件
#导入Flask类库
from flask import Flask
#创建应用实例app
app = Flask(__name__)
#路由
@app.route('/')
def index():
return "hello,world!"
#启动
if __name__ == "__main__":
app.run(port=4555, debug=True)
2. render_template模板。
把hello world改进成一个网页就要写个html文件,就引入render_template模板,把html文件放到templates文件夹内。
W1.py文件
#导入Flask类库
from flask import Flask, render_template
#创建应用实例app
app = Flask(__name__)
#路由
@app.route('/')
def index():
return render_template("index.html")
#启动
if __name__ == "__main__":
app.run(port=4555, debug=True)
index.html文件
<!DOCTYPE html>
<html>
<head>
<title>Upload</title>
</head>
<body>
<h1>欢迎使用Web目标检测服务</h1>
</form>
</body>
</html>
3.进阶 html 表单
将上面index.html文件修改,即可实现本地图片上传。
<!DOCTYPE html>
<html>
<head>
<title>Upload</title>
</head>
<body>
<h1>欢迎使用Web目标检测服务</h1>
<div class="upload-files">
<!--html form表单:id表单名;action提交地址(index页面url:当前页面地址);method提交方式(post);enctype在向服务器发送表单数据之前如何对其进行编码,method="post"时可以使用,值可以是:multipart/form-data、text/plain等。-->
<form id="upload-form" action="{{ url_for('upload') }}" method="POST" enctype="multipart/form-data">
<!--html strong标签:强调文本-->
<strong>Files:</strong><br>
<!--html 表单输入input:class 属性规定元素的类名(classname);type属性规定 input 元素的类型(file);accept接受不限制图像类型;multiple接受多个值的文件上传字段-->
<input class="upload-file" type="file" name="file" accept="image/*" multiple>
<div id="msg">
<!--html 表单输入input:class 属性规定元素的类名(classname);type属性规定 input 元素的类型(submit提交);value submit按钮的值;按钮id-->
<input class="upload-name" type="submit" value="提交图片" id="upload-button">
</div>
</form>
</body>
</html>
4.继续进阶 本地图片上传并返回给前端
新建web.html
<!DOCTYPE html>
<html>
<head>
<title>Upload</title>
</head>
<body>
<img src=" {{url_for('send_image', filename=image_name)}}">
</form>
</body>
</html>
W2.py
# -*- coding: utf-8 -*-
import os.path
import cv2
import os
from flask import Flask, request, render_template, send_from_directory
app = Flask(__name__)
APP_ROOT = os.path.dirname(os.path.abspath(__file__))
@app.route('/')
def index():
return render_template("index.html")
@app.route('/upload',methods=["POST"])
def upload():
target = os.path.join(APP_ROOT, 'images')
for upload in request.files.getlist("file"):
filename = upload.filename
destination = "/".join([target, filename])
upload.save(destination)
return render_template("web.html", image_name=filename)
@app.route('/upload/<filename>')
def send_image(filename):
return send_from_directory("images",filename)#send_from_directory可以用于附件下载链接的生成
if __name__ == "__main__":
app.run(port=4555, debug=True)
5.继续进阶 本地图片上传后用yolov3处理后返回给前端
W3.py
# -*- coding: utf-8 -*-
import os.path
import cv2
import os
from Detector import Predict
from flask import Flask, request, render_template, send_from_directory
app = Flask(__name__)
APP_ROOT = os.path.dirname(os.path.abspath(__file__))
@app.route("/")
def index():
return render_template("index.html")
@app.route("/upload", methods=["POST"])
def upload():
target = os.path.join(APP_ROOT, 'images/')
for upload in request.files.getlist("file"):
filename = upload.filename
destination = "/".join([target, filename])
upload.save(destination)
image = Predict(os.path.join(target, filename))
out_image = cv2.imwrite(os.path.join(target, "flask"+filename), image)
return render_template("web.html", image_name="flask"+filename)
@app.route('/upload/<filename>')
def send_image(filename):
return send_from_directory("images", filename)
if __name__ == "__main__":
app.run(port=4555, debug=True)
Detector.py
# -*- coding: utf-8 -*-
import numpy as np
import cv2
from PIL import Image, ImageFont, ImageDraw
import arabic_reshaper
from bidi.algorithm import get_display
def Predict(imagePath):
Confidence, Threshold, Width, Height = 0.01, 0.3, 608, 608
color1 = np.random.randint(0,255, size = 255)
color2 = np.random.randint(0,255, size = 255)
color3 = np.random.randint(0,255, size = 255)
font = ImageFont.truetype('Sahel.ttf', 20)
labels = ["person","bicycle","car","motorbike","aeroplane","bus","train","truck","boat",
"traffic light",
"fire hydrant",
"stop sign",
"parking meter",
"bench",
"bird",
"cat",
"dog",
"horse",
"sheep",
"cow",
"elephant",
"bear",
"zebra",
"giraffe",
"backpack",
"umbrella",
"handbag",
"tie",
"suitcase",
"frisbee",
"skis",
"snowboard",
"sports ball",
"kite",
"baseball bat",
"baseball glove",
"skateboard",
"surfboard",
"tennis racket",
"bottle",
"wine glass",
"cup",
"fork",
"knife",
"spoon",
"bowl",
"banana",
"apple",
"sandwich",
"orange",
"broccoli",
"carrot",
"hot dog",
"pizza",
"donut",
"cake","chair",
"sofa","pottedplant","bed","diningtable","toilet","tvmonitor","laptop","mouse","remote","keyboard","cell phone","microwave","oven","toaster","sink","refrigerator","book","clock","vase","scissors","teddy bear","hair drier","toothbrush"]
trained_model_configuration = "yolov3.cfg"
trained_model_weights = "yolov3.weights"
model = cv2.dnn.readNetFromDarknet(trained_model_configuration, trained_model_weights)
model.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV)
model.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU)
modelLayers = model.getLayerNames()
findOutputLayers = lambda model : [modelLayers[i[0] - 1] for i in model.getUnconnectedOutLayers()]
def boxPlot(labelIdx, confidence, left, top, right, bottom, i):
clr1 = color1[i]
clr2 = color2[i]
clr3 = color3[i]
d = ImageDraw.Draw(picture)
d.rectangle([(left, top), (right, bottom)], None, (clr1, clr2, clr3), 3)
if labels:
assert(labelIdx < len(labels))
reshaped_text = arabic_reshaper.reshape(labels[labelIdx])
bidi_text = get_display(reshaped_text)
d.text((left, top - 5), bidi_text, font = font, fill=(clr1,clr2,clr3))
def boxDet(image, model_outputs):
imHeight = image.shape[0]
imWidth = image.shape[1]
classIds = []
confidences = []
boxes = []
for output in model_outputs:
for prediction in output:
scores = prediction[5:]
labelIdx = np.argmax(scores)
confidence = scores[labelIdx]
if confidence > Confidence:
center_x = int(prediction[0] * imWidth)
center_y = int(prediction[1] * imHeight)
width = int(prediction[2] * imWidth)
height = int(prediction[3] * imHeight)
left = int(center_x - width / 2)
top = int(center_y - height / 2)
classIds.append(labelIdx)
confidences.append(float(confidence))
boxes.append([left, top, width, height])
indices = cv2.dnn.NMSBoxes(boxes, confidences, Confidence, Threshold)
result = []
for i in indices:
i = i[0]
box = boxes[i]
left = box[0]
top = box[1]
width = box[2]
height = box[3]
x = boxPlot(classIds[i], confidences[i], left, top, left + width, top + height, i)
result.append(x)
return result
if (imagePath):
frame = cv2.imread(imagePath)
#print(frame.shape)
outputFile = imagePath[:-4]+'_Object_Detector.jpg'
picture = Image.fromarray(frame)
blob = cv2.dnn.blobFromImage(frame, 1/255, (Width, Height), [0,0,0], 1, crop=False)
model.setInput(blob)
model_outputs = model.forward(findOutputLayers(model))
boxDet(frame, model_outputs)
if (imagePath):
print('image')
opencvimage = np.array(picture)
print('Done!')
return opencvimage
requirements.txt
Flask
numpy
python-bidi
arabic_reshaper
pillow
参考:https://github.com/KiLJ4EdeN/Persian_ObjectDetection_WebService