返回顶部
首页 > 资讯 > 后端开发 > Python >在python中使用nvidia的VPF库对RTSP流进行硬解码并使用opencv进行显示
  • 878
分享到

在python中使用nvidia的VPF库对RTSP流进行硬解码并使用opencv进行显示

pythonopencvvpfRTSP硬解码gpu解码 2023-09-08 10:09:18 878人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

解码并处理视频流的多线程应用 随着视频处理技术的不断发展,越来越多的应用需要对视频流进行解码和处理。在本文中,我们将介绍一个基于python的多线程应用程序,该应用程序可以解码并处理多个RTSP视频流,同时利用GPU加速,以提高处理速度。

解码并处理视频流的多线程应用

随着视频处理技术的不断发展,越来越多的应用需要对视频流进行解码和处理。在本文中,我们将介绍一个基于python多线程应用程序,该应用程序可以解码并处理多个RTSP视频流,同时利用GPU加速,以提高处理速度。

这个应用程序使用了一些关键的Python库和工具,包括PyNvCodec、OpenCV、和PyCUDA等。它充分利用了现代GPU的计算能力,实现了高效的视频解码和处理。

多线程解码

在这个应用程序中,我们使用了Python的concurrent.futures库来实现多线程解码。每个视频流都在独立的线程中解码,这样可以同时处理多个视频流,充分利用了多核CPU的性能。

from concurrent.futures import ThreadPoolExecutor# ...# 创建线程池pool = ThreadPoolExecutor(max_workers=len(urls))futures = []# 遍历每个视频流并提交解码任务for url in urls:    future = pool.submit(decode_rtsp_stream, index, url, gpuID)    futures.append(future)    index += 1# 等待所有任务完成pool.shutdown()# 获取每个任务的结果for future in futures:    future.result()

视频解码和处理

视频解码是这个应用程序的核心功能。我们使用PyNvCodec库来进行视频解码,同时利用了GPU来加速处理。

def decode_rtsp_stream(thread_index: int, url: str, gpu_id: int):    # 获取视频流参数    params = get_stream_params(url)    # ...    # 创建NvDecoder实例    nvdec = nvc.PyNvDecoder(w, h, f, c, g)    # ...    while True:        # 读取视频流数据        bits = proc.stdout.read(read_size)        # ...        # 解码视频帧        surf = nvdec.DecodeSurfaceFromPacket(enc_packet, pkt_data)        # ...        # 执行颜色空间转换和表面下载        cvtSurface = nv_cvt.Execute(surf, cc_ctx)        success = nv_down.DownloadSingleSurface(cvtSurface, data)        # ...        # 显示解码后的帧        cv2.imshow(str(thread_index), new_data)        cv2.waiTKEy(1)    # ...

完整代码

这个应用程序可以广泛用于视频监控、实时视频分析、视频编码和解码等领域。通过多线程解码和GPU加速,它可以处理多个高分辨率视频流,并在实时性要求较高的情况下提供流畅的显示和处理效果。

import osimport sysimport subprocessimport jsonimport PyNvCodec as nvcimport numpy as npfrom io import BytesIOfrom multiprocessing import Processimport uuidimport timefrom concurrent.futures import ThreadPoolExecutorimport cv2import pycuda.gpuarray as gpuarray# import PytorchNvCodec as pnvcimport torchimport torchvision.transforms as Tdef add_cuda_dll_directories():    if os.name == "nt":        cuda_path = os.environ.get("CUDA_PATH")        if cuda_path:            os.add_dll_directory(cuda_path)        else:            print("CUDA_PATH environment variable is not set.", file=sys.stderr)            exit(1)        sys_path = os.environ.get("PATH")        if sys_path:            paths = sys_path.split(";")            for path in paths:                if os.path.isdir(path) and path != '.':                    os.add_dll_directory(path)        else:            print("PATH environment variable is not set.", file=sys.stderr)            exit(1)def surface_to_tensor(surface: nvc.Surface) -> torch.Tensor:    """    Converts planar rgb surface to cuda float tensor.    """    if surface.FORMat() != nvc.PixelFormat.RGB_PLANAR:        raise RuntimeError("Surface shall be of RGB_PLANAR pixel format")    surf_plane = surface.PlanePtr()    img_tensor = pnvc.DptrToTensor(        surf_plane.GpuMem(),        surf_plane.Width(),        surf_plane.Height(),        surf_plane.Pitch(),        surf_plane.ElemSize(),    )    if img_tensor is None:        raise RuntimeError("Can not export to tensor.")    img_tensor.resize_(3, int(surf_plane.Height() / 3), surf_plane.Width())    img_tensor = img_tensor.type(dtype=torch.cuda.FloatTensor)    img_tensor = torch.divide(img_tensor, 255.0)    img_tensor = torch.clamp(img_tensor, 0.0, 1.0)    return img_tensordef get_stream_params(url: str):    cmd = [        "ffprobe",        "-v",        "quiet",        "-print_format",        "JSON",        "-show_format",        "-show_streams",        url,    ]    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)    stdout = proc.communicate()[0]    bio = BytesIO(stdout)    json_out = json.load(bio)    params = {}    if not "streams" in json_out:        return {}    for stream in json_out["streams"]:        if stream["codec_type"] == "video":            params["width"] = stream["width"]            params["height"] = stream["height"]            params["framerate"] = float(eval(stream["avg_frame_rate"]))            codec_name = stream["codec_name"]            is_h264 = True if codec_name == "h264" else False            is_hevc = True if codec_name == "hevc" else False            if not is_h264 and not is_hevc:                raise ValueError(                    "Unsupported codec: "                    + codec_name                    + ". Only H.264 and HEVC are supported in this sample."                )            else:                params["codec"] = (                    nvc.CudaVideoCodec.H264 if is_h264 else nvc.CudaVideoCodec.HEVC                )                pix_fmt = stream["pix_fmt"]                is_yuv420 = pix_fmt == "yuv420p"                is_yuv444 = pix_fmt == "yuv444p"                # YUVJ420P and YUVJ444P are deprecated but still wide spread, so handle                # them as well. They also indicate JPEG color range.                is_yuvj420 = pix_fmt == "yuvj420p"                is_yuvj444 = pix_fmt == "yuvj444p"                if is_yuvj420:                    is_yuv420 = True                    params["color_range"] = nvc.ColorRange.JPEG                if is_yuvj444:                    is_yuv444 = True                    params["color_range"] = nvc.ColorRange.JPEG                if not is_yuv420 and not is_yuv444:                    raise ValueError(                        "Unsupported pixel format: "                        + pix_fmt                        + ". Only YUV420 and YUV444 are supported in this sample."                    )                else:                    params["format"] = (                        nvc.PixelFormat.NV12 if is_yuv420 else nvc.PixelFormat.YUV444                    )                # Color range default option. We may have set when parsing                # pixel format, so check first.                if "color_range" not in params:                    params["color_range"] = nvc.ColorRange.MPEG                # Check actual value.                if "color_range" in stream:                    color_range = stream["color_range"]                    if color_range == "pc" or color_range == "jpeg":                        params["color_range"] = nvc.ColorRange.JPEG                # Color space default option:                params["color_space"] = nvc.ColorSpace.BT_601                # Check actual value.                if "color_space" in stream:                    color_space = stream["color_space"]                    if color_space == "bt709":                        params["color_space"] = nvc.ColorSpace.BT_709                return params    return {}def decode_rtsp_stream(thread_index: int, url: str, gpu_id: int):    params = get_stream_params(url)    if not len(params):        raise ValueError("Can not get " + url + " streams params")    w = params["width"]    h = params["height"]    f = params["format"]    c = params["codec"]    framerate = params["framerate"]    g = gpu_id    if nvc.CudaVideoCodec.H264 == c:        codec_name = "h264"    elif nvc.CudaVideoCodec.HEVC == c:        codec_name = "hevc"    bsf_name = codec_name + "_mp4toannexb,dump_extra=all"    cmd = [        "FFmpeg",        "-hide_banner",        "-i",        url,        "-c:v",        "copy",        "-bsf:v",        bsf_name,        "-f",        codec_name,        "pipe:1",    ]    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)    nvdec = nvc.PyNvDecoder(w, h, f, c, g)    read_size = 4096    rt = 0    fd = 0    t0 = time.time()    print("running stream")    # nv_cvt = nvc.PySurfaceConverter(    #     w, h, self.nvYuv.Format(), nvc.PixelFormat.RGB, 0    # )    nv_cvt = nvc.PySurfaceConverter(w, h, nvc.PixelFormat.NV12, nvc.PixelFormat.BGR, g)    cc_ctx = nvc.ColorspaceConversionContext(        params["color_space"], params["color_range"]    )    nv_down = nvc.PySurfaceDownloader(        w, h, nv_cvt.Format(), g    )    data = np.zeros((w * h, 3), np.uint8)    empty_count = 0    while True:        t1=time.time()        if not read_size:            read_size = int(rt / fd)            rt = read_size            fd = 1        bits = proc.stdout.read(read_size)        if not len(bits):            print("Can't read data from pipe")            break        else:            rt += len(bits)        enc_packet = np.frombuffer(buffer=bits, dtype=np.uint8)        pkt_data = nvc.PacketData()        try:            surf = nvdec.DecodeSurfaceFromPacket(enc_packet, pkt_data)            if not surf.Empty():                fd += 1                if pkt_data.bsl < read_size:                    read_size = pkt_data.bsl                cvtSurface = nv_cvt.Execute(surf, cc_ctx)                success = nv_down.DownloadSingleSurface(cvtSurface, data)                if success:                    new_data = data.reshape((h, w, 3))                    cv2.imshow(str(thread_index), new_data)                    cv2.waitKey(1)            else:                empty_count += 1                if empty_count > framerate * 30:                    print("surf is Empty too many times > "+str(framerate * 30))                    nvdec = nvc.PyNvDecoder(w, h, f, c, g)                    empty_count = 0        except nvc.HwResetException:            nvdec = nvc.PyNvDecoder(w, h, f, c, g)            empty_count = 0            continue        t2 = time.time()        # print((t2-t1)*1000)if __name__ == "__main__":    add_cuda_dll_directories()    print("This sample decodes multiple videos in parallel on given GPU.")    print("It doesn't do anything beside decoding, output isn't saved.")    print("Usage: SampleDecodeRTSP.py $gpu_id $url1 ... $urlN .")    if len(sys.argv) < 2:        print("Provide gpu ID and input URL(s).")        exit(1)    gpuID = int(sys.argv[1])    urls = sys.argv[2:]    pool = ThreadPoolExecutor(max_workers=len(urls))    futures = []    index = 0    for url in urls:        future = pool.submit(decode_rtsp_stream, index, url, gpuID)        futures.append(future)        index += 1    pool.shutdown()    for future in futures:        future.result()

运行脚本

python rtsp_decoder.py  0 rtsp://admin:a1234567@10.10.16.26:554/Streaming/Channels/101?transportmode=multicast

VPF库安装

windows11编译VideoProcessingFramework库_random_2011的博客-CSDN博客

来源地址:https://blog.csdn.net/q317379184/article/details/132174203

--结束END--

本文标题: 在python中使用nvidia的VPF库对RTSP流进行硬解码并使用opencv进行显示

本文链接: https://lsjlt.com/news/399774.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 在python中使用nvidia的VPF库对RTSP流进行硬解码并使用opencv进行显示
    解码并处理视频流的多线程应用 随着视频处理技术的不断发展,越来越多的应用需要对视频流进行解码和处理。在本文中,我们将介绍一个基于Python的多线程应用程序,该应用程序可以解码并处理多个RTSP视频流,同时利用GPU加速,以提高处理速度。...
    99+
    2023-09-08
    python opencv vpf RTSP硬解码 gpu解码
  • 详解在Python中使用OpenCV进行直线检测
    目录1. 引言2. 霍夫变换3. 举个栗子3.1 读入图像 进行灰度化3.2 执行边缘检测3.3 进行霍夫变换补充1. 引言 在图像处理中,直线检测是一种常见的算法,它通常获取n个边...
    99+
    2024-04-02
  • 在Python中如何使用OpenCV进行直线检测
    这篇文章主要介绍了在Python中如何使用OpenCV进行直线检测的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇在Python中如何使用OpenCV进行直线检测文章都会有所收获,下面我们一起来看看吧。1. 引言...
    99+
    2023-06-29
  • 怎么在python中使用Pandas对MySQL数据库进行读写
    本篇文章给大家分享的是有关怎么在python中使用Pandas对MySQL数据库进行读写,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。1、read_sql_query 读取 m...
    99+
    2023-06-14
  • 怎么在Python中使用Selenium对Cookie进行操作
    这篇文章给大家介绍怎么在Python中使用Selenium对Cookie进行操作,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。python主要应用领域有哪些1、云计算,典型应用OpenStack。2、WEB前端开发,众...
    99+
    2023-06-14
  • 在跨平台环境中使用C++进行图形显示
    跨平台 c++++ 图形显示答案: 是,c++ 具有跨平台特性,使其适合构建可以在各种操作系统上运行的图形应用程序。详情:图形库: sfml、sdl 和 imgui 等库提供跨平台兼容性...
    99+
    2024-05-10
    c++ 图形显示 linux macos
  • 怎么在python中使用pynput库对鼠标、键盘进行监控
    这篇文章将为大家详细讲解有关怎么在python中使用pynput库对鼠标、键盘进行监控,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。python是什么意思Python是一种跨平台的、具有解释...
    99+
    2023-06-08
  • 如何在Python中使用二维码对象进行数据传输?
    在当今数字化的时代,二维码已经成为了一种非常常见的数据传输方式。Python作为一种流行的编程语言,自然也有相应的库可以用来生成和解码二维码。在本篇文章中,我们将会探讨如何在Python中使用二维码对象进行数据传输。 一、生成二维码对象 P...
    99+
    2023-10-23
    响应 二维码 对象
  • SpringBoot中使用Redis对接口进行限流的实现
    目录实现的思路 使用 Hash 存储接口的限流配置 使用普通kv,存储api的请求次数 使用SpringBoot实现 RedisKeys ObjectRedisTemplate Re...
    99+
    2024-04-02
  • 如何在Python中使用Selenium对异常进行处理
    这篇文章主要介绍了如何在Python中使用Selenium对异常进行处理,编程网小编觉得不错,现在分享给大家,也给大家做个参考,一起跟随编程网小编来看看吧!python是什么意思Python是一种跨平台的、具有解释性、编译性、互动性和面向对...
    99+
    2023-06-06
  • 怎么在python中使用except对异常进行处理
    本篇文章为大家展示了怎么在python中使用except对异常进行处理,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。python有哪些常用库python常用的库:1.requesuts;2.scra...
    99+
    2023-06-14
  • 怎么在python中使用moviepy对视频进行处理
    本篇文章为大家展示了怎么在python中使用moviepy对视频进行处理,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Python主要用来做什么Python主要应用于:1、Web开发;2、数据科学研...
    99+
    2023-06-08
  • 使用PHP中的urlencode()函数对URL进行编码
    使用PHP中的urlencode()函数对URL进行编码的具体代码示例如下:<php // 定义要编码的URL $url = "https://www.example.com/searchq=一个中文查询"; ...
    99+
    2023-11-18
    PHP URL编码 urlencode函数
  • Android使用KeyStore对数据进行加密的示例代码
    谈到 Android 安全性话题,Android Developers 官方网站给出了许多很好的建议和讲解,涵盖了存储数据、权限、网络、处理凭据、输入验证、处理用户数据、加密等...
    99+
    2022-06-06
    加密 keystore 示例 数据 Android
  • 怎么在python中使用sorted对键和值进行排序
    今天就跟大家聊聊有关怎么在python中使用sorted对键和值进行排序,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Python的优点有哪些1、简单易用,与C/C++、Java、C...
    99+
    2023-06-14
  • 如何在Java中使用RSA加密对密码进行加密解密
    这期内容当中小编将会给大家带来有关如何在Java中使用RSA加密对密码进行加密解密,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。具体如下:public static void ...
    99+
    2023-05-31
    java rsa加密 ava
  • 如何使用Python中的多线程进行任务并发执行
    如何使用Python中的多线程进行任务并发执行多线程是一种常用的并发编程技术,可以提高程序的执行效率。在Python中,使用多线程可以实现任务的并发执行,从而加快程序的运行速度。本文将介绍如何使用Python中的多线程进行任务的并发执行,并...
    99+
    2023-10-22
    并发执行 Python多线程
  • 使用Python对Syslog信息进行分析并绘图的实现
    实验目的: 对设备Syslong信息进行分析记录,并写入sqlite数据库中;后续读取数据库的信息,对Syslog的严重级别分布、来源进行分析进行分析。 同时监控O...
    99+
    2024-04-02
  • 如何在 Python 中使用 NumPy 库对文件中的数据进行统计分析?
    Python 是一种强大的编程语言,它拥有众多的库和工具可以帮助开发者更高效地完成任务。其中,NumPy 库是一款专门用于数值计算的库,在处理大量数据时可以提供高效的处理速度和良好的性能。 在本文中,我们将介绍如何使用 NumPy 库对文件...
    99+
    2023-11-04
    文件 关键字 numy
  • 如何在JAVA中使用MD5加密对密码进行加密
    本篇文章为大家展示了如何在JAVA中使用MD5加密对密码进行加密,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。新建Md5.javapackage com.loger.md5;import java....
    99+
    2023-05-31
    java md5加密 ava
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作