使用Flask和OpenCV处理多个摄像机

使用Flask和OpenCV处理多个摄像机

本文介绍了使用Flask和OpenCV处理多个摄像机的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在通过烧瓶测试实时视频流(便携式计算机和USB网络摄像头)时,我无法在主页上以及访问装饰器时显示视频流.我的主要目的是通过使用下面提到的烧瓶访问多台摄像机,这是我正在使用的代码

While Testing the live video streaming (laptop and USB webcam) through flask, I am not able to display the video streaming on the main page as well as while accessing the decorator. My main aim is to access multiple cameras through using flask mentioned below is the code I am working on

app.py

from flask import Flask, render_template, Response
import cv2

app = Flask(__name__)

def find_camera(id):
    cameras = ['0','1']
    print(cameras[id])
    return cameras[int(id)]
#  for cctv camera use rtsp://username:password@ip_address:554/user=username_password='password'_channel=channel_number_stream=0.sdp' instead of camera
#  for webcam use zero(0)


def gen_frames(camera_id):

    cam = find_camera(camera_id)
    cap= cv2.VideoCapture(cam)

    while True:
        # for cap in caps:
        # # Capture frame-by-frame
        success, frame = cap.read()  # read the camera frame
        if not success:
            break
        else:
            ret, buffer = cv2.imencode('.jpg', frame)
            frame = buffer.tobytes()
            yield (b'--frame\r\n'
                b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')  # concat frame one by one and show result


@app.route('/video_feed/<string:id>/', methods=["GET"])
def video_feed(id):

    """Video streaming route. Put this in the src attribute of an img tag."""
    return Response(gen_frames(id),
                    mimetype='multipart/x-mixed-replace; boundary=frame')


@app.route('/', methods=["GET"])
def index():
    return render_template('index.html')


if __name__ == '__main__':
    app.run()

HTML页面

<!doctype html>
<html lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
          integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">

    <title>Multiple Live Streaming</title>
</head>
<body>
<div class="container">
    <div class="row">

        <div class="col-lg-7">
            <h3 class="mt-5">Multiple Live Streaming</h3>
            <img src="{{ url_for('video_feed', id='0') }}" width="100%">
        </div>


    </div>
</div>
</body>
</html>

作为初学者,我需要知道我们是否需要使用多线程一次处理多个摄像机?

Being a beginner to this I need to know whether we need to use multithreading for handling multiple cameras at a time?

对此的任何建议都会有很大帮助.

Any suggestions on this will be a great help.

推荐答案

如建议的那样,使用 ip地址并遍历它们会更好.这样可以使代码更加清晰.您的烧瓶代码将依次如下所示:

As suggested, it would be much better to use ip addresses and loop through them. It would make for much better clarity ion your code. Your flask code would in-turn look like this:

from flask import Flask, render_template, Response
import cv2

app = Flask(__name__)

# list of camera accesses
cameras = [
 "rtsp://username:password@ip_address:554/user=username_password='password'_channel=channel_number_stream=0.sdp",
 "rtsp://username:password@ip_address:554/user=username_password='password'_channel=channel_number_stream=0.sdp",
...
  ]


def find_camera(list_id):
    return cameras[int(list_id)]


def gen_frames(camera_id):
    cam = find_camera(camera_id)  # return the camera access link with credentials. Assume 0?
    # cam = cameras[int(id)]
    cap = cv2.VideoCapture(cam)  # capture the video from the live feed

    while True:

        # # Capture frame-by-frame. Return boolean(True=frame read correctly. )
        success, frame = cap.read()  # read the camera frame
        if not success:
            break
        else:
            ret, buffer = cv2.imencode('.jpg', frame)
            frame = buffer.tobytes()
            yield (b'--frame\r\n'
                   b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')  # concat frame one by one and show result


@app.route('/video_feed/<string:list_id>/', methods=["GET"])
def video_feed(list_id):
    return Response(gen_frames(list_id),
                    mimetype='multipart/x-mixed-replace; boundary=frame')


@app.route('/', methods=["GET"])
def index():
    return render_template('index.html', camera_list=len(cameras), camera=cameras)


if __name__ == '__main__':
    app.run()

注意如何获取摄像机地址列表的长度以及 index 函数中的整个列表的长度.我之所以使用它,是因为我想假设如果提供或删除了任何摄像机凭据,代码只会继续将提要添加/删除到模板文件中.

Notice how I get the length of my list of camera addresses and the whole list in the index function. I'm using this because I want to assume the code will just keep adding/removing feeds to the template file if any camera credential is provided or removed.

您的模板文件将如下所示:

Your template file would then look something like this:

 {% for camera_number in range(0, camera_list) %}
            <div class="col-lg-5">
                <img src="{{ url_for('video_feed', list_id=camera_number) }}" width="100%"><br/>
            </div>
        {% endfor %}

在这里,您将从传递到URL的位置获得摄像机列表及其列表的长度.这应该工作.如果您需要进一步说明,请伸出手.

Here, you would get the length of the list of cameras its list as well from where you can pass to the URL. This should work. Do reach out if you need further clarification.

这篇关于使用Flask和OpenCV处理多个摄像机的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-30 17:31