Setting frame size of QuickCam Pro 3000 with OpenCV? - c++

I'm using OpenCV 2.4.6 to grab images with my old Logitech QuickCam Pro 3000 webcam. Using VideoCapture::set( CV_CAP_PROP_FRAME_WIDTH, ... ) I'm not able to set the value of the width (idem for the height). set(...) always returns false.
Is it normal?
P.S. I'm on Linux (kubuntu) and it seems to use V4L.

It seems that your camera was not initialized properly. The following code works for me.
using namespace cv;
[...]
VideoCapture capture(0);
capture.set(CV_CAP_PROP_FRAME_WIDTH, width);
capture.set(CV_CAP_PROP_FRAME_HEIGHT, height);
I experimented with it a bit and found the following issues:
capture.set returns 0 if capture was not initialized.
capture.set returns 0 if camera is busy (another process using it).
It is not guaranteed that calling VideoCapture::set will change camera resolution to your desired resolution. For example, with my Logitech HD Pro Webcam C290, setting resolution to 640x480 and 1920x1080 works. But when I try 1024x768, VideoCapture::set returns true, but actual resolution is set to 960x720. So, check the actual resolution after reading a frame.

Related

OpenCV: Difference between cap.set(CAP_PROP_FRAME_WIDTH or CAP_PROP_FRAME_HEIGHT) and resize()

I am working on OpenCV (4.3.0) and trying to understand how I can change the resolution of the image.
To my understanding there are 2 ways that I can do this,
Using "cap.set()" function
cv::VideoCapture cap(0)
cap.set(CAP_PROP_FRAME_WIDTH, 320);//Setting the width of the video
cap.set(CAP_PROP_FRAME_HEIGHT, 240);//Setting the height of the video
Using "resize()" function,
int up_width = 600;
int up_height = 400;
Mat resized_up;
resize(image, resized_up, Size(up_width, up_height), INTER_LINEAR);
I wanted to understand if they both are the same or if they are different. What are the exact differences between them?
cap means capability of a camera. we set the required resolution before capturing from camera. If the resolution is supported only then we get a valid frame from the camera. For example a webcam might support some fixed number of resolutions like 1280x720, 640x480 etc and we can only set the cam for those resolutions.
resize is an interpolation (bilinear or bicubic or anyohter)function which resizes(upscale or downscale) a frame to any desired size.
Here is one of your question's answer. CAP_PROP_FRAME_WIDTH and CAP_PROP_FRAME_HEIGHT are some of capture properties. 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.
So if your camera backend matches with the opencv supported backends, then you will be able to change the resolution of your camera (if your camera configuration supports different resolution). For example a camera can support 640x480 and 1920x1080 at the same time. If opencv backend support this camera backend you can switch the resolution configurations by the code:
cap.set(CAP_PROP_FRAME_WIDTH, 640);
cap.set(CAP_PROP_FRAME_HEIGHT, 480);
or
cap.set(CAP_PROP_FRAME_WIDTH, 1920);
cap.set(CAP_PROP_FRAME_HEIGHT, 1080);
What about resize ?
resize() is totally different than the concept we talked above. Video properties are based on hardware, if you use a camera with 640x480 resolution. It means that camera sensor has specified perceptron cells inside for each pixel. However, resize deal with the resulted image via on software. What resize is doing is that interpolating(manipulating) image's height and width. Otherwords, it looks like you are looking at somewhere very close(zoom in) or very far(zoom out).

Can't change OpenCV video capture resolution

The problem I am having is that I am unable to change the resolution of an OpenCV video capture. The resolution is always 640x480, no matter what. The code I'm using is written in C++ and I'm using opencv 3.4.8. I've created a super simple program with which to do this and it just doesn't seem to work no matter what I try.
Here is the code in its entirety:
#include "opencv2/opencv.hpp"
using namespace cv;
int main(int argc, char** argv)
{
VideoCapture cap(0);
cap.set(CAP_PROP_FRAME_HEIGHT, 1080);
cap.set(CAP_PROP_FRAME_WIDTH, 1920);
// open the default camera, use something different from 0 otherwise;
// Check VideoCapture documentation.
if (!cap.open(0))
return 0;
for (;;)
{
Mat frame;
cap.read(frame);
if (frame.empty()) break; // end of video stream
imshow("this is you, smile! :)", frame);
if (waitKey(10) == 27) break; // stop capturing by pressing ESC
}
// the camera will be closed automatically upon exit
// cap.close();
return 0;
}
When I run the above code frame is always 640x480.
I've tried changing the resolution with cap.set() to smaller and higher resolutions. I am using an ImageSource camera and I know that the resolutions I am attempting to use are supported by the camera and I can view video at those resolutions in another program.
I've tried using different cameras/webcams.
I've tried explicitly changing the backend API when I create the VideoCapture object - i.e. VideoCapture cap(0, CAP_DSHOW). I tried DSHOW, FFMPEG, IMAGES, etc.
I've tried running the same program on different computers.
The result is always the same 640x480 resolution.
Is there something simple I am missing? Every other post I can seem to find on SO just points toward using the cap.set() to change the width and height.
It depends on what your camera backend is. As the documentation says:
Each backend supports devices properties (cv::VideoCaptureProperties)
in a different way or might not support any property at all.
Also mentioned in this documentation:
Reading / writing properties involves many layers. Some unexpected
result might happens along this chain. Effective behaviour depends
from device hardware, driver and API Backend.
It seems your camera backend is not supported by OpenCV Video I/O module.
Note: I also met such kind of cameras, some of them different resolutions are working with different numbers. For example, you may catch desired resolution by trying VideoCaptur(-1) , VideoCapture(1) , VideoCapture(2) ...
Turns out the error was in the "if(!cap.open(0))" line that I was trying to use to check if cap had successfully initialized.
I was under the impression open was just returning true if the video capture object was open or false otherwise. But it actually releases the video capture object if it is already open and then it re-opens it.
Long story short that means that the cap.set() calls that I was using to change the resolution were being erased when the object was re-opened with cap.open(0). At which point the resolution was set back to the default of 640x480.
The method I was looking for is cap.isOpened(), which simply returns true or false if the object is open. A simple, silly mistake.

Change camera resolution with OpenCV?

I am trying to set the resolution of a USB camera to 1280x720 via OpenCV using the code below:
VideoCapture Camera(0);
Camera.set(CAP_PROP_FRAME_WIDTH,(unsigned int)1280);
Camera.set(CAP_PROP_FRAME_HEIGHT,(unsigned int)720);
while(1){
Mat f;
Camera.read(f);
imshow("test cam", f);
waitKey(10);
cout<<f.size().width<<"x"<<f.size().height<<endl;
}
However the resolution is limited to 640x480. I say limited as setting the resolution lower to 320x240 does work, so I assume there could be driver/hardware limitation somewhere. I am not familier with the Pi to work it out. I can confirm the camera is capable of outputting 1280x720 and even 1920x1080 images via "fswebcam".

OpenCV recognizes my camera but cant read

I've been working on a computer vision project for a while now using the webcam of my laptop (it shows up as "HD WebCam" with 640x480 res) but want to use this program with the camera of my DJI-Inspire1 drone. The camera is recognized and opened but it fails to read images from it.
In more detail:
in my player class load camera function:
capture.open(-1); // this opens a window with a combobox showing all
//the cameras i have. Selecting the DJI camera fails
//the read while selecting the webcam fails and crashes.
// capture.open(0); opens the webcam succesfully
// capture.open(1);
open(1) seems to try to open DJI-Camera but gives different values than
open(-1) and crashes after reading a frame (the frames are entirely
black 720x480 CV_8UC3) In debug mode it crashes whie reading the frame with a Segmentation fault and points to a dissassembly of "DriverProc" (i guess?) and a line with a movdqa command.
// capture.open(2); oddly also seems to try and open DJI-camera now with
// 720x486 resolution resulting in a black 720x486 CV_8UC3 image (no crashes).
// anything above open(2) fails and crashes
if(capture.isOpened()){
// in here i check the values of different properties, they are:
// open(-1) open(1) open(2) HD WEBCAM
// CV_CAP_PROP_FORMAT = 0 -1 -1 -1
// CV_CAP_PROP_FRAME_WIDTH = 720 720 720 640
// CV_CAP_PROP_FRAME_HEIGHT = 486 480 486 480
// CV_CAP_PROP_FOURCC = 1.49883e+09 -4.66163e+08 -4.66163e08 8.44715e+08
// CV_CAP_PROP_FPS = 30 0 0 0
}
next up is in the main loop of the player class (its on its own thread)
while(!stop){
// this is the command that tries to read the next frame
if(!capture.read(frame)){
// this happens for the open(-1) version
}
}
So basically the resolution is either 720x486 or 720x480 which is very strange, there seems to be three cameras connected yet the list with capture.open(-1) shows only 2. open(2) will succefully load a black image :P. Im certain that the camera is working since i can view it in other applications such as "Livestream Studio". The Video goes from the camera to a controller (which reduces the resolution to 720 i think) wirelessly and from there to a Blackmagic design HDMI->USB3.0 converter and from there to the PC. After Intense googling i found out that the fourcc code 1.49883e+09 for the open(-1) version is indeed "2VUY" which is used by Blackmagic so that makes sense. could find what the -4.66163e08 ones mean though.
I'm using openCV 3.0.0 , minGW4.92 32bit , Qt 5.5.0
So does anyone have any ideas as to what the problem might be? I'm all out of ideas.

Getting and Setting Camera Settings

I have been searching around and can't find an example of how to get and set the camera capturing settings. For example the capturing resolution, fps, color balance, etc. I have only seen examples of how to change the settings when saving the captured video but I want to be able to find all the camera's capturing modes and choose which one I want. For example, I am using the PS3eye webcam and in the test program it allows you to change the settings (320x240 at 15,30,60,120 fps, 640x480 at 15,30,60,75 fps). So is there a function in OpenCV for getting all the camera's capture modes and choosing one? I remember in OpenFrameworks there was a function to change these settings but I would like to know how to do it in OpenCV.
Here is the code for OpenFrameworks with OpenCV that does sort of what I want:
vidGrabber.setDeviceID( 4 );
vidGrabber.setDesiredFrameRate( 30 ); //I want this
vidGrabber.videoSettings();
vidGrabber.setVerbose(true);
vidGrabber.initGrabber(320,240); //And this
cvSetCaptureProperty()
with these flags:
CV_CAP_PROP_FRAME_WIDTH - width of frames in the video stream (only for cameras)
CV_CAP_PROP_FRAME_HEIGHT - height of frames in the video stream (only for cameras)
CV_CAP_PROP_FPS - frame rate (only for cameras)
I built a Directshow camera library which able to acquire the camera resolutions and properties.
https://github.com/kcwongjoe/directshow_camera
The fps is usually depended on your machine, resolution and exposure time. To change the fps, you can modify the exposure time in a fixed resolution.