#主業務邏輯中的視圖和路由的定義 import os import datetime from flask import render_template, request, session, Response #導入藍圖程序,用於構建路由 from werkzeug.utils import redirect from . import main from manage import mqtt #導入db,用於操作數據庫 from manage import db #導入實體類,用於操作數據庫 from ..models import * import json from datetime import datetime as dt from sqlalchemy import text import socket import pickle import cv2 import numpy as np import math import threading import time #主頁的訪問路徑 @main.route('/') def main_index(): #獲取登入信息 if 'id' in session and 'uname' in session: return render_template('allindex.html') else: return render_template('sign_in.html') #登入頁面的訪問路徑 @main.route('/login', methods=['GET','POST']) def login_views(): if request.method == 'GET': if 'id' in session and 'uname' in session: return redirect('/') else: return render_template('sign_in.html') else: #接收前端傳過來的資料 username = request.form['username'] password = request.form['password'] #使用接收的用戶和密碼到資料庫中查詢 user = User.query.filter_by(account=username, password=password).first() #如果用戶存在,將信息保存置session並重定向回首頁,否則重定向回登入頁 if user: resp = redirect('/') #判斷是否有記住密碼 if 'rem' in request.form: sn = str(user.sn) max_age = 60*60*24*365 resp.set_cookie("username", username, max_age=max_age) resp.set_cookie("sn", sn, max_age=max_age) session['uname'] = user.account session['id'] = user.sn return resp else: errMsg = "Wrong login or password" return render_template('sign_in.html',errMsg=errMsg) #註冊頁面的訪問路徑 @main.route('/register',methods=['POST',"GET"]) def register_views(): if request.method == 'GET': return render_template('registration.html') else: #獲取文本框的值並賦值給user實體對象 user = User() user.account = request.form['username'] user.password = request.form['password'] #將數據保存進資料庫 - 註冊 db.session.add(user) #手動提交,目的是為了獲取提交後的user的id db.session.commit() #當user成功插入進資料庫之後,程序會自動將所有信息取出來在賦值給user #完成登入的操作 user = User.query.filter_by(account=user.account).first() session['id'] = user.sn session['uname'] = user.account return redirect('/') #毛豆田的主頁面 @main.route('/aindex', methods=['POST', 'GET']) def aindex_views(): return render_template('aindex.html') #毛豆車的主頁面 @main.route('/cindex', methods=['POST', 'GET']) def cindex_views(): return render_template('cindex.html') #毛豆田拍攝設定的主頁面 @main.route('/ashoot_setting/', methods=['POST', 'GET']) def ashoot_setting_views(tid): if request.method == 'GET': dict = request.args.to_dict() if dict: try: nr = "KDAIS" + dict['nr'] mode = int(dict['mode']) jvtotime = JvtOTime.query.filter_by(nr=nr, MODE=mode).order_by(text('datetime desc')).first() tilt_angle = jvtotime.tilt_angle pan_angle = jvtotime.pan_angle zoom = str(jvtotime.zoom_now) time1 = jvtotime.time1 time2 = jvtotime.time2 time3 = jvtotime.time3 time4 = jvtotime.time4 time5 = jvtotime.time5 time6 = jvtotime.time6 time7 = jvtotime.time7 time8 = jvtotime.time8 dict = {"tilt_angle":tilt_angle, "pan_angle":pan_angle, "zoom":zoom, "time1":time1, "time2":time2, "time3":time3, "time4":time4, "time5":time5, "time6":time6, "time7":time7, "time8":time8} return json.dumps(dict) except Exception: dict = {"tilt_angle":"0", "pan_angle":"0", "zoom":"0", "time1":"00000000", "time2":"00000000", "time3":"00000000", "time4":"00000000", "time5":"00000000", "time6":"00000000", "time7":"00000000", "time8":"00000000"} return json.dumps(dict) return render_template('aim.html', params=locals()) else: dict = request.form.to_dict() jvtotime = JvtOTime() if dict['nr'] == '1': jvtotime.MAC = 'b8:27:eb:a1:b0:70' elif dict['nr'] == '2': jvtotime.MAC = 'b8:27:eb:e7:51:44' elif dict['nr'] == '3': jvtotime.MAC = 'b8:27:eb:ce:a5:35' elif dict['nr'] == '4': jvtotime.MAC = 'b8:27:eb:06:9a:f1' elif dict['nr'] == '5': jvtotime.MAC = 'b8:27:eb:0c:f0:21' elif dict['nr'] == '6': jvtotime.MAC = 'b8:27:eb:df:4b:0f' elif dict['nr'] == '7': jvtotime.MAC = 'b8:27:eb:af:df:b6' elif dict['nr'] == '8': jvtotime.MAC = 'b8:27:eb:d2:d0:8f' elif dict['nr'] == '9': jvtotime.MAC = 'b8:27:eb:57:3c:da' elif dict['nr'] == '10': jvtotime.MAC = 'b8:27:eb:bd:29:b1' elif dict['nr'] == '11': jvtotime.MAC = 'b8:27:eb:7c:f6:06' elif dict['nr'] == '12': jvtotime.MAC = 'b8:27:eb:74:bd:ac' elif dict['nr'] == '13': jvtotime.MAC = 'b8:27:eb:e7:21:e5' elif dict['nr'] == '14': jvtotime.MAC = 'b8:27:eb:6f:5a:6b' elif dict['nr'] == '15': jvtotime.MAC = 'b8:27:eb:e3:f1:f4' elif dict['nr'] == '16': jvtotime.MAC = 'b8:27:eb:60:1c:2e' elif dict['nr'] == '17': jvtotime.MAC = 'b8:27:eb:9d:68:05' elif dict['nr'] == '18': jvtotime.MAC = 'b8:27:eb:4d:e4:34' jvtotime.nr = 'KDAIS' + dict['nr'] jvtotime.MODE = int(dict['mode']) jvtotime.tilt_angle = dict['tilt_angle'] jvtotime.pan_angle = dict['pan_angle'] jvtotime.zoom_before = 0 jvtotime.zoom_now = int(dict['zoom']) jvtotime.time1 = dict['time1'] jvtotime.time2 = dict['time2'] jvtotime.time3 = dict['time3'] jvtotime.time4 = dict['time4'] jvtotime.time5 = dict['time5'] jvtotime.time6 = dict['time6'] jvtotime.time7 = dict['time7'] jvtotime.time8 = dict['time8'] jvtotime.datetime = dt.now() db.session.add(jvtotime) db.session.commit() return {"status":"OK"} #毛豆田歷史資料的主頁面 @main.route('/aimg_history/', methods=['POST', 'GET']) def aimg_history_views(tid): if request.method == 'GET': return render_template('ahistory_ndvi1.html', params=locals()) else: pass #毛豆車拍攝設定的主頁面 @main.route('/cshoot_setting/', methods=['POST', 'GET']) def cshoot_setting_views(tid): if request.method == 'GET': return render_template('cim.html', params=locals()) else: pass #毛豆車歷史資料的主頁面 @main.route('/cimg_history/', methods=['POST', 'GET']) def cimg_history_views(tid): if request.method == 'GET': return render_template('chistory_ndvi1.html', params=locals()) else: pass #退出的訪問路徑 @main.route('/logout') def logout_views(): if 'id' in session and 'uname' in session: del session['id'] del session['uname'] return redirect('/') lock = threading.Lock() @main.route("/udp_client") def udp_views(): time.sleep(1) max_length = 65000 # max_length = 95000 #lab1的IP host = "192.168.50.65" # lab2的IP # host = "192.168.51.161" port = 8000 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #地下室小兵 # cap = cv2.VideoCapture('rtsp://admin:abcd1234@192.168.51.48/av2_0') #主機攝像頭 # cap = cv2.VideoCapture(0) #外面小兵 cap = cv2.VideoCapture('rtsp://admin:admin@192.168.50.182/av2_0') ret, frame = cap.read() while ret: # compress frame frame = cv2.resize(frame, (500, 400), interpolation=cv2.INTER_AREA) retval, buffer = cv2.imencode(".jpg", frame) if retval: # convert to byte array buffer = buffer.tobytes() # get size of the frame buffer_size = len(buffer) num_of_packs = 1 if buffer_size > max_length: num_of_packs = math.ceil(buffer_size / max_length) frame_info = {"packs": num_of_packs} # send the number of packs to be expected print("Number of packs:", num_of_packs) sock.sendto(pickle.dumps(frame_info), (host, port)) left = 0 right = max_length for i in range(num_of_packs): print("left:", left) print("right:", right) # truncate data to send data = buffer[left:right] left = right right += max_length # send the frames accordingly sock.sendto(data, (host, port)) ret, frame = cap.read() print("done") lock = threading.Lock() #影像串流的路徑 @main.route ( "/video_feed", methods=['POST', 'GET']) def video_feed_views( ) : # 影像生成器函數,將影像以jpg格式傳給前端 def generate(): # lab1的IP host = "192.168.50.65" # lab2的IP # host = "192.168.51.161" port = 8000 max_length = 65540 # max_length = 95540 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind((host, port)) frame_info = None buffer = None frame = None port8000_status = 1 print("-> waiting for connection") while True: data, address = sock.recvfrom(max_length) if len(data) < 100: frame_info = pickle.loads(data) if frame_info: nums_of_packs = frame_info["packs"] for i in range(nums_of_packs): data, address = sock.recvfrom(max_length) if i == 0: buffer = data else: buffer += data frame = np.frombuffer(buffer, dtype=np.uint8) frame = frame.reshape(frame.shape[0], 1) frame = cv2.imdecode(frame, cv2.IMREAD_COLOR) frame = cv2.resize(frame, (1280, 720), interpolation=cv2.INTER_AREA) global lock with lock: if frame is None: continue # encode the frame in JPEG format (flag, encodedImage) = cv2.imencode(".jpg", frame) # ensure the frame was successfully encoded if not flag: continue # yield the output frame in the byte format yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + bytearray(encodedImage) + b'\r\n') if request.method == 'GET': # return the response generated along with the specific media # type (mime type) return Response(generate ( ) ,mimetype = "multipart/x-mixed-replace; boundary=frame") else: pass