33

I am trying to acquire images from my webcam using a python code that imports OpenCV. The code is the following:

import sys
sys.path.append("C:\\opencv\\build\\python\\2.7")
import cv2
import cv2.cv as cv
import time

# Set resolution
cap = cv2.VideoCapture(0)
print "Frame default resolution: (" + str(cap.get(cv.CV_CAP_PROP_FRAME_WIDTH)) + "; " + str(cap.get(cv.CV_CAP_PROP_FRAME_HEIGHT)) + ")"
cap.set(cv.CV_CAP_PROP_FRAME_WIDTH, 800)
cap.set(cv.CV_CAP_PROP_FRAME_HEIGHT, 600)
print "Frame resolution set to: (" + str(cap.get(cv.CV_CAP_PROP_FRAME_WIDTH)) + "; " + str(cap.get(cv.CV_CAP_PROP_FRAME_HEIGHT)) + ")"

# Acquire frame
capture = cv.CreateCameraCapture(0)
img = cv.QueryFrame(capture)

The code works fine, except that the Camera default resolution is 640x480, and my code seems to be able to set only resolution values lower than that. For example, I can set the image size to 320x240, but I can't change it to 800x600. I have no error appearing: simply the resolution is set to the default one (640x480) as I try to set it to higher values.

The camera I am using (no other webcam is connected to the computer) is the QuickCam V-UBK45: with the software provided by Logitech, I am able to take pictures at full resolution (1280x960) and at all intermediate ones (e.g. 800x600).

Therefore, those frame sizes are supported from the hardware, but my code can't access them.

Does anyone know what I can do?

Ste
  • 339
  • 1
  • 3
  • 3
  • 1
    does the camera capture *video* at 640x480 in other applications? – loopbackbee Oct 18 '13 at 11:05
  • what @goncalopp said, made me think, that they might restrict the resolution for *video streams* ( bandwidth ) in the driver, while their application is still able to take *single* pics at higher rez. – berak Oct 18 '13 at 11:26
  • Do you know the code for this in cv2, as in don't mix cv and cv2. Any ideas? – praxmon Feb 13 '14 at 12:51

7 Answers7

33

The problem as mentioned above is caused by the camera driver. I was able to fix it using Direct Show as a backend. I read (sorry, but I do not remember where) that almost all cameras provide a driver that allows their use from DirectShow. Therefore, I used DirectShow in Windows to interact with the cameras and I was able to configure the resolution as I wanted and also get the native aspect ratio of my camera (16:9).

You can try this code to see if this works for you:

import cv2

cap = cv2.VideoCapture(0, cv2.CAP_DSHOW) # this is the magic!

cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)

r, frame = cap.read()
...
print('Resolution: ' + str(frame.shape[0]) + ' x ' + str(frame.shape[1]))

In the OpenCV documentation, I found the following information for those who want to know more about OpenCV backends (OpenCV docs)

I hope this can help you!

Ian Kemp
  • 28,293
  • 19
  • 112
  • 138
JoeyGutMen
  • 377
  • 3
  • 7
17

I used the different resolutions to set image resolution from List of common resolutions by looping over

def set_res(cap, x,y):
    cap.set(cv.CV_CAP_PROP_FRAME_WIDTH, int(x))
    cap.set(cv.CV_CAP_PROP_FRAME_HEIGHT, int(y))
    return str(cap.get(cv.CV_CAP_PROP_FRAME_WIDTH)),str(cap.get(cv.CV_CAP_PROP_FRAME_HEIGHT))

It seems that OpenCV or my camera allows only certain resolutions.

  • 160.0 x 120.0

  • 176.0 x 144.0

  • 320.0 x 240.0

  • 352.0 x 288.0

  • 640.0 x 480.0

  • 1024.0 x 768.0

  • 1280.0 x 1024.0

vwvw
  • 372
  • 4
  • 16
duggi
  • 556
  • 5
  • 13
9

I got it to work, so this post is for others experiencing the same problem:

I am running on the Logitech C270 as well. For some reason it would only show 640x480 even though the webcam supports 1280x720. Same issue persists with the built-in webcam in my laptop.

If I set it to 800x600 in the code it shows 640x480. However, if I set it to 1024x768 it becomes 800x600. And if I set it to something silly like 2000x2000 it becomes 1280x720.

This is in C++ on OpenCV 3.0, but perhaps it applies to Python as well.

ubehagelig
  • 173
  • 1
  • 2
  • 7
  • 2
    This is correct, trying `(7680, 4320)` gives `(1280.0, 720.0)` to me, which is my camera's max resolution. – Rockybilly Oct 22 '17 at 18:43
4

Try the following code to obtain the maximum camera resolution, using this you can capture your photos or video using maximum resolution:

import cv2

HIGH_VALUE = 10000
WIDTH = HIGH_VALUE
HEIGHT = HIGH_VALUE

capture = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
capture.set(cv2.CAP_PROP_FRAME_WIDTH, WIDTH)
capture.set(cv2.CAP_PROP_FRAME_HEIGHT, HEIGHT)
width = int(capture.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(capture.get(cv2.CAP_PROP_FRAME_HEIGHT))

print(width,height)
Elijan9
  • 1,269
  • 2
  • 17
  • 18
PRASAD
  • 51
  • 4
1

For cv2 just change to this.

    cap.set(cv2.CAP_PROP_FRAME_WIDTH, 800)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 600)
1

OpenCV now only allows only these Resolutions.

  1. '320.0x240.0': 'OK'
  2. '640.0x480.0': 'OK'
  3. '1280.0x720.0': 'OK'

Source: https://www.learnpythonwithrune.org/find-all-possible-webcam-resolutions-with-opencv-in-python/

These are the common resolutions. It may support some more resolutions, you can check. If you can not find the supported resolution. You can also use:

frame = imutils(frame, width = 720)

This will set you to the nearer supported resolution. Note: use you required value for the width and will set it to the nearer supported resolution and then you can check the supported resolution by using:

print(frame.shape)

imutils method is completely based on experience and testing around.

Yash
  • 11
  • 6
0

Here is what I was able to use

import cv2
import platform
index = 0 # capture device index

if platform.system() == "Windows":
    cv2.CAP_DSHOW
    #sets the Windows cv2 backend to DSHOW (Direct Video Input Show)
    cap = cv2.VideoCapture(index)
elif platform.system() == "Linux":
    cv2.CAP_GSTREAMER # set the Linux cv2 backend to GTREAMER
    #cv2.CAP_V4L
    cap = cv2.VideoCapture(index)
else:
    cap = cv2.VideoCapture(index)
    # For MAC please refer to link below for I/O
    cap.set(cv2.CAP_FFMPEG, cv2.CAP_FFMPEG_VIDEOTOOLBOX) # not sure!
    #please refer to reference link at bottom of page for more I/O

cap.set(cv2.CAP_PROP_FRAME_WIDTH, 3840) # 4k/high_res
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 2160) # 4k/high_res
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
print(width, height)

_, frame = cap.read()
height, width = frame.shape[:2]
print(width, height)

cap.release()
#while True:
    #pass if your terminal closes automatically
Dean
  • 11
  • 3