乐趣区

关于python:PythonOpencv读取高帧率USB摄像头问题

前几次应用 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()
    

问题剖析

  • 笔者发现,每次在摄像头的控制软件上调参数,比方分辨率设置 800600,然而运行代码后仍然是 640480,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,从以上博主的链接中能够看到:
<div class=”table-box”><table align=”center” border=”1″ cellpadding=”1″ cellspacing=”1″><thead><tr><th scope=”col” style=”text-align:center;vertical-align:middle;”> 参数 </th>

        <th scope="col" style="text-align:center;vertical-align:middle;"> 值 </th>
        <th scope="col" style="text-align:center;vertical-align:middle;width:514px;"> 性能 / 意义 </th>
    </tr></thead><tbody><tr><td style="text-align:center;vertical-align:middle;">CV_CAP_PROP_POS_MSEC</td>
        <td style="text-align:center;vertical-align:middle;">0</td>
        <td style="text-align:center;vertical-align:middle;width:514px;"> 视频文件的以后地位(以毫秒为单位)或视频捕捉工夫戳 </td>
    </tr><tr><td style="text-align:center;vertical-align:middle;">CV_CAP_PROP_POS_FRAMES</td>
        <td style="text-align:center;vertical-align:middle;">1</td>
        <td style="text-align:center;vertical-align:middle;width:514px;"> 基于 0 的索引将被解码 / 捕捉下一帧 </td>
    </tr><tr><td style="text-align:center;vertical-align:middle;">CV_CAP_PROP_POS_AVI_RATIO</td>
        <td style="text-align:center;vertical-align:middle;">2</td>
        <td style="text-align:center;vertical-align:middle;width:514px;"> 视频文件绝对地位:0 - 电影的开始,电影的 1 - 完结 </td>
    </tr><tr><td style="text-align:center;vertical-align:middle;">CV_CAP_PROP_FRAME_WIDTH</td>
        <td style="text-align:center;vertical-align:middle;">3</td>
        <td style="text-align:center;vertical-align:middle;width:514px;"> 视频里每一帧的宽 </td>
    </tr><tr><td style="text-align:center;vertical-align:middle;">CV_CAP_PROP_FRAME_HEIGHT</td>
        <td style="text-align:center;vertical-align:middle;">4</td>
        <td style="text-align:center;vertical-align:middle;width:514px;"> 视频里每一帧的高 </td>
    </tr><tr><td style="text-align:center;vertical-align:middle;">CV_CAP_PROP_FPS</td>
        <td style="text-align:center;vertical-align:middle;">5</td>
        <td style="text-align:center;vertical-align:middle;width:514px;"> 视频的帧速 </td>
    </tr><tr><td style="text-align:center;vertical-align:middle;">CV_CAP_PROP_FOURCC</td>
        <td style="text-align:center;vertical-align:middle;">6</td>
        <td style="text-align:center;vertical-align:middle;width:514px;">4 个字符示意的视频编码器格局 </td>
    </tr><tr><td style="text-align:center;vertical-align:middle;">CV_CAP_PROP_FRAME_COUNT</td>
        <td style="text-align:center;vertical-align:middle;">7</td>
        <td style="text-align:center;vertical-align:middle;width:514px;"> 视频的帧数 </td>
    </tr><tr><td style="text-align:center;vertical-align:middle;">CV_CAP_PROP_FORMAT</td>
        <td style="text-align:center;vertical-align:middle;">8</td>
        <td style="text-align:center;vertical-align:middle;width:514px;">byretrieve()返回的 Mat 对象的格局 </td>
    </tr><tr><td style="text-align:center;vertical-align:middle;">CV_CAP_PROP_MODE</td>
        <td style="text-align:center;vertical-align:middle;">9</td>
        <td style="text-align:center;vertical-align:middle;width:514px;"> 批示以后捕捉模式的后端特定值 </td>
    </tr><tr><td style="text-align:center;vertical-align:middle;">CV_CAP_PROP_BRIGHTNESS</td>
        <td style="text-align:center;vertical-align:middle;">10</td>
        <td style="text-align:center;vertical-align:middle;width:514px;"> 图像的亮度(仅实用于相机)</td>
    </tr><tr><td style="text-align:center;vertical-align:middle;">CV_CAP_PROP_CONTRAST</td>
        <td style="text-align:center;vertical-align:middle;">11</td>
        <td style="text-align:center;vertical-align:middle;width:514px;"> 图像对比度(仅实用于相机)</td>
    </tr><tr><td style="text-align:center;vertical-align:middle;">CV_CAP_PROP_SATURATION</td>
        <td style="text-align:center;vertical-align:middle;">12</td>
        <td style="text-align:center;vertical-align:middle;width:514px;"> 图像的饱和度(仅实用于相机)</td>
    </tr><tr><td style="text-align:center;vertical-align:middle;">CV_CAP_PROP_HUE</td>
        <td style="text-align:center;vertical-align:middle;">13</td>
        <td style="text-align:center;vertical-align:middle;width:514px;"> 图像的色相(仅实用于相机)</td>
    </tr><tr><td style="text-align:center;vertical-align:middle;">CV_CAP_PROP_GAIN</td>
        <td style="text-align:center;vertical-align:middle;">14</td>
        <td style="text-align:center;vertical-align:middle;width:514px;"> 图像的增益(仅实用于相机)</td>
    </tr><tr><td style="text-align:center;vertical-align:middle;">CV_CAP_PROP_EXPOSURE</td>
        <td style="text-align:center;vertical-align:middle;">15</td>
        <td style="text-align:center;vertical-align:middle;width:514px;"> 曝光(仅实用于相机)</td>
    </tr><tr><td style="text-align:center;vertical-align:middle;">CV_CAP_PROP_CONVERT_RGB</td>
        <td style="text-align:center;vertical-align:middle;">16</td>
        <td style="text-align:center;vertical-align:middle;width:514px;"> 示意图像是否应转换为 RGB 的布尔标记 </td>
    </tr><tr><td style="text-align:center;vertical-align:middle;">CV_CAP_PROP_WHITE_BALANCE</td>
        <td style="text-align:center;vertical-align:middle;">17</td>
        <td style="text-align:center;vertical-align:middle;width:514px;"> 目前不反对 </td>
    </tr><tr><td style="text-align:center;vertical-align:middle;">CV_CAP_PROP_RECTIFICATION</td>
        <td style="text-align:center;vertical-align:middle;">18</td>
        <td style="text-align:center;vertical-align:middle;width:514px;"> 平面摄像机的整流标记(留神:只有以后反对 DC1394 v 2.x 后端)</td>
    </tr></tbody></table></div>
    
  • 如果要批改分辨率就必须应用:
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() 
    
    outmasages.Camaro_image() # 调用摄像头
    
    outmasages.cap.release() # 开释对象和销毁窗口
    cv2.destroyAllWindows()
    
退出移动版