计算机视觉---flask框架封装目标检测,应用线程提高程序运行效率

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
1.前言

上一篇文章flask部署 目标检测算法中讲到可以将检测算法封装到flask框架中进行web端展示但在实际应用中发现一些问题并进行了解决在本文中进行补充。

2.利用线程提高flask程序运行效率

flask web端访问时每次都会从头加载程序导致每次访问页面刷新率很低或者需要等好一段时间才能刷新成功可以利用线程达到仅在程序启动后第一次从头加载程序而后刷新获取到实时视频流即可不再从头加载程序。

实例(部分代码)

import threading
from flask import Flask, render_template, Response
app = Flask(__name__)

lock = threading.Lock()  #线程锁
result_img = None   #初始化检测结果并定义为全局变量  

#zed获取视频并进行目标检测获取检测结果
def camera(cfgfile, weightfile):
    import cv2
    zed = sl.Camera()
    init_params = sl.InitParameters()
    init_params.camera_resolution = sl.RESOLUTION.HD720  #分辨率分辨率越高成像后的图像像素数就越高图像就越清晰。
    init_params.camera_fps = 30  # Set fps at 30帧率越高视频越流畅最低是30 

。。。省略部分代码。。目标检测过程代码。。。。
    
    ##结尾获取检测结果图片设为全局变量便于后续函数调用
    global result_img 
    result_img = plot_boxes_cv2(img, boxes[0], savename=None, class_names=class_names)


##相机推流 获取检测结果视频流并返回
def generate():
    global result_img, lock  #result_img 设置为全局变量
    while True:
        with lock:
            if result_img is None:
                continue
            (flag, encodedImage) = cv2.imencode(".jpg", result_img)   #将 OpenCV 图像转换为 JPEG 图像
            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')


#相机拉流调用generate函数实现向网页返回每一帧图片的编码将视频流传输到web浏览器
@app.route("/tt_demo")
def tt_demo():
    return Response(generate(),mimetype="multipart/x-mixed-replace; boundary=frame")


# 前端页面
@app.route('/bdlf')
def index():
    return render_template("bdlf.html")

#主函数线程调用
if __name__ =="__main__":
    host="0.0.0.0"
    port=7000
    debug=False
    use_reloader=False
    t = threading.Thread(target=camera, args=(args.cfgfile, args.weightfile), daemon = True)
    # t.daemon()
    t.start() #线程启动
   # app.run(host,port,debug,use_reloader)
   t2 = threading.Thread(target=app.run, args=(host,port,debug,use_reloader))
   t2.start()

前端引用

<img src="{{ url_for('tt_demo') }}">   ##与后端入口函数名保持一致
3.知识小记
1线程传参
  • 使用args 传递参数 threading.Thread(target=sing, args=(10, 100, 100))
  • 使用kwargs传递参数 threading.Thread(target=sing, kwargs={“a”: 10, “b”:100, “c”: 100})
  • 同时使用 args 和 kwargs 传递参数 threading.Thread(target=sing, args=(10, ), kwargs={“b”: 100,“c”: 100})
(2) 守护线程
  • 设置守护主线程有两种方式
    threading.Thread(target=show_info, daemon=True)
    线程对象.setDaemon(True)
  • 一定在线程执行start()之前
  • 守护线程就是会随着主线程的结束而结束。即主进程在其代码结束后守护进程在此时就被回收主进程会一直等非守护子进程都运行完毕后回收子进程的资源
  • 主线程在有非守护线程存在的情况下设置守护线程作用不大
(3)查看线程数
  • threading.enumerate()返回当前存活的threading.Thread线程对象列表
4线程锁
with temp_lock:
    # do something...

相当于以下代码

temp_lock.acquire() #上锁
try:
   # do something...
finally:
   temp_lock.release() #释放锁

也就是在运行的时候对语句块的内容上锁了运行完后再释放了这个锁。

在这里插入图片描述 图片怎么居中啊

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6