如何使用 holoviews 和 tornado 制作流图 python

How to make a streaming plot with holoviews and tornado python

您好,我刚刚开始使用 holoviews,我正在尝试使用 holoviews、opencv 准备一个小型流媒体视频应用程序。我对龙卷风和异步编程的经验非常有限。

from holoviews.streams import Pipe, Buffer
from tornado.ioloop import IOLoop
from tornado import gen
import cv2
@gen.coroutine
def f():
    pipe = Pipe(data=[])
    #print(pipe)
    vd = cv2.VideoCapture("TestVideo.mp4")
    width = int(vd.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(vd.get(cv2.CAP_PROP_FRAME_HEIGHT))
    frames = int(vd.get(cv2.CAP_PROP_FRAME_COUNT))
    print("Hello")
    for i in range(frames):
        ret, frame = vd.read()
        #print(i)
        try:
            rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            gen.sleep(10000000000)
            pipe.send(rgb[:])
            #print(str(i)+'x')
        except:
            #print(str(i)+'Error')
            print("Error at Frame:"+str(i))
            pass
    vd.release()
    cv2.destroyAllWindows()

IOLoop.current().add_callback(f)
hv.DynamicMap(hv.RGB, streams=[pipe])

我没有收到 running/streaming 更新。我只得到最后一帧的单张图像。有人可以帮我找出我的错误

除了关于 gen.sleep 以秒为单位的时间的评论之外,您需要将回调编写为生成器。应该这样做:

from holoviews.streams import Pipe, Buffer
from tornado.ioloop import IOLoop
from tornado import gen
import cv2

@gen.coroutine
def f():
    vd = cv2.VideoCapture("TestVideo.mp4")
    width = int(vd.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(vd.get(cv2.CAP_PROP_FRAME_HEIGHT))
    frames = int(vd.get(cv2.CAP_PROP_FRAME_COUNT))
    while frames > 0:
        ret, frame = vd.read()
        rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        pipe.send(rgb)
        frames -= 1
        yield gen.sleep(1)
    vd.release()
    cv2.destroyAllWindows()

pipe = Pipe(data=[])
IOLoop.current().add_callback(f)
hv.DynamicMap(hv.RGB, streams=[pipe])

谢谢@philippjfr

最后我使用 streamz python 库得到了一些可行的东西。然而,这种方法有效。这是我基于上述方法的工作解决方案。

```

import numpy as np
import pandas as pd
import holoviews as hv
hv.extension('bokeh', 'matplotlib')
from holoviews.streams import Pipe, Buffer
from tornado.ioloop import IOLoop
from tornado import gen
import cv2

@gen.coroutine
def f():
    width = int(vd.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(vd.get(cv2.CAP_PROP_FRAME_HEIGHT))
    frames = int(vd.get(cv2.CAP_PROP_FRAME_COUNT))
    while frames > 0:
        ret, frame = vd.read()
        rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        frames -= 1
        yield pipe.send(rgb)
    vd.release()
    cv2.destroyAllWindows()

vd = cv2.VideoCapture("TestVideo.mp4")    
ret, frame0 = vd.read()
rgb = cv2.cvtColor(frame0, cv2.COLOR_BGR2RGBA)
pipe = Pipe(data=rgb)
#pipe = Pipe(data=[])
IOLoop.current().add_callback(f)
hv.DynamicMap(hv.RGB, streams=[pipe])

```