相关文章推荐
飞奔的可乐  ·  pgsql 16进制转中文 - CSDN文库·  10 月前    · 
瘦瘦的野马  ·  【精选】Kotlin的数组array和集合l ...·  1 年前    · 
不拘小节的双杠  ·  MySQL启动报错[ERROR] ...·  1 年前    · 
风流倜傥的麦片  ·  PaddleDetection 快速上手 ...·  2 年前    · 
爽快的哑铃  ·  excel 去除特殊字符-掘金·  2 年前    · 
Code  ›  Python+Opencv读取高帧率USB摄像头问题开发者社区
帧率
https://cloud.tencent.com/developer/article/2210232
谦虚好学的大脸猫
1 年前
作者头像
虫无涯
0 篇文章

Python+Opencv读取高帧率USB摄像头问题

原创
前往专栏
腾讯云
开发者社区
文档 意见反馈 控制台
首页
学习
活动
专区
工具
TVP
文章/答案/技术大牛
发布
首页
学习
活动
专区
工具
TVP
返回腾讯云官网
社区首页 > 专栏 > 全栈测试技术 > Python+Opencv读取高帧率USB摄像头问题

Python+Opencv读取高帧率USB摄像头问题

原创
作者头像
虫无涯
发布 于 2023-01-17 17:15:52
1K 0
发布 于 2023-01-17 17:15:52
举报

前几次使用Python+Opencv,对网络摄像头,USB摄像头进行 数据采集 ,基本流程已经跑通,没什么大问题。最近项目中使用了一款120fps/s的USB摄像头,但是调试好代码运行后,问题来了。

遇到的问题

120fps,每次只能读取30多张图片或者最多也在40张以下。根本达不到要求。

开始使用的代码

# -*- coding: cp936 -*-
Author:NoamaNelson
Date:2019-11-19
Discription:Read Camaro picture and save 
import cv2,os,time
import numpy as np
class CamaroCap(object):
    """ 打开视频流 """
    def __init__(self):
        self.cap = cv2.VideoCapture(0) 
    """ 图片信息打印 """      
    def get_image_info(self,image):
        print(type(image))
        print(image.shape)
        print(image.size)
        print(image.dtype)
        pixel_data = np.array(image)
        print(pixel_data)
    """ 逐帧读取数据并保存图片到本地制定位置 """
    def Camaro_image(self):
        i = 0
        while(True):
            ret,frame = self.cap.read() #ret:True或者False,代表有没有读取到图片;frame:表示截取到一帧的图片
            if ret == False:
                break
            self.get_image_info(frame) # print("打印图片信息") 注意:调试的时候可以打开,如果是一直运行程序,建议把这行代码注释掉,避免影响内存占用          
            cv2.imshow('capture',frame) # 展示图片
            cv2.imwrite(r"D:\image\\"+ str(i) + ".jpg",frame)  # 保存图片
            i = i + 1
            if cv2.waitKey(1) & 0xFF == ord('q'): # 
                break
if __name__ == '__main__':
    outmasages = CamaroCap() 
    outmasages.Camaro_image() # 调用摄像头
    outmasages.cap.release() # 释放对象和销毁窗口
    cv2.destroyAllWindows()
    

问题分析

  • 笔者发现,每次在摄像头的控制软件上调参数,比如分辨率设置800 600,但是运行代码后依然是640 480,why?why?
  • 该摄像头在640*480分辨率下,支持120fps,笔者在代码中限制了下帧率为60fps,但还是每秒只能获取30多张图片,这又是Why?why?
self.cap.set(cv2.CAP_PROP_FPS, 60)
  • 开始求助网络,从网上搜了很多,终于是看到了希望
  • 原来以上问题在于, 博主链接 分析结论笔者使用的USB相机,同样支持视频编码格式为YUY2/MJPG,但是Opencv默认读取的是YUY2,而笔者在摄像头控制软件上查看了下,YUY2格式的各种分辨率下的帧率最大才40帧,那么这就对了,就知道为啥一直是30-40张图片了。那么就需要在脚本中修改格式为MJPG,从以上博主的链接中可以看到:
  • 如果要修改分辨率就必须使用:
CAP_PROP_FRAME_WIDTH 和 CAP_PROP_FRAME_HEIGHT进行设置宽和高
  • 要修改格式为MJPG编码必须使用:
CV_CAP_PROP_FOURCC
  • 那么就需要在代码中加入:
#self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 800)
#self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 600)
#self.cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'))

修改后的代码

# -*- coding: cp936 -*-
Author:zhangbo
Date:2019-11-07
Discription:Read Camaro picture and save 
import cv2,os,time,datetime
import numpy as np
class CamaroCap(object):
    """ 打开视频流 """
    def __init__(self):
        self.cap = cv2.VideoCapture(0)
        #self.cap.set(cv2.CAP_PROP_FPS, 120) 这个有时候生效,有时候不生效不知道是什么原因
        self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 800)
        self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 600)
        self.cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'))
    """ 图片信息打印 """      
    def get_image_info(self,image):
        print(type(image))
        print(image.shape)
        print(image.size)
        print(image.dtype)
        pixel_data = np.array(image)
        print(pixel_data)
    """ 逐帧读取数据并保存图片到本地制定位置 """
    def Camaro_image(self):
        i = 0
        while(True):
            ret,frame = self.cap.read() #ret:True或者False,代表有没有读取到图片;frame:表示截取到一帧的图片
            if ret == False:
                break
            #self.get_image_info(frame) # print("打印图片信息") 注意:调试的时候可以打开,如果是一直运行程序,建议把这行代码注释掉,避免影响内存占用          
            cv2.imshow('capture',frame) # 展示图片
            mtime = datetime.datetime.now().strftime('%Y-%m-%d_%H_%M_%S')
            print(mtime)
            cv2.imwrite(r"D:\image\\" + str(i) + str("-") + mtime + ".jpg",frame)  # 保存图片
            i = i + 1
            if cv2.waitKey(1) & 0xFF == ord('q'): 
                break
if __name__ == '__main__':
    outmasages = CamaroCap() 
 
推荐文章
飞奔的可乐  ·  pgsql 16进制转中文 - CSDN文库
10 月前
瘦瘦的野马  ·  【精选】Kotlin的数组array和集合list的简单使用以及注意事项_kotlin vararg arraylist_liuhaha1015的博客-CSDN博客
1 年前
不拘小节的双杠  ·  MySQL启动报错[ERROR] InnoDB: Trying to access page number 4294967295 in space 0, space name innodb_system, which is outside the tables
1 年前
风流倜傥的麦片  ·  PaddleDetection 快速上手 - 野哥李 - 博客园
2 年前
爽快的哑铃  ·  excel 去除特殊字符-掘金
2 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号