在AWS上部署简单的目标检测项目

前提条件

实验环境

  • Ubuntu 16.04 LTS
  • Python 3.5.2
  • Tesorflow 2.3.0
  • Flask 1.1.1
  • Numpy 1.18.5
  • Opencv 3.4.2

下载相关库

sudo pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple numpy==1.18.5
sudo pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python==3.4.2.16 opencv-contrib-python==3.4.2.16
sudo pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple flask
sudo pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple tensorflow==2.3.0

在这里插入图片描述

在这里插入图片描述

项目结构

├─Flask_obj_detection
│  ├─static
│  │  └─images
│  │  └─LeNet_classify_model.h5
│  ├─templates
│  │  └─upload.html
│  │  └─upload_success.html
│  ├─flask_app.py
│  ├─SelectSearch.py 

具体步骤

创建项目结构

mkdir Flask_obj_detection
cd Flask_obj_detection
mkdir static templates
cd static 
mkdir images

在这里插入图片描述

编写py文件

vi SelectSearch.py

其内容如下:

import sys
import cv2
import numpy as np
import tensorflow as tf
from tensorflow.keras import datasets, layers, models
import os

def detect(path,detected_path,weight_path):
	# 读取图片
	img = cv2.imread(path)
	# print(img)
	# 按比例缩放图片
	newHeight = 200
	newWidth = int( img.shape[1] * 200 / img.shape[0] )
	img = cv2.resize( img, (newWidth, newHeight) )
	# 创建选择性搜索分割对象
	ss = cv2.ximgproc.segmentation.createSelectiveSearchSegmentation()
	# 设置输入图像,我们将运行分割
	ss.setBaseImage( img )
	# 快速但低召回选择性搜索方法
	ss.switchToSelectiveSearchFast()
	# 高召回但慢选择性搜索方法
	# ss.switchToSelectiveSearchQuality()

	# 运行选择性搜索分割输入图像
	rects = ss.process()
	# print(rects)
	# print( 'Total Number of Region Proposals: {}'.format( len( rects ) ) )
	class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer',
				   'dog', 'frog', 'horse', 'ship', 'truck']
	# 加载创建完全相同的模型,包括其权重和优化程序
	loaded_model = tf.keras.models.load_model(weight_path)
	while True:
		# 创建原始图像的副本
		new_img = img.copy()
		# print(new_img)
		region_score = []
		max_rect = 0
		max_name = ""
		max_score = 0
		# 重复所有的区域建议
		for i, rect in enumerate( rects ):
			x, y, w, h = rect # 预测框的左上角坐标(x,y)以及框的宽w,高h
			pre_img = new_img[y:y+h,x:x+w]
			pre_img = cv2.resize(pre_img,(32,32))
			pre_img = (np.expand_dims(pre_img,0))
			# 输入的图片维度为(1,32,32,3)
			pred_arr = loaded_model.predict(pre_img)
			# 预测标签
			pre_label = np.argmax(pred_arr[0])
			# 预测得分
			score = np.max(pred_arr[0])
			# 预测类名
			class_name = class_names[pre_label]
			if score > max_score:
				max_rect = rect
				max_name = class_name
				max_score = score
			# region_score.append([rect,class_name,score])
		print([max_rect,max_name,max_score])
		x,y,w,h = max_rect
		# cv2.rectangle(new_img, (x, y), (x + w, y + h), (0, 255, 0), 1, cv2.LINE_AA )
		cv2.rectangle(new_img, (x, y), (x + w, y + h), (0, 255, 0), 2, cv2.LINE_AA)
		font = cv2.FONT_HERSHEY_SIMPLEX
		text = max_name+" "+str(max_score*100)[0:4]+"%"
		cv2.putText(new_img, text, (x, y-5), font, 0.5, (0,0,255), 2)
		# 显示输出
		# cv2.imshow("Output", new_img)
		cv2.imwrite(detected_path, new_img)
		break
		# 等待按键输入
		# k = cv2.waitKey( 0 ) & 0xFF
		# q键
		# if k == 113:
			# break
	# 关闭所有窗口
	cv2.destroyAllWindows()
vi flask_app.py

其内容如下:

from flask import (Flask, render_template, request, flash, redirect, url_for, make_response, jsonify)
from werkzeug.utils import secure_filename
import os
import time
from datetime import timedelta
from SelectSearch import detect

ALLOWED_EXTENSIONS = set(["png","jpg","JPG","PNG", "bmp"])

def is_allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS

app = Flask(__name__)

# 静态文件缓存过期时间
app.send_file_max_age_default = timedelta(seconds=1)

@app.route("/upload",methods = ['POST', 'GET'])
def upload():
	if request.method == "POST":
		f = request.files['file']
		if not ( f and is_allowed_file(f.filename)):
			return jsonify({
				"error":1001, "msg":"请检查上传的图片类型,仅限于png、PNG、jpg、JPG、bmp"
			})
		basepath = os.path.dirname(__file__)
		upload_path = os.path.join(basepath, "static/images",secure_filename(f.filename))
		f.save(upload_path)
		
		img_path = upload_path
		detected_path = os.path.join(basepath, "static/images", "output" + secure_filename(f.filename))
		weight_path = os.path.join(basepath, "static", "LeNet_classify_model.h5")
		print(upload_path,detected_path)
		detect(img_path,detected_path,weight_path)
		

		# return render_template("upload_ok.html", userinput = user_input, val1=time.time(), path = detected_path)
		path = "./images/" + "output" + secure_filename(f.filename)
		print(path)
		return render_template("upload_success.html", path = path, val1 = time.time()) #渲染模板,显示图片检测结果
		
	return render_template("upload.html", path = "./images/test.jpg")

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5000)

编写HTML文件

vi upload.html

其内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>目标检测</title>
</head>
<body align="center">
    <h1>目标检测</h1>
    <img src="{{ url_for('static', filename= path,_t=val1) }}" width="400" height="400" alt="图片"/>
    <form action="" enctype='multipart/form-data' method='POST'>
        <input type="file" name="file" style="margin-top:20px;"/>
        <input type="submit" value="检测图片" class="button-new" style="margin-top:15px;"/>
    </form>
</body>
</html>
vi upload_success.html

其内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>目标检测</title>
</head>
<body align="center">
    <h1>目标检测</h1>
    <img src="{{ url_for('static', filename= path,_t=val1) }}" width="400" height="400" alt="图片"/>
    <form action="" enctype='multipart/form-data' method='POST'>
        <input type="file" name="file" style="margin-top:20px;"/>
        <input type="submit" value="检测图片" class="button-new" style="margin-top:15px;"/>
    </form>
</body>
</html>

运行项目

python3 flask_app.py
# 或者
export FLASK_APP=flask_app.py
flask run --host=0.0.0.0

在这里插入图片描述
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FriendshipT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值