YOLOv5部署到web端詳細(xì)過(guò)程(flask+js簡(jiǎn)單易懂)
前言
最近,老板讓寫(xiě)一個(gè)程序把yolov5檢測(cè)模型部署到web端,在網(wǎng)頁(yè)直接進(jìn)行目標(biāo)檢測(cè)。經(jīng)過(guò)1個(gè)星期的努力,終于實(shí)現(xiàn)基本功能??(累暈了)。網(wǎng)上查閱了很多資料,發(fā)現(xiàn)很多的技術(shù)比較復(fù)雜,當(dāng)然他們的頁(yè)面都比較漂亮,然后我打算自己寫(xiě)一篇簡(jiǎn)單記錄一下哈哈。進(jìn)入正題,該項(xiàng)目完全由Python的輕量級(jí)web框架flask完成,其實(shí)有一點(diǎn)js代碼,簡(jiǎn)單易懂??
最終實(shí)現(xiàn)效果圖
先看項(xiàng)目的效果圖吧哈哈,比較辣雞,但是功能實(shí)現(xiàn)了?。ê罄m(xù)會(huì)優(yōu)化頁(yè)面)

檢測(cè)結(jié)果顯示:

哈哈 可以看到檢測(cè)結(jié)果還是可以的??
后端實(shí)現(xiàn)
首先,寫(xiě)了三個(gè)路由函數(shù),分別是主界面、檢測(cè)函數(shù)、檢測(cè)結(jié)果顯示。如下所示
主界面
# 定義路由
@app.route('/', methods=['GET', 'POST'])
def upload():
if request.method == 'POST':
# 從表單中獲取上傳的文件
f = request.files['file']
global filename
filename = f.filename
global file_path
# 將文件保存到服務(wù)器本地
file_path = os.path.join(os.getcwd(), filename)
print(file_path)
f.save(file_path)
# 返回文件路徑
# return file_path
return render_template('index1.html')
檢測(cè)函數(shù)
#檢測(cè)函數(shù)
@app.route('/det', methods=['GET','POST'])
def my_flask_function():
#print('測(cè)試一下!')
opt = parse_opt()
main(opt)
# return jsonify({'message': 'Hello from Flask!'})
return render_template('123.html')檢測(cè)結(jié)果顯示
@app.route('/sh', methods=['GET', 'POST'])
def hello_world():
img_path = 'runs\\detect\\exp\\' + str(filename)
img_stream = return_img_stream(img_path)
return render_template('showimage.html', img_stream=img_stream)
#獲取圖片并展現(xiàn)到前端頁(yè)面
def return_img_stream(img_local_path):
"""
工具函數(shù):
獲取本地圖片流
:param img_local_path:文件單張圖片的本地絕對(duì)路徑
:return: 圖片流
"""
import base64
img_stream = ''
with open(img_local_path, 'rb') as img_f:
img_stream = img_f.read()
img_stream = base64.b64encode(img_stream).decode()
return img_stream
最后,我把detect文件中的函數(shù),parse_out函數(shù)直接放到app.py文件中了,因?yàn)檫@樣傳遞圖片路徑比較方便。其中的main函數(shù)直接是調(diào)用的detect文件,如下所示:
# 檢測(cè)圖片的
def parse_opt():
parser = argparse.ArgumentParser()
parser.add_argument('--weights', nargs='+', type=str, default= 'yolov5s.pt', help='model path or triton URL')
#parser.add_argument('--source', type=str, default=0, help='file/dir/URL/glob/screen/0(webcam)')
parser.add_argument('--source', type=str, default= file_path, help='file/dir/URL/glob/screen/0(webcam)')
parser.add_argument('--data', type=str, default= 'models/yolov5s.yaml', help='(optional) dataset.yaml path')
parser.add_argument('--imgsz', '--img', '--img-size', nargs='+', type=int, default=[640], help='inference size h,w')
parser.add_argument('--conf-thres', type=float, default=0.25, help='confidence threshold')
parser.add_argument('--iou-thres', type=float, default=0.45, help='NMS IoU threshold')
parser.add_argument('--max-det', type=int, default=1000, help='maximum detections per image')
parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
parser.add_argument('--project', default= 'runs/detect', help='save results to project/name')
parser.add_argument('--name', default='exp', help='save results to project/name')
parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
parser.add_argument('--vid-stride', type=int, default=1, help='video frame-rate stride')
opt = parser.parse_args()
opt.imgsz *= 2 if len(opt.imgsz) == 1 else 1 # expand
#print_args(vars(opt))
args = parser.parse_args(args=[])
print(args)
return opt到這里,后端實(shí)現(xiàn)就基本寫(xiě)完了。接下來(lái),看看前端頁(yè)面 很簡(jiǎn)單,我都不好意思寫(xiě)??
前端實(shí)現(xiàn)
主要就兩個(gè)頁(yè)面,分別是主頁(yè)面index1.html和showimage.html。
主界面(index1.html)
index1.html就是主界面,顯示的一些操作按鈕。代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<title>簡(jiǎn)單實(shí)現(xiàn)</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<h2>選擇圖片上傳檢測(cè)</h2>
<br />
<br />
<img id="imageDisplay" width="500" height="500" />
<br />
<form method="POST" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="上傳">
</form>
<br />
<div id="imagePath"></div>
<script>
function displayImage() {
var fileInput = document.getElementById("imageFile");
var imagePath = document.getElementById("imagePath");
var imageDisplay = document.getElementById("imageDisplay");
var file = fileInput.files[0];
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function (e) {
imagePath.innerHTML = "Image Path: " + fileInput.value;
imageDisplay.src = e.target.result;
};
}
function Detect() {
$.ajax({
type: 'POST',
url: '/det',
success: function(response) {
console.log(response);
},
error: function(error) {
console.log(error);
}
});
}
function Show() {
var img = document.getElementById('img');
img.src = '/sh';
}
</script>
<button id="my-button" onclick="Detect()">檢測(cè)</button>
<a >
<button id="my-button1" onclick="Show()">顯示圖片</button>
</a>
</body>
</html>
顯示圖片界面(showimage.html)
然后就是 showiamge.html,該頁(yè)面是在點(diǎn)擊顯示圖片按鈕之后,進(jìn)行跳轉(zhuǎn),然后顯示檢測(cè)結(jié)果的圖片。代碼如下所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>檢測(cè)結(jié)果顯示</title>
</head>
<body>
<img style="width:500px " src="data:;base64,{{ img_stream }}">
</body>
</html>
總結(jié)
寫(xiě)的比較潦草,代碼的功能不難理解,相對(duì)比較基礎(chǔ)。有什么問(wèn)題可以在評(píng)論直接問(wèn)。然后就是代碼基本上都放上來(lái)了,可以直接復(fù)制然后用,如果想直接要項(xiàng)目代碼,可以私信我(不收任何費(fèi)用)。
后續(xù)會(huì)優(yōu)化前端界面(等有時(shí)間了),因?yàn)檎娴奶罅恕?/strong>
到此這篇關(guān)于YOLOv5部署到web端的文章就介紹到這了,更多相關(guān)YOLOv5部署web端內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python出現(xiàn)RuntimeError錯(cuò)誤問(wèn)題及解決
這篇文章主要介紹了python出現(xiàn)RuntimeError錯(cuò)誤問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05
Python+Appium實(shí)現(xiàn)自動(dòng)搶微信紅包
不知從何時(shí)開(kāi)始微信紅包橫空出世,對(duì)于網(wǎng)速和手速慢的人只能在一旁觀望,做為python的學(xué)習(xí)者就是要運(yùn)用編程解決生活和工作上的事情。于是我用python解決我們的手速問(wèn)題python實(shí)現(xiàn)自動(dòng)搶微信紅包,至于網(wǎng)速慢得那就只能自己花錢提升了。2021-05-05
Python讀取大量Excel文件并跨文件批量計(jì)算平均值的方法
這篇文章主要介紹了Python讀取大量Excel文件并跨文件批量計(jì)算平均值,介紹基于Python語(yǔ)言,實(shí)現(xiàn)對(duì)多個(gè)不同Excel文件進(jìn)行數(shù)據(jù)讀取與平均值計(jì)算的方法,需要的朋友可以參考下2023-02-02
python實(shí)現(xiàn)對(duì)csv文件的列的內(nèi)容讀取
今天小編就為大家分享一篇python實(shí)現(xiàn)對(duì)csv文件的列的內(nèi)容讀取,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-07-07
python pygame模塊編寫(xiě)飛機(jī)大戰(zhàn)
這篇文章主要為大家詳細(xì)介紹了python pygame模塊編寫(xiě)飛機(jī)大戰(zhàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11
詳解Python最長(zhǎng)公共子串和最長(zhǎng)公共子序列的實(shí)現(xiàn)
這篇文章主要介紹了詳解Python最長(zhǎng)公共子串和最長(zhǎng)公共子序列的實(shí)現(xiàn)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07

