How to set camera FPS in OpenCV? CV_CAP_PROP_FPS is a fake - opencv

How to set Camera FPS?
May be
cvSetCaptureProperty(cameraCapture, CV_CAP_PROP_FPS, 30);
?
But it's return
HIGHGUI ERROR: V4L2: Unable to get property (5) - Invalid argument
Because there is no implementation in highgui/cap_v4l.cpp
static int icvSetPropertyCAM_V4L( CvCaptureCAM_V4L* capture,
int property_id, double value ){
static int width = 0, height = 0;
int retval;
/* initialization */
retval = 0;
/* two subsequent calls setting WIDTH and HEIGHT will change
the video size */
/* the first one will return an error, though. */
switch (property_id) {
case CV_CAP_PROP_FRAME_WIDTH:
width = cvRound(value);
if(width !=0 && height != 0) {
retval = icvSetVideoSize( capture, width, height);
width = height = 0;
}
break;
case CV_CAP_PROP_FRAME_HEIGHT:
height = cvRound(value);
if(width !=0 && height != 0) {
retval = icvSetVideoSize( capture, width, height);
width = height = 0;
}
break;
case CV_CAP_PROP_BRIGHTNESS:
case CV_CAP_PROP_CONTRAST:
case CV_CAP_PROP_SATURATION:
case CV_CAP_PROP_HUE:
case CV_CAP_PROP_GAIN:
case CV_CAP_PROP_EXPOSURE:
retval = icvSetControl(capture, property_id, value);
break;
default:
fprintf(stderr,
"HIGHGUI ERROR: V4L: setting property #%d is not supported\n",
property_id);
}
/* return the the status */
return retval;
}
How to solve it?

using the python wrappers for opencv, it worked for me to refer to the variable as:
cap = cv2.VideoCapture(1)
cap.set(cv2.cv.CV_CAP_PROP_FPS, 60)
I am using python 2.7.3 and opencv 2.4.8
The camera is the PS3 Eye

I don't know if that's still valid, but some time ago, something like one year and a half, I encountered that exactly problem. I contacted with a developer of OpenCV and he told me that the access and ability to change some of the properties of a capture weren't implemented yet and some other just worked for certain kinds of camera. I finally took a look to libdc1394 (working in linux) and made some functions that converted the data retrieved by libdc1394 to IplImages from OpenCV. It wasn't a such a tough task.

CV_CAP_PROP_FPS is a NOT a fake. See cap_libv4l.cpp(1) in OpenCV github repo. The key is to make sure, you use libv4l over v4l while configuring OpenCV. For that, before running cmake, install libv4l-dev
sudo apt-get install libv4l-dev
Now while configuring OpenCV with cmake, enable option, WITH_LIBV4L. If all goes good, in configuration status, you will see some thing similar to below
V4L/V4L2: Using libv4l1 (ver ) / libv4l2 (ver )
And then while building your OpenCV code, you will have to link with libv4l1/libv4l2/libv4lconvert.
Arbitary FPS values at the resolutions you choose, needn't be supported by your webcam. You may check supported resolutions/fps with a graphical tools like cheese or commands like lsusb (2)

check opencv2.4 handbook out, the video capture thing is much better than before,
->set(CV_CAP_PROP_FPS,30);works for me most of the times.
but a little bit low efficiency.
just in case you might not like the new opencv2.4 and still want to control your camera. check the videoinput lib here. it works good and using directshow features.
http://www.aishack.in/2010/03/capturing-images-with-directx/
http://www.muonics.net/school/spring05/videoInput/

Related

libtiff: TIFFGetField returns incorrect image' width and height

I have a tiff file with 1736x1160x48b resolution. I'm using libtiff 4.0 dll and I have noticed that the resolution being read from the TIFFGetField function is incorrect. I'm getting 156 width and 104 height which is too low.
TIFF* pTiff;
pTiff = dll.OpenTIFF(szFilePath, (char*)("r"));
if (pTiff == nullptr) {
return LPROCESS_FAILED;
}
uint32_t uWidth = 0;
uint32_t uHeight = 0;
int ret = 0;
ret = dll.TIFFGetField(pTiff, TIFFTAG_IMAGEWIDTH, &uWidth);
ret = dll.TIFFGetField(pTiff, TIFFTAG_IMAGELENGTH, &uHeight );
// ret value is 1 on both lines
Do I need to update my tiff library to 4.5? Is there a fix on the latest version? or is this a format error on the image side? Though when I try to open the image on other photo viewing application, it was able to interpret correctly.
Update: I used libtiff 4.5 latest release and I'm still getting incorrect width and height. My guess is that the image I'm trying to load is not yet fully supported by libtiff. Here is the details of the image from exiftool:

GpuMat to FFMPEG Encoder

I'm doing some image processing with opencv::cuda so what I end up with is a cv::cuda::GpuMat. I now want to encode it using ffmpeg(so I can choose the encoder to be hardware accelerated or not). Now I wonder if i can somehow keep the data on the GPU for the encoder without downloading it, because that seems to be the bottleneck in my application running multiple threads.
I'm resizing the images with Opencv CUDA so I have less to download. (resizing with sws_scale makes no difference)
cv::cuda::GpuMat currentFrame;
...
cv::cuda::GpuMat resized;
cv::cuda::resize(currentFrame,resized,cv::Size(width*0.75,height*0.75),0,0,cv::INTER_NEAREST);
cv::Mat frameEnc = cv::Mat(resized);
const int stride[] = { static_cast<int>(frameEnc.step[0]) };
sws_scale(swsctx, &frameEnc.data, stride, 0, frameEnc.rows, avframe->data, avframe->linesize);
ret = avcodec_send_frame(codec, avframe);
if(!ret) {
/* rescale packet timestamp */
pkt->duration = 1;
av_packet_rescale_ts(pkt, codec->time_base, vstrm->time_base);
/* write packet */
av_write_frame(outctx, pkt);
}
Now this does work and performs ok, but I really wish I could do something like:
cv::cuda::GpuMat currentFrame;
...
GpuMatToAvFrame(currentFrame,avframe);
ret = avcodec_send_frame(codec, avframe);
if(!ret) {
/* rescale packet timestamp */
pkt->duration = 1;
av_packet_rescale_ts(pkt, codec->time_base, vstrm->time_base);
/* write packet */
av_write_frame(outctx, pkt);
}
where the avframe data is also on the gpu so that I don't download need any transfer between GPU-CPU/CPU-GPU
I think the class cv::cudacodec::VideoWriter could help, once an issue with OpenCV gets fixed. The class allows you to write a GpuMat directly. However I believe that due to a bug in OpenCV, you can't build OpenCV with support for this class. Which means this isn't a great solution now, but might be in the future.

Compare Images From Pylon GigE Camera Video Feed using absdiff

I'm trying to grab two pictures from an basler GigE camera video feed with pylon and opencv. The two pictures are converted to grayscale and compared using absdiff. The pixels that have changed should be the object i'm looking for.
Here is the while-loop of the code.
while(camera.IsGrabbing()) {
camera.RetrieveResult(5000,ptrGrabResult, TimeoutHandling_ThrowException);
if(ptrGrabResult->GrabSucceeded()){
formatConverter.Convert(pylonImage, ptrGrabResult);
openCVImage1 = cv::Mat(ptrGrabResult->GetHeight(), ptrGrabResult->GetWidth(), CV_8UC3, (uint8_t *) pylonImage.GetBuffer());
}
else{
cout<<"ERROR OpenCVImage1:" <<ptrGrabResult->GetErrorCode()<<ptrGrabResult->GetErrorDescription()<< endl;
}
camera.RetrieveResult(5000,ptrGrabResult, TimeoutHandling_ThrowException);
if(ptrGrabResult->GrabSucceeded()){
formatConverter.Convert(pylonImage, ptrGrabResult);
openCVImage2 = cv::Mat(ptrGrabResult->GetHeight(), ptrGrabResult->GetWidth(), CV_8UC3, (uint8_t *) pylonImage.GetBuffer());
}
else{
cout<<"ERROR OpenCVImage2:" <<ptrGrabResult->GetErrorCode()<<ptrGrabResult->GetErrorDescription()<< endl;
}
cvtColor(openCVImage1,grayImage1,CV_BGR2GRAY);
cvtColor(openCVImage2,grayImage2,CV_BGR2GRAY);
absdiff(grayImage1,grayImage2,differenceImage);
imshow("DiffImage", differenceImage);
threshold(differenceImage,thresholdImage,sensitivity, 255, THRESH_BINARY);
switch(waitKey(10)){
case 27: //ESC
return 0;
case 116: //t
trackingEnabled = !trackingEnabled;
if(trackingEnabled=false) cout<<"tracking disabled"<<endl;
else cout<<"tracking enabled"<<endl;
break;
case 112: //d
debugMode=!debugMode;
if(debugMode==false){cout<<"Code paused, press 'p' again to resume"<<endl;
while (pause==true) {
switch(waitKey(0)){
case 112: //p
pause = false;
cout<<"Code Resumed"<<endl;
break;
}
}
}
}
//do stuff
}
I have three problems doing that.
First: The differenceImage is always black. Altough I'm moving in fornt of the camera. Probably I'm not grabbing the pictures correctly. Does anyone know what i'm doing wrong? Already tried to add a waitKey(10) before the second RetrieveResult.
Second: The switch(waitKey(10)) is not working. No Matter what i press on the keyboard, there is no output on the screen. Already tried it using if and else if, but that didn't solve the problem either.
Third: If i stop debugging and start debugging again, i get an exception caught by my catch block. Probably this is because the camera didn't stop Grabbing after i stopped debugging. If i plug the camera out and back in the script runs. I tried using stopGrabbing() and close() but it didn't work.
I'm using windows 7 with visual studio 2010!!
Thanks a lot in Advance!

opencv cvGrabFrame frame rate on iOS?

I'm using openCV to split a video into frames. For that I need the fps and duration. Both of these value return 1 when asking them via cvGetCaptureProperty.
I've made a hack where I use AVURLAsset to get the fps and duration, but when I combine that with openCV I get only a partial video. It seems like it's missing frames.
This is my code right now:
while (cvGrabFrame(capture)) {
frameCounter++;
if (frameCounter % (int)(videoFPS / MyDesiredFramesPerSecond) == 0) {
IplImage *frame = cvCloneImage(cvRetrieveFrame(capture));
// Do Stuff
}
if (frameCounter > duration*fps)
break; // this is here because the loop never stops on its own
}
How can I get all the frames of a video using openCV on iOS? (opencv 2.3.2)
According to the documentation you should check the value returned by cvRetrieveFrame(), if a null pointer is returned you're at the end of the video sequence. Then you break the loop when that happens, instead of relying on the accuracy of FPS*frame_number.

Flicker removal using OpenCV?

I am a newbie to openCV. I have installed the opencv library on a ubuntu system, compiled it and trying to look into some image/video processing apps in opencv to understand more.
I am interested to know if OpenCV library has any algorithm/class for removal flicker in captured videos? If yes what document or code should I should look deeper into?
If openCV does not have it, are there any standard implementations in some other Video processing library/SDK/Matlab,.. which provide algorithms for flicker removal from video sequences?
Any pointers would be useful
Thank you.
-AD.
I don't know any standard way to deflicker a video.
But VirtualDub is a Video Processing software which has a Filter for deflickering the video. You can find it's filter source and documents (algorithm description probably) here.
I wrote my own Deflicker C++ function. here it is. You can cut and paste this code as is - no headers needed other than the usual openCV ones.
Mat deflicker(Mat,int);
Mat prevdeflicker;
Mat deflicker(Mat Mat1,int strengthcutoff = 20){ //deflicker - compares each pixel of the frame to a previously stored frame, and throttle small changes in pixels (flicker)
if (prevdeflicker.rows){//check if we stored a previous frame of this name.//if not, theres nothing we can do. clone and exit
int i,j;
uchar* p;
uchar* prevp;
for( i = 0; i < Mat1.rows; ++i)
{
p = Mat1.ptr<uchar>(i);
prevp = prevdeflicker.ptr<uchar>(i);
for ( j = 0; j < Mat1.cols; ++j){
Scalar previntensity = prevp[j];
Scalar intensity = p[j];
int strength = abs(intensity.val[0] - previntensity.val[0]);
if(strength < strengthcutoff){ //the strength of the stimulus must be greater than a certain point, else we do not want to allow the change
//value 25 works good for medium+ light. anything higher creates too much blur around moving objects.
//in low light however this makes it worse, since low light seems to increase contrasts in flicker - some flickers go from 0 to 255 and back. :(
//I need to write a way to track large group movements vs small pixels, and only filter out the small pixel stuff. maybe blur first?
if(intensity.val[0] > previntensity.val[0]){ // use the previous frames value. Change it by +1 - slow enough to not be noticable flicker
p[j] = previntensity.val[0] + 1;
}else{
p[j] = previntensity.val[0] - 1;
}
}
}
}//end for
}
prevdeflicker = Mat1.clone();//clone the current one as the old one.
return Mat1;
}
Call it as: Mat= deflicker(Mat). It needs a loop, and a greyscale image, like so:
for(;;){
cap >> frame; // get a new frame from camera
cvtColor( frame, src_grey, CV_RGB2GRAY ); //convert to greyscale - simplifies everything
src_grey = deflicker(src_grey); // this is the function call
imshow("grey video", src_grey);
if(waitKey(30) >= 0) break;
}

Resources