自动更新烧瓶模板中的返回数据

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自动更新烧瓶模板中的返回数据相关的知识,希望对你有一定的参考价值。

我正在研究Yolov3,OpenCV,python和Flask。在这里,我解释每个项目的用法细节。

Yolov3-检测和识别视频输入中的对象

Opencv-捕获视频输入中检测到的对象的图像。

Flask-作为Web服务器,因为它支持python语言。

我的目标开发能够捕获对象图像并直接或实时在flask Web中更新的应用程序

作为参考,当前我的系统能够使用OpenCv和python捕获图像并将其保存为一个名为images的文件夹。您可以参考下面的代码。

opencv和python代码捕获检测到的对象的图像

for i in range(len(boxes)):
    if i in indexes:
         x,y,w,h = boxes[i]
         label = str(LABELS[class_ids[i]])
         confidence= confidences[i]
         color = colors[class_ids[i]]
         crop_img = image[y:y + h, x:x + w]
         imagesPath = "images/file_%d.jpg"%self.d
         cv2.imwrite(imagesPath, crop_img)
         self.d+=1
         cv2.rectangle(image,(x,y),(x+w,y+h),color,2)
         cv2.putText(image,label+" "+str(round(confidence,2)),(x,y+30),font,1,(255,255,255),2)

[当图像成功保存在图像文件夹中时。我将所有图像都转换为base64并在flask中作为json返回。在这里,我将python代码附加在flask中。

将图像转换为base64并在html模板中呈现

@app.route("/images")
def get_images():
    directory = os.listdir('C:/Users/HP/Miniconda3/envs/count_vechicle/coding/images')
    os.chdir('C:/Users/HP/Miniconda3/envs/count_vechicle/coding/images')

    image_list= list()
    for file in directory:
        data = dict()
        base = os.path.basename(file)
        data["label"] = base
        open_file = open(file,'rb')
        image_read = open_file.read()
        image_64_encode = base64.encodebytes(image_read)
        data["data"] = image_64_encode.decode('ascii')
        image_list.append(data)    
    final_data = 'files':image_list
    return render_template('images.html', final_data=final_data)

images.html

<!DOCTYPE html>
<html>
<head>
    <!DOCTYPE html>
<html lang="en">
<head>
  <title>yolo</title>
</head>
 <body>
   <h1 class="logo">Results</h1>
   <ul>
    % for data in final_data.files %
    <li>data.label</li>
    <img alt="embedded" src="data:image/jpg;base64,data.data"/>
    % endfor %
   </ul>

 </body>
</html>

问题和问题

我在这里有两个主要问题。

1)当我运行我的应用程序时,我的应用程序很好地捕获了图像。但是,当打开image.html页面以显示图片时,它会自动停止。为什么会发生以及如何解决呢?

2)如果应用程序甚至可以打开image.html页面,也可以捕获图像。我应该怎么做才能直接或实时更新我的​​网站?

这里附上完整的代码。因为我已经工作了多个星期,但仍然找不到解决方案。希望有人可以帮忙。让我知道您是否需要更多信息

code

App.py

from flask import Flask, render_template, Response,jsonify
from camera import VideoCamera
import numpy as np
import os
import time
import detect as dt
from PIL import Image
import cv2
import base64
import json
from pprint import pprint

app = Flask(__name__)



def success_handle(output, status=200, mimetype='application/json'):
    return Response(output, status=status, mimetype=mimetype)

@app.route("/images")
def get_images():
    directory = os.listdir('C:/Users/HP/Miniconda3/envs/count_vechicle/coding/images')
    os.chdir('C:/Users/HP/Miniconda3/envs/count_vechicle/coding/images')

    flist = list()
    for file in directory:
        data = dict()
        base = os.path.basename(file)
        data["label"] = base
        open_file = open(file,'rb')
        image_read = open_file.read()
        image_64_encode = base64.encodebytes(image_read)
        data["data"] = image_64_encode.decode('ascii')
        flist.append(data)
    final_data = 'files':flist
    return render_template('images.html', final_data=final_data)


@app.route('/')
def index():
    return render_template('index.html')

def gen(camera):
    frame_id = 0
    while True:
        frame = camera.get_frame()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')

@app.route('/video_feed')
def video_feed():
    return Response(gen(VideoCamera()),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

camera.py

import cv2
import time
import os
import numpy as np

font = cv2.FONT_HERSHEY_PLAIN
starting_time= time.time()
frame_id = 0
count = 0
d = 0

labelsPath = os.path.sep.join(["yolo-coco", "coco.names"])
weightsPath = os.path.sep.join(["yolo-coco", "yolov3.weights"])
configPath = os.path.sep.join(["yolo-coco", "yolov3.cfg"])
#imagesPath = 'C:/Users/HP/Miniconda3/envs/count_vechicle/coding/images/file_%d.jpg"%d'
labelsPath = os.path.sep.join(["yolo-coco", "coco.names"])
VideoPath = os.path.sep.join(["videos", "highway.mp4"])
LABELS = open(labelsPath).read().strip().split("\n")


net = cv2.dnn.readNet(configPath, weightsPath)

layer_names = net.getLayerNames()
outputlayers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]


colors= np.random.uniform(0,255,size=(len(LABELS),3))

class VideoCamera(object):
    def __init__(self):
        # Using OpenCV to capture from device 0. If you have trouble capturing
        # from a webcam, comment the line below out and use a video file
        # instead.
        self.video = cv2.VideoCapture(VideoPath)
        self.frame_id = 0
        self.d = 0
        # If you decide to use video.mp4, you must have this file in the folder
        # as the main.py.
        # self.video = cv2.VideoCapture('video.mp4')

    def __del__(self):
        self.video.release()


    def get_frame(self):
        success, image = self.video.read()
        # We are using Motion JPEG, but OpenCV defaults to capture raw images,
        # so we must encode it into JPEG in order to correctly display the
        # video stream.
        self.frame_id+=1
        #print(frame_id)

        height,width,channels = image.shape
        #print (frame.shape)
        #detecting objects
        blob = cv2.dnn.blobFromImage(image,0.00392,(320,320),(0,0,0),True,crop=False) #reduce 416 to 320    


        net.setInput(blob)
        outs = net.forward(outputlayers)
        #print(outs)
        print(outs[1])

        #Showing info on screen/ get confidence score of algorithm in detecting an object in blob
        class_ids=[]
        confidences=[]
        boxes=[]

        for out in outs:
            #print(out)
            for detection in out:
                scores = detection[5:]
                class_id = np.argmax(scores)
                confidence = scores[class_id]
                print(confidence)
                if confidence > 0.8:
                    #object detected
                    center_x= int(detection[0]*width)
                    center_y= int(detection[1]*height)
                    w = int(detection[2]*width)
                    h = int(detection[3]*height)

                    #cv2.circle(img,(center_x,center_y),10,(0,255,0),2)
                    #rectangle co-ordinaters
                    x=int(center_x - w/2)
                    y=int(center_y - h/2)
                    #cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)

                    boxes.append([x,y,w,h]) #put all rectangle areas
                    confidences.append(float(confidence)) #how confidence was that object detected and show that percentage
                    class_ids.append(class_id) #name of the object tha was detected

        indexes = cv2.dnn.NMSBoxes(boxes,confidences,0.4,0.6)
        # result = open('C:/Users/HP/Miniconda3/envs/count_vechicle/coding/images/frame%04d.txt'%(count), 'w')
        for i in range(len(boxes)):
            if i in indexes:
                x,y,w,h = boxes[i]
                label = str(LABELS[class_ids[i]])
                # cv2.imwrite(label, crop_img)
                confidence= confidences[i]
                color = colors[class_ids[i]]
                crop_img = image[y:y + h, x:x + w]
                imagesPath = "images/file_%d.jpg"%self.d
                cv2.imwrite(imagesPath, crop_img)
                self.d+=1
                cv2.rectangle(image,(x,y),(x+w,y+h),color,2)
                cv2.putText(image,label+" "+str(round(confidence,2)),(x,y+30),font,1,(255,255,255),2)


        elapsed_time = time.time() - starting_time
        fps=frame_id/elapsed_time
        cv2.putText(image,"FPS:"+str(round(fps,2)),(10,50),font,2,(0,0,0),1)

        # cv2.imshow("Image",image)
        # key = cv2.waitKey(1) #wait 1ms the loop will start again and we will process the next frame

        # if key == 27: #esc key stops the process
        #     break;
        ret, jpeg = cv2.imencode('.jpg', image)
        return jpeg.tobytes()

index.html

<html>
  <head>
    <title>Object Detection</title>
  </head>
  <body>
    <h1>Video Streaming Demonstration</h1>
    <img src=" url_for('video_feed') ">
  </body>
</html>

images.html

<!DOCTYPE html>
<html>
<head>
    <!DOCTYPE html>
<html lang="en">
<head>
  <title>yolo</title>
</head>
 <body>
   <h1 class="logo">Results</h1>
   <ul>
    % for data in final_data.files %
    <li>data.label</li>
    <img alt="embedded" src="data:image/jpg;base64,data.data"/>
    % endfor %
   </ul>

 </body>
</html>
答案

我认为您可以使用套接字或websocket解决此问题。看起来您在使用Flask。也许您可以尝试在flask-soscketio上进行测试

以上是关于自动更新烧瓶模板中的返回数据的主要内容,如果未能解决你的问题,请参考以下文章

自动更新 WPF 数据网格中的计算属性

如何将数据从烧瓶发送到 html 模板

某些更新命令无法自动生成数据库返回以下错误意外错误

cloudformation 堆栈更新和启动模板版本/自动缩放组的问题

电脑系统总是自动更新怎么办

AC自动机HDU中模板题汇总(待更新)