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".
Related
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).
I am trying to develop an application using OpenCV. I got a Raspberry Pi Camera 3 (Raspicam 3) now. I am trying to migrate my code from standart version with Webcam to Raspicam version using the API found at https://www.uco.es/investiga/grupos/ava/node/40.
What I did is simply convert:
cv::Mat image;
VideoCapture cap(0); // open the default camera
cap >> image;
cap.release();
into
cv::Mat image;
raspicam::RaspiCam_Cv Camera;
Camera.set( CV_CAP_PROP_FORMAT, CV_8UC3 );
Camera.grab();
Camera.retrieve ( image);
Camera.release();
Now the photo I took has really weird colors (seems like inverted) when I try to see it with
cv::imwrite("myimg.jpg",image);
The difference I notice is that raspberry pi camera API sets this value:
Camera.set( CV_CAP_PROP_FORMAT, CV_8UC1 );
However this value causes program to crash,
so I either use
Camera.set( CV_CAP_PROP_FORMAT, CV_8UC3 );
or
Camera.set( CV_CAP_PROP_FORMAT, CV_BGR2HSV );
Then, it does not crash but the colors are weird looking. (e.g. Orange is blue)
The question is, how do I prevent this color change? How do I set up camera with right parameters so that it takes a normal photo?
I should let you know that I dont know OpenCV in detail, just trying to figure these things out.
Thanks in advance for any help.
Cheers,
EDIT:
When I comment the line
Camera.set( CV_CAP_PROP_FORMAT, CV_8UC1 );
Everything is also blue-ish. So I guess it does not have anything to do with it.
EDIT: Added error details.
Have you checked if the color space of your Raspberry Pi is the same as Open CV?
Open CV uses the Blue Green Red (BGR) convention, which is not that frequent. It might correspond to your "blue-ish" description...
If so, just swap the first and last channels to get RGB values :)
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.
I'm trying to capture the raw data of the logitech pro 9000 (eg. the so called Bayer pattern). This can be achieved by using the so called bayer application, that can be found floating over the internet. It should return a 8 bit bayer pattern, but the results are quite obviously not such a pattern.
However; The image that is being streamed seems to be quite off. As can be seen in the image below, I get 2 images of the scene in a 3 channel image (meaning 6 channels in total). Each image is 1/4th of the total capture area, so it would seem that there is some kind of YUV data being streamed.
I was unable to convert this data into anything meaningful using the conversions provided by openCV. Any ideas what kind of data is being sent and (more importantly) how to convert this into RGB?
EDIT
As requested; the codesnippet that is used to generate the image.
system("Bayer.exe 1 8"); //Sets the camera to raw mode
// set up camera
VideoCapture capture(0);
if(!capture.isOpened()){
waitKey();
exit(0);
}
Mat capturedFrame;
while(true){
capture>>capturedFrame;
imshow("Raw",capturedFrame);
waitKey(25);
}
How did you get frames from stream using openCV? Can you share some code snippets? There are too many video formats in openCV for getting correct color channel and compressed data.
I think you should be able to obtain correct image frames as mentioned here :
http://forum.openrobotino.org/archive/index.php/t-295.html?s=c33acb1fb91f5916080f8dfd687598ec
This is most likely to happen if the out put data format ( width, height, bit depth, no of channels...) of camera and the data format your program expect is different.
However i could capture of logitec pro cam, simply by using
Mat img;
VideoCapture cap(0);
cap >> img;
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.