解决pyuvc无法读取yuv格式的问题

news/2024/7/21 7:50:18 标签: python, yuv, UVC摄像头, 图像处理, opencv

问题描述

我使用pyuvc访问uvc摄像头,但是发现pyuvc只支持了MJPEG的格式和GRAY格式。我在linux下通过v4l2-ctl查看,发现摄像头本身还支持YUV的格式,但是pyuvc解析出的帧格式则没有。后面通过阅读pyuvc的代码,发现libuvc本身没有限制YUV的格式,是pyuvc限制的。修改代码后重新编译whl,重新安装就可以了。

yuvcyuv_3">如何让pyuvc支持yuv格式

要修改的内容都在uvc_bindings.pyx中。

首先修改_supported_formats,增加对uvc.UVC_FRAME_FORMAT_YUYV和uvc.UVC_FRAME_FORMAT_ANY的支持。修改前后的对比如下:
在这里插入图片描述
然后在class Frame中增加一个获取原始buffer的接口:

python">    @property
    def data_buffer(self):
        cdef np.uint8_t[::1] view = <np.uint8_t[:self._uvc_frame.data_bytes]>self._uvc_frame.data
        return view

最后修改class Capture的get_frame()成员函数,让其在读取到MJPEG、GRAY之外的格式时,使用Frame类来存放帧数据:

python">        if uvc_frame.frame_format == uvc.UVC_COLOR_FORMAT_MJPEG:
            ##check jpeg header
            header_ok = turbojpeg.tjDecompressHeader2(
                self.tj_context,
                <unsigned char *>uvc_frame.data,
                uvc_frame.data_bytes,
                &j_width,
                &j_height,
                &jpegSubsamp
            )
            if not (
                header_ok >= 0 and
                uvc_frame.width == j_width and
                uvc_frame.height == j_height
            ):
                raise StreamError("JPEG header corrupt.")
            out_frame_mjpeg = MJPEGFrame()
            out_frame_mjpeg.tj_context = self.tj_context
            out_frame_mjpeg.attach_uvcframe(uvc_frame=uvc_frame, copy=True)
            frame = out_frame_mjpeg

        elif uvc_frame.frame_format == uvc.UVC_COLOR_FORMAT_GRAY8:
            # if uvc_frame.width * uvc_frame.height > uvc_frame.data_bytes:
            #     raise StreamError(
            #         f"Received too few bytes to fill {uvc_frame.width}x"
            #         f"{uvc_frame.height} GRAY8 image"
            #     )
            out_frame_gray = Frame()
            out_frame_gray.attach_uvcframe(uvc_frame=uvc_frame, copy=True)
            frame = out_frame_gray

        else:
            # 这个分支是新增的
            out_frame_gray = Frame()
            out_frame_gray.attach_uvcframe(uvc_frame=uvc_frame, copy=True)
            frame = out_frame_gray

代码变化如下:

python">         else:
-            raise NotImplementedError(f"Unsupported frame format {uvc_frame.frame_format}")
+            out_frame_gray = Frame()
+            out_frame_gray.attach_uvcframe(uvc_frame=uvc_frame, copy=True)
+            frame = out_frame_gray

yuvc_66">编译pyuvc

在windows下编译pyuvc需要提前安装vsstudio,我装的是vsstudio2015,具体命令参考源码中的README.rst文件的描述:

   pip install build delvewheel
   git clone https://github.com/pupil-labs/pyuvc --recursive
   cd pyuvc
   scripts/download-deps-win.ps1 -DEPS_TMP_PATH tmp
   $Env:DEPS_PATHS_LOC = "tmp/dep_paths.json"
   python -m build -w   # will create a wheel in dist/ folder; insert the wheel path below
   python scripts/repair-wheels-win.py $Env:DEPS_PATHS_LOC <wheel location> wheelhouse
   pip install wheelhouse/<wheel name>

在编译中我遇到的问题在delvewheel进行repair时报Unable to find library: msvcr100.dll【已解决】这篇文章中有介绍。

编译生成新的whl文件在源码的wheelhouse/目录下。在本地安装或者复制到其它环境下安装均可。

yuv_83">如何使用yuv数据

我的摄像头返回的是packaged格式的YUV420数据,我直接保存到磁盘文件中。

python">frame = cam.get_frame(timeout=0.001)
data_buffer = frame.data_buffer
with open(f"data_buffer{i}.yuy2",'wb') as f:
    f.write(data_buffer)

也可以用opencv来转码。

参考资料

使用python访问uvc摄像头

delvewheel进行repair时报Unable to find library: msvcr100.dll【已解决】

linux下使用v4l2-ctl查看摄像头数据


http://www.niftyadmin.cn/n/5304986.html

相关文章

pythonPandas四:数据操作与转换

当涉及到数据操作和转换时&#xff0c;Pandas提供了许多有用的功能。以下是一些示例说明&#xff1a; 数据选择和操作&#xff1a; import pandas as pd# 创建一个示例DataFrame data {Name: [Alice, Bob, Charlie],Age: [25, 30, 35],City: [New York, London, Paris]} df p…

使用 SpringSecurity 发送POST请求出现 403

问题场景 在使用 SpringSecurity 时对一些访问权限进行了设置, 在用户请求资源时出现了403错误 , 通过检查代码发现请求权限是开放的, 并且切换成 GET 请求也是可以通过, 换成POST 请求就无法通过。 解决方法 在 SpringSecurity 中关闭 CSRF 因为 前端向后台发送 post 请求…

5-7 各门课程平均分(列的计算)——python

dt eval(input()).values() number {} lsn [] for i in dt:for j in i.keys():lsn.append(j)number[j] number.get(j,0) i[j] number sorted(number.items(),key lambda x : x[1], reverse True) for x,y in number:print(f"{x}平均{y/len(dt):.1f}分",) 编写…

郑州大学算法设计与分析实验2

判断题 1 #include<bits/stdc.h> using namespace std;const int N 50; int f[N], n;int main() { // freopen("1.in", "r", stdin);ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin >> n;f[1] 1; f[2] 1;for(int i 3; i &l…

家具工厂ERP有什么功能?能为企业带来哪些优势

市面上的家具产品类型多、销售平台多、用料复杂、关联业务多&#xff0c;各种经营数据的统计分析工作量繁重&#xff0c;传统粗放型管理模式难以满足现代精细化管理需求。 有些家具工厂利用ERP系统轻松实现多终端数据实时同步、随时掌握车间工时负荷、减少物料BOM数据录入工作…

fabric学习

1.通过connection连接远程主机&#xff0c;并执行命令 from fabric import connectioncon1 connection.Connection(host10.10.102.198, userroot, port22, connect_kwargs{"password":"HCCloud2022CN"}) con1.run(free -h) 2.上传压缩文件到主机指定目录…

Linux中删除文件的命令方法大全

Linux中删除文件的命令方法大全 linux中快速删除的几种方法一. rm -rf1&#xff0c;删除一个文件&#xff1a;2&#xff0c;删除一个目录及其内容&#xff1a;3&#xff0c;删除多个文件或目录&#xff1a;4&#xff0c;使用通配符删除一类文件&#xff1a;1&#xff0c;*&…

【力扣100】35.搜索插入位置 || 二分查找

添加链接描述 class Solution:def searchInsert(self, nums: List[int], target: int) -> int:nlen(nums)i,j0,n-1while i<j:midi(j-i)//2if nums[mid]target:return midelif target<nums[mid]:jmid-1else:imid1 #包含两种情况&#xff0c;1.target在mid右边…