OpenCV (via python) on Linux: Set frame width/height? - python

I'm using openCV via python on linux (ubuntu 12.04), and I have a logitech c920 from which I'd like to grab images. Cheese is able to grab frames up to really high resolutions, but whenever I try to use openCV, I only get 640x480 images. I have tried:
import cv
cam = cv.CaptureFromCAM(-1)
cv.SetCaptureProperty(cam,cv.CV_CAP_PROP_FRAME_WIDTH,1920)
cv.SetCaptureProperty(cam,cv.CV_CAP_PROP_FRAME_WIDTH,1080)
but this yields output of "0" after each of the last two lines, and when I subsequently grab a frame via:
image = cv.QueryFrame(cam)
The resulting image is still 640x480.
I've tried installing what seemed to be related tools via (outside of python):
sudo apt-get install libv4l-dev v4l-utils qv4l2 v4l2ucp
and I can indeed apparently manipulate the camera's settings (again, outside of python) via:
v4l2-ctl --set-fmt-video=width=1920,height=1080,pixelformat=1
v4l2-ctl --set-parm=30
and observe that:
v4l2-ctl -V
indeed suggests that something has been changed:
Format Video Capture:
Width/Height : 1920/1080
Pixel Format : 'H264'
Field : None
Bytes per Line : 3840
Size Image : 4147200
Colorspace : sRGB
But when I pop into the python shell, the above code behaves exactly the same as before (printing zeros when trying to set the properties and obtaining an image that is 640x480).
Being able to bump up the resolution of the capture is pretty mission critical for me, so I'd greatly appreciate any pointers anyone can provide.

From the docs,
The function cvSetCaptureProperty sets the specified property of video capturing. Currently the function supports only video files: CV_CAP_PROP_POS_MSEC, CV_CAP_PROP_POS_FRAMES, CV_CAP_PROP_POS_AVI_RATIO .
NB This function currently does nothing when using the latest CVS download on linux with FFMPEG (the function contents are hidden if 0 is used and returned).

I had the same problem as you. Ended up going into the OpenCV source and changing the default parameters in modules/highgui/src/cap_v4l.cpp, lines 245-246 and rebuilding the project.
#define DEFAULT_V4L_WIDTH 1920
#define DEFAULT_V4L_HEIGHT 1080
This is for OpenCV 2.4.8

It seems to be variable by cammera.
AFIK, Logitech cameras have particularly bad linux support (though It;s gotten better) Most of their issues are with advanced features like focus control. i would advise sticking with basic cameras (IE manual focus Logitech cameras) just to play it safe.
My built in laptop camera has no issue and displays at normal resolution.
My external logitech pro has issues initalizing.
However, I can overcome the resolution issue with these two lines.
Yes, they are the same as you used.
cv.SetCaptureProperty(self.capture,cv.CV_CAP_PROP_FRAME_WIDTH, 1280)
cv.SetCaptureProperty(self.capture,cv.CV_CAP_PROP_FRAME_HEIGHT, 720)
My Logitech still throws errors but the resolution is fine.
Please make sure the resolution you set is a supported by your camera or v4l will yell at you. If I set an unsupported native resolution, I have zero success.

Not sure if it works, but you can try to force the parameters to your values after you instantiate camera object:
import cv
cam = cv.CaptureFromCAM(-1)
os.system("v4l2-ctl --set-fmt-video=width=1920,height=1080,pixelformat=1")
os.system("v4l2-ctl --set-parm=30")
image = cv.QueryFrame(cam)
That's a bit hacky, so expect a crash.

## Sets up the camera to capture video
cap = cv2.VideoCapture(device)
width = 1280
height = 720
#set the width and height
cap.set(3,width)
cap.set(4,height)

Related

Setting camera width / height (field of view) opencv while streaming images works with Windows but not Linux

I am writing a python app that utilizes opencv to display an image using pyqt. I wrote the application on windows originally using DirectShow camera API preference. When the camera was displayed I could set the width/height of the camera easily using the opencv API cap.set(3, X) cap.set(4, y). I need to shrink these values in order to boost the FPS of my camera I am using.
However, I just moved my code over to Ubuntu and everything works exactly the same except as soon as I change the FOV values, the camera freezes and I no longer can get frames. I am able to change other camera features like brightness, contrast, etc, but for some reason the width/height is a problem.
I tried different API preferences: CAP_V4L2, CAP_V4L, CAP_GSTREAMER. None of these allowed me to edit it on the fly while streaming images.
Any ideas why the change?

OpenCV changing VideoCapture resolution causes colour issues and glitches

I want to capture 1920x1080 video from my camera but I've run into two issues
When I initialize a VideoCapture, it changes the width/height to 640/480
When I try to change the width/height in cv2, the image becomes messed up
Images
When setting 1920x1080 in cv2, the image becomes blue and has a glitchy bar at the bottom
cap = cv2.VideoCapture('/dev/video0')
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
Here's what's happening according to v4l2-ctl. The blue image doesn't seem to be a result of a pixelformat change (eg. RGB to BGR)
And finally, here's an example of an image being captured at 640x480 that has the correct colouring. The only difference in the code is that width/height is not set in cv2
Problem:
Actually the camera you are using has 2 mode:
640x480
1920x1080
One is for main stream, one is for sub stream. I also met this problem couple of times and here is the possible reasons why it doesn't work.
Note: I assume you tried different ways to run on full resolution(1920x1080) such as cv2.VideoCapture(0) , cv2.VideoCapture(-1) , cv2.VideoCapture(1) ...
Possible reasons
First reason could be that the camera doesn't support the resolution you desire but in your case we see that it supports 1920x1080 resolution. So this can not be the reason for your isssue.
Second reason which is general reason is that opencv backend doesn't support your camera driver. Since you are using VideoCaptureProperties of opencv, Documentation says:
Reading / writing properties involves many layers. Some unexpected result might happens along this chain. Effective behaviour depends from device hardware, driver and API Backend.
What you can do:
In this case, if you really need to reach that resolution and make compatible with opencv, you should use the SDK of your camera(if it has).

Is there a way to adjust shutter speed or exposure time of a webcam using Python and OpenCV

In my robotic vision project, I need to detect a marker of a moving object but motion causes blurring effect in the image. Deconvolution methods are quite slow. So I was thinking to use a higher fps camera. Someone said I don't need higher fps, instead I need shorter exposure time.
OpenCV's Python Interface cv2 provides a method to change the settings of camera but it does not include "Exposure Time" or "Shutter Speed" settings. I'm also afraid that webcams don't even support this kind of settings.
Any other thoughts about:
Eliminating blurring effect using camera setting?
OR
Restoration of Image with real-time performance?
OR
Any suggestion about a low cost camera for real-time robotic applications?
There is a method available to change properties of VideoCapture object in OpenCV which can be used to set exposure of input image.
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_EXPOSURE, 40)
However this parameter is not supported by all cameras. Each camera type offers a different interface to set its parameters. There are many branches in OpenCV code to support as many of them, but of course not all the possibilities are covered.
Same is the case with my camera. So I had to find a different solution. That is using v4l2_ctl utility from command line terminal.
v4l2-ctl -d /dev/video0 -c exposure_absolute=40
But this retains its value for current video session only. That means you have to start video preview first and then set this property As soon as VideoCapture is released, the exposure value is restored to default.
I wanted to control exposure within my python script, so I used subprocess module to run linux bash command. e.g.
import subprocess
subprocess.check_call("v4l2-ctl -d /dev/video0 -c exposure_absolute=40",shell=True)
For instance
I was trying with a c920 for a while whithout success, but sometimes worked, other not using this:
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_EXPOSURE, -4)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240) # after not change the exposure
But finally I realized that I was setting the width and height just after, and so I change the order and now is working fine!! Don´t blow your mind trying to disable the CAP_PROP_AUTO_EXPOSURE flag!! Its not necessary(at least with c920 on windows)!!
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240) # before works fine
cap.set(cv2.CAP_PROP_EXPOSURE, -4)
By the way, the range of exposure in C920 is from -2 to -11!!(on windows 10)
Thanks a lot

How to manually set exposure on a Facetime HD camera in Python opencv 3.2.0 OSX El Capitan

I am trying to figure out how to manually set the exposure for my Facetime HD camera in the opencv program I am writing in Python. I am using opencv version 3.2.0, python 2.7, and running on OSX El Capitan.
I am writing a program which will take a photograph from the webcam every n seconds and write it to the disk. From what I have seen in the documentation, I would want to use this method to set the exposure on my camera.
cv2.VideoCapture.set(CV_CAP_PROP_EXPOSURE, value) → retval
After some tinkering and looking around online, I found I was able to access that camera property in my version of opencv using the following:
cv2.CAP_PROP_EXPOSURE
What is strange, is that in my function which actually captures the photograph, I can see that the default exposure value is 0.0, and then when I go to change it with the set method, the exposure hasn't changed when I check the value again. It would appear that the set method is simply not working.
Here is my function:
def takePhoto():
cam = cv2.VideoCapture(0)
print(cam.get(cv2.CAP_PROP_EXPOSURE)) #this prints out 0.0
cam.set(cv2.CAP_PROP_EXPOSURE, 0.5)
print(cam.get(cv2.CAP_PROP_EXPOSURE)) #this also prints out 0.0, despite the use of set() in the line above
s, im = cam.read() # captures image
cv2.imwrite("test.jpg",im) # writes image test.jpg to disk
cam.release()
Is it just the case that this camera is not compatible with manual exposure control? I have also read in one or two places that opencv in OSX does not allow for manually controlling properties of cameras. Is that what's wrong here? Or am I using the set method improperly? I just really need to be able to manually control exposure, as the photos taken by my program are consistently underexposed.
Thanks,
Brian
I don't have a FacetimeHD Camera but I guess you need to set the exposure mode to manual (disable auto exposure) using
cam.set(cv2.CAP_PROP_AUTO_EXPOSURE, 0)

Unable to change frame height, width in OpenCV

I'm using the OpenCV python bindings to put together a quick script/prototype, but for some odd reason,
camera.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 640.0)
...does nothing at all. By this, I mean it returns True, but the frame height is constant. No, returning a constant is not a fault, as camera.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT) will return 240.0 as the default value.
I don't have any clue on why is this failing. Any ideas?
For what it's worth, I'm running this code on windows 8.1.
It's often not possible to change the camera settings through openCV.
It depends on how well the camera implements the interface to Microsoft's Directshow.
Since Directshow is difficult to understand, poorly documented and hard to test and cameras are cheaply made.....
You have to set both WIDTH and HEIGHT in order to change camera resolution. Some says that changing the height automatically adjusts the width, but this did not worked for me.
See my other answer on this topic.

Categories

Resources