Resolution Issues When Setting Video Capture Device

asked 2020-11-01 08:14:19 -0600

slalomchip gravatar image

I’m getting odd behavior when setting the capture dimensions for an HD video signal when using two different capture cards. I have an AHD video camera set to 1920x1080p @ 30fps. I have two different EZCAP USB3 video capture devices: EZCAP267 (AHD-to-USB3) EZCAP311 (HDMI-to-USB3 with an AHD-to-HDMI converter. The converter outputs at 1920x1080 @ 30fps)

If I don’t set the width and height captured, the EZCAP311 captures the video stream at 1920x1080 but the EZCAP267 captures it at 640x480 (black borders top and bottom so that the image still has an aspect ratio of 16:9)

I then played around with setting the capture devices. In all cases, the EZCAP311 captured at 1920x1080, but the EZCAP267 captured at unexpected dimensions. Here are the EZCAP267 results:

  • No setting: 640x480 (4:3 aspect ratio with black borders top and bottom)
  • Set to 1920x1080. Achieved 1027x768 (4:3 aspect ratio with the black borders top and bottom)
  • Set to 2048x1152. Achieved 1280x720 (16:9 aspect ratio)
  • Set to 2560x1400. Achieved 1360x768 (16:9 aspect ratio)
  • Set to 3840x2160. Achieved 1920x1080 (16:9 aspect ratio)

Does anyone know why the capture dimensions are not what I expect and why the capture dimensions need to be set for one capture device but not the other one?

I’m running OpenCV 3.4.2 in Python 3.7 on a Windows 10 platform. Both capture devices are compatible with DirectShow and require no Windows drivers. Here is my script:

import cv2

cap = cv2.VideoCapture(0)

cap.set(cv2.CAP_PROP_FRAME_WIDTH, 2048)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1152)

frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
print('Width x Height = ', frame_width, 'x', frame_height)

while(True):
    ret, frame = cap.read()
    cv2.imshow('frame',frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()
edit retag flag offensive close merge delete

Comments

btw,

cap = cv2.VideoCapture(0)

will probably use the MSMF backend (default), so try again with

 cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)

to see, if it makes any difference.

but frankly, you're at the mercy of your hw/driver vendors, the underlying backends and the os here, there's not much you can do from the opencv side.

berak gravatar imageberak ( 2020-11-01 09:44:32 -0600 )edit

@berak - I tried your suggestion and received the error "TypeError: VideoCapture() takes at most 1 argument (2 given)". The OpenCV allows it using C++ and I've found references to it using Python and the old cv (vs cv2) package. I've found other discrepancies that the cv package supported but apparently are no longer supported in cv2. Thanks. Any other suggestions?

slalomchip gravatar imageslalomchip ( 2020-11-01 17:59:25 -0600 )edit

OpenCV 3.4.2

very very outdated, update to recent 3.4.12, please.

(and indeed, i missed it -- that version will not let you specify a certain backend)

berak gravatar imageberak ( 2020-11-02 01:55:04 -0600 )edit

@berak - I updated OpenCV. The OpenCV package for Anaconda is 3.4.2 - I don't know why it is so old. Also, I didn't realize MSMF is the default backend. After setting the backend to DirectShow, I never got better resolution than 648x480 with the EZCAP267 but always got 1920x1080 with the EZCAP311. Furthermore, my webcam never got better that 640x480 with the DirectShow but got up to 1280x720 with the MSMF. But I don't understand why I need to set the dimensions height than 1920x1080 to get 1920x1080. Likewise, for the webcam I need to set the dimensions to 2560x1440 to achieve 1280x720 resolution. As you mentioned - probably a driver issue. As long as I got it to work OK, I'm content. Thanks for the help!

slalomchip gravatar imageslalomchip ( 2020-11-02 19:38:29 -0600 )edit