简体   繁体   English

USB摄像头:OpenCV VideoCapture返回部分帧

[英]USB Camera: OpenCV VideoCapture Returns Partial Frames

I am developing a program to process frames from a USB camera on Ubuntu. 我正在开发一个程序来处理Ubuntu上USB摄像头的帧。 Currently I'm using OpenCV in python. 目前我在python中使用OpenCV。 When I try to read a frame using a cv2.VideoCapture object I only get partial frames . 当我尝试使用cv2.VideoCapture对象读取帧时,我只获得部分帧

The camera I'm using is a Kayeton GS1M2812 USB camera, which claims to be UVC compliant. 我正在使用的相机是Kayeton GS1M2812 USB相机,声称符合UVC标准。 Most applications (like cheese, for instance) list the camera among available webcams, but don't display any frames. 大多数应用程序(例如奶酪)将相机列在可用的网络摄像头中,但不显示任何帧。 Google Hangouts, on the other hand, can display live frames from the camera without a problem. 另一方面,Google Hangouts可以毫无问题地显示来自相机的实时帧。

I can also successfully capture images and video using streamer . 我也可以使用streamer成功捕获图像和视频。 eg: 例如:

streamer -c /dev/video1 -o capture.jpg

Initially when I tried to use cv.VideoCapture , I got select timeouts and no images. 最初,当我尝试使用cv.VideoCapture ,我得到了选择超时而没有图像。 After some research I found that restarting the uvcvideo module with nodrop=1 allowed me to at least get partial frames from opencv (like the one linked above). 经过一些研究后,我发现用nodrop=1重新启动uvcvideo模块让我至少可以从opencv获得部分帧(就像上面链接的那样)。

I tried setting the uvcvideo timeout param to a ridiculously large value and messed with all the other params and various quirks, but to no avail. 我尝试将uvcvideo超时参数设置为一个非常大的值,并与所有其他参数和各种怪癖混淆,但无济于事。

I did find that changing the resolution ( cv.CAP_PROP_FRAME_WIDTH and cv.CAP_PROP_FRAME_HEIGHT ) to 320x240 or smaller before each call to read() results in capturing a full frame, but anything larger doesn't. 我确实发现在每次调用read()之前将分辨率( cv.CAP_PROP_FRAME_WIDTHcv.CAP_PROP_FRAME_HEIGHT )更改为320x240或更小会导致捕获一个完整的帧,但是任何更大的帧都不会。

I've also tried changing various parameters with v4l2-ctl , but that hasn't worked either. 我也尝试用v4l2-ctl更改各种参数,但这也没有用。

What can I do to fix this? 我该怎么做才能解决这个问题?

Here is my python code: 这是我的python代码:

import cv2 as cv
import numpy as np
import sys

if len(sys.argv) != 2:
    print("invalid arguments")
    sys.exit()

camNo = int(sys.argv[1])
print("opening camera %d" % camNo)

cap = cv.VideoCapture(camNo)

print("done")

while True:
    cap.set(cv.CAP_PROP_FRAME_WIDTH,640);
    cap.set(cv.CAP_PROP_FRAME_HEIGHT,480);
    ret, frame = cap.read()
    print(ret)

    if(frame is None):
        print("Received empty frame. Exiting")
        sys.exit()

    cv.imshow('frame', frame)
    if cv.waitKey(30) & 0xFF == ord('q'):
        break

cap.release()
cv.destroyAllWindows()

This code works correctly when I use my laptop's builtin webcam (usually /dev/video0 ), but displays partial frames when I use the USB camera. 当我使用笔记本电脑的内置网络摄像头(通常是/dev/video0 )时,此代码可正常工作,但在使用USB摄像头时显示部分帧。

I am using python 2.7.12 and opencv 3.3.1 on Ubuntu 16.04 我在Ubuntu 16.04上使用python 2.7.12和opencv 3.3.1

Probably by default opencv is requesting uncompressed images from your webcam. 可能默认情况下,opencv会从您的网络摄像头请求未压缩的图像。 That's why when you reduce the resolution or FPS you get a full image otherwise the bandwidth is insufficient for the whole image. 这就是为什么当你降低分辨率或FPS时你得到一个完整的图像,否则带宽不足以满足整个图像。

You can try setting the codec cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*'MJPG')) . 您可以尝试设置编解码器cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*'MJPG'))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM