問候,我正在做一個無人機專案,我想在我的筆記本電腦上從我的無人機處理中獲取流,并根據處理給出一個命令,我正在使用相同的燒瓶框架。
目前,作為第一步,我想從無人機獲取流并將其放入燒瓶服務器并在燒瓶網站上查看,而不是現在做處理部分。
我將視頻壓縮成 jpg 并使用 base 64 對其進行編碼后將其放到服務器上,然后最后使用json.dumps()它requests.put()。
在燒瓶服務器程式的服務器端,我得到它的 using request.json, use json.loads(),但我不清楚下一步該做什么。
我對燒瓶,Web 開發經驗不足,并且在制作程式時經驗和知識有限,但它在燒瓶程式上回傳錯誤 405 。
這是程式
燒瓶服務器
import base64
import json
from flask import Flask, make_response, render_template, request
app = Flask(__name__)
def getFrames(img):
pass
@app.route('/video', methods=['POST', 'GET'])
def video():
if request.method == 'PUT':
load = json.loads(request.json)
imdata = base64.b64decode(load['image'])
respose = make_response(imdata.tobytes())
return respose
@app.route('/')
def index():
return render_template('index.html')
@app.route('/cmd')
def cmd():
pass
if __name__ == "__main__":
app.run(debug=True)
索引.html
<!DOCTYPE html>
<html>
<head>
<title>Video Stream</title>
</head>
<body>
<h1>
Live Stream
</h1>
<div>
<img src="{{ url_for('video') }}" width="50%">
</div>
</body>
</html>
無人機計劃
import base64
import json
import requests
import cv2
cap = cv2.VideoCapture(1)
ip = '' #url returned by the flask program
while True:
success, img = cap.read()
cv2.imshow("OUTPUT", img)
_, imdata = cv2.imencode('.JPG', img)
jStr = json.dumps({"image": base64.b64encode(imdata).decode('ascii')})
requests.put(url=(ip '/video'), data=jStr)
if cv2.waitKey(1) == 27:
break
任何幫助都非常感謝!!!
uj5u.com熱心網友回復:
您不必轉換為base64和使用 JSON。將 JPG 直接作為原始位元組發送會更簡單、更快捷
為了讓它更簡單,我會用/upload無人機將影像發送到服務器,/video并將影像發送給用戶。
import requests
import cv2
cap = cv2.VideoCapture(0)
while True:
success, img = cap.read()
if success:
cv2.imshow("OUTPUT", img)
_, imdata = cv2.imencode('.JPG', img)
print('.', end='', flush=True)
requests.put('http://127.0.0.1:5000/upload', data=imdata.tobytes())
# 40ms = 25 frames per second (1000ms/40ms),
# 1000ms = 1 frame per second (1000ms/1000ms)
# but this will work only when `imshow()` is used.
# Without `imshow()` it will need `time.sleep(0.04)` or `time.sleep(1)`
if cv2.waitKey(40) == 27: # 40ms = 25 frames per second (1000ms/40ms)
break
cv2.destroyAllWindows()
cap.release()
現在燒瓶。這部分不完整。
它從無人機獲取影像并保存在全域變數中。當用戶打開頁面時,它會從/video
from flask import Flask, make_response, render_template, request
app = Flask(__name__)
frame = None # global variable to keep single JPG
@app.route('/upload', methods=['PUT'])
def upload():
global frame
# keep jpg data in global variable
frame = request.data
return "OK"
@app.route('/video')
def video():
if frame:
return make_response(frame)
else:
return ""
@app.route('/')
def index():
return 'image:<br><img src="/video">'
if __name__ == "__main__":
app.run(debug=True)
此時它只能顯示一個靜態影像。它需要將其發送為motion-jpeg
編輯:
發送motion-jpeg所以你看視頻的版本。
它可以與Chrome,Microsoft Edge和Brave(都使用 chrome 引擎)一起正常作業。
問題使Firefox. 它一直掛起并嘗試加載影像。我不知道真正的問題是什么,但如果我添加time.sleep()它就可以解決問題。
from flask import Flask, Response, render_template_string, request
import time
app = Flask(__name__)
frame = None # global variable to keep single JPG,
# at start you could assign bytes from empty JPG
@app.route('/upload', methods=['PUT'])
def upload():
global frame
# keep jpg data in global variable
frame = request.data
return "OK"
def gen():
while True:
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n'
b'\r\n' frame b'\r\n')
time.sleep(0.04) # my Firefox needs some time to display image / Chrome displays image without it
# 0.04s = 40ms = 25 frames per second
@app.route('/video')
def video():
if frame:
# if you use `boundary=other_name` then you have to yield `b--other_name\r\n`
return Response(gen(), mimetype='multipart/x-mixed-replace; boundary=frame')
else:
return ""
@app.route('/')
def index():
return 'image:<br><img src="/video">'
#return render_template_string('image:<br><img src="{{ url_for("video") }}">')
if __name__ == "__main__":
app.run(debug=True)#, use_reloader=False)
服務器可能會在行程的單獨執行緒中運行用戶,有時它可能不會frame在用戶之間共享。如果我使用use_reloader=False,那么我可以停止發送到/upload,這會停止瀏覽器中的視頻,稍后我可以再次開始發送到/upload,瀏覽器再次顯示流(無需重新加載頁面)。沒有use_reloader=False瀏覽器不會重新啟動視頻,它需要重新加載頁面。也許它需要用來flask.g保持框架。或者/upload必須將幀保存在檔案或資料庫中,并且/video必須從檔案或資料庫中讀取幀。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/488518.html
