stremlit+fastapi处理视频

使用stremalit以及fastapi来处理视频

  • 思路1

在steamlit中通过opencv打开视频中的每一帧,再将图片发送到后端进行相关处理,最后返回处理好的图片,将其显示在同一位置连续展示达到视频效果。这样可以实现实时返回结果,关键代码如下。

# 使用opencv读取视频帧并展示 来达到视频的效果
image_placeholder = st.empty()  # 创建空白块使得展示原图
result_place = st.empty()  # 创建空白块使得展示处理好的结果

import tempfile

f = st.file_uploader("Upload file")  # 上传本地视频 数据以二进制写入内存无法直接用opencv打开

if f is not None:
    tfile = tempfile.NamedTemporaryFile(delete=False)  # 创建临时文件
    tfile.write(f.read())  # 视频数据写入临时文件

    cap = cv2.VideoCapture(tfile.name)  # opencv打开临时文件
    if (cap.isOpened() == False):
        st.write("Error opening video stream or file")

    while (cap.isOpened()):
        success, frame = cap.read()
        if success:
            to_show = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)  # 读取当前帧图片数据
            to_show = Image.fromarray(np.uint8(to_show))  # numpy.ndarray 转 PIL.Image.Image
            bytes_io = io.BytesIO()  
            to_show.save(bytes_io, format="PNG")  # 将数据以二进制写入内存

            estimate = process(bytes_io.getvalue(), backend)  # 发送二进制图片数据 返回处理好的图片二进制数据
            estimated_image = Image.open(io.BytesIO(estimate.content)).convert("RGB") # 得到处理好的结果图片
            image_placeholder.image(to_show, caption='Video')  # 原图片 将图片帧展示在同一位置得到视频效果
            result_place.image(estimated_image, caption='Video')  # 结果图片 将图片帧展示在同一位置得到视频效果

        else:
            break
    cap.release()
  • 思路2

将整个视频作为数据发送到后端,在后台将整个视频处理好后,再发送回前端。

streamlit

使用st.file_uploader读取本地视频,再使用st.video展示处理完的视频,代码如下。

f = st.file_uploader("Upload file")  # 上传本地视频   数据为二进制存在内存中 可通过f.getvalue读取

if f is not None:
    estimate = process(f, backend)  # 返回response需要用response.content读取其中内容
    estimate = io.BytesIO(estimate.content)  # 往内存中写入estimate.content数据
    st.video(estimate, format="video/mp4", start_time=0)  # 展示视频

fastapi

采用response文件的方式将我们处理好的视频发送至前端,代码如下。

@app.post("/estimation", response_class=FileResponse)
def main(file: bytes = File(...)):
    out_video = video_process(file)  # 使用response文件方式 video_process返回值为文件名
    return out_video

opencv处理前端发送过来的数据

仍然采用创建临时文件的方式打开前端传过来的二进制数据,代码如下。
注意,opencv保存视频时需选择avc1编码方式,streamlit不支持显示MP4V的编码视频。
以及streamlit可能不支持显示avi文件,建议保存文件统一为MP4格式。

def video_process(binary_video):
    import tempfile
    
     outfile_name = 'output.mp4'  # 输出结果文件名
    
    binary_video = io.BytesIO(binary_video)  # 将前端传来binary_video写入内存
    tfile = tempfile.NamedTemporaryFile(delete=False)  # 创建临时文件
    tfile.write(binary_video.read())  # 写入临时文件

    cap = cv2.VideoCapture(tfile.name)  # 打开文件
    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))  # 获取视频图像宽
    height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))  # 获取视频图像高
    fps = cap.get(cv2.CAP_PROP_FPS)  # 读取图像显示帧率
    fourcc = int(cv2.VideoWriter_fourcc(*'avc1'))  # 选择编码方式 streamlit不支持显示MPV4编码方式
    out = cv2.VideoWriter(outfile_name, fourcc, fps, (width, height))  # 创建输出视频
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值