cvQueryFrame doesn't return null - opencv

CvCapture* capture = cvCreateFileCapture( filename );
int nFrames = (int) cvGetCaptureProperty( capture , CV_CAP_PROP_FRAME_COUNT );
printf("Frame count - %d\n", nFrames);
while(1){
frame = cvQueryFrame( capture );
if( !frame ) {
break;
}
}
nFrames == 101
but cycle doesn't stop after 101 iteration, why?

cvQueryFrame returns an IplImage pointer. Based on the old documentation here, it may or may not return NULL in the event of an error. In addition to checking for if it's NULL, you will probably want to check if the returned IplImage* has valid data to see if you actually got a frame or not.
Or better yet, switch to using the C++ interface:
VideoCapture cap( filename );
//check if we succeeded
if(!cap.isOpened())
{
//...
}
Mat frame;
for(;;)
{
//get a new frame from camera
bool got_frame = cap.read(frame);
if(!got_frame)
break;
//...
}

Related

opencv Unable to record video from camera to a file

i am trying capture a video from webcam. But i am always getting a 441 byte size file getting created.
Also in console there is error coming
OpenCVCMD[37317:1478193] GetDYLDEntryPointWithImage(/System/Library/Frameworks/AppKit.framework/Versions/Current/AppKit,_NSCreateAppKitServicesMenu) failed.
Code Snippet
void demoVideoMaker() {
//Camera Input
VideoCapture cap(0);
vidoFeed = ∩
namedWindow("VIDEO", WINDOW_AUTOSIZE);
//Determine the size of inputFeed
Size inpFeedSize = Size((int) cap.get(CV_CAP_PROP_FRAME_WIDTH), // Acquire input size
(int) cap.get(CV_CAP_PROP_FRAME_HEIGHT));
cout<<"Input Feed Size: "<<inpFeedSize<<endl;
VideoWriter outputVideo;
char fName[] = "capturedVid.avi";
outputVideo.open(fName, CV_FOURCC('P','I','M','1'), 20, inpFeedSize, true);
if (!outputVideo.isOpened()) {
cout<<"Failed to write Video"<<endl;
}
//Event Loop
Mat frame;
bool recordingOn = false;
while(1){
//Process user input if any
char ch = char(waitKey(10));
if (ch == 'q') {
break;
}if (ch == 'r') {
recordingOn = !recordingOn;
}
//Move to next frame
(*vidoFeed)>>frame;
if (frame.empty()) {
printf("\nEmpty Frame encountered");
}else {
imshow("VIDEO", frame);
if(recordingOn) {
cout<<".";
outputVideo.write(frame);
}
}
}
}
I am using opencv2.4, XCode 8.2 on mac OS Sierra 10.12.1
Tried changing the codec, fps, but nothing helped. I was assuming this would be a straight forward task but got stuck here. Please help.

Error while capturing video for a pre-defined time period

This program captures video until I press Esc. But I need to modify this program and capture video for 30s.
After recording the video it plays very fast and the video length reduces. I tried to add waitKey at the end, but it still doesn't work. After recording the video length should be the same. How can I do that? Any suggestions?
int main( int argc, const char** argv )
{
using namespace std;
using namespace cv;
VideoCapture cap(0);
while(!(cap.isOpened() && cap.grab()))
{
cout << "Camera not ready" << endl;
}
VideoWriter Writer("D:/MyVideo.avi", CV_FOURCC('P','I','M','1'),20,Size(640,480), true);
while (waitKey(30)!= 27)
{
Mat frame;
cap >> frame;
Writer.write(frame);
imshow("D:/MyVideo", frame);
}
}
int64 t0 = cv::getTickCount();
while (waitKey(30)!= 27)
{
Mat frame;
cap >> frame; // read a new frame from video
Writer.write(frame); //writer the frame into the file
double t = (cv::getTickCount() - t0) / cv::getTickFrequency();
if (t > 30)
break;
...
// now, we need to adjust to the desired framerate of 20fps,
// so we need to sleep for 1000/20 = 50 milliseconds
// either have a window, and use waitKey():
// imshow("lalala", frame);
// waitKey(50);
// or just sleep(), unfortunately system dependant ;(
// win:
// Sleep(50);
// linux, etc.:
// usleep(50);
}

Does cvQueryFrame advance the current frame?

I'm trying to learn OpenCV using an O'Reilley book and am finding the sample programs raise as many questions as they answer. In a very basic program to show a video:
#include <highgui.h>
#include <string>
int main( int argc, char** argv){
std::string name = "Example 2";
cvNamedWindow(name.c_str(),CV_WINDOW_AUTOSIZE);
CvCapture* capture = cvCreateFileCapture( argv[1]);
IplImage* frame;
while(1) {
frame = cvQueryFrame( capture );
if ( !frame ) break;
cvShowImage (name.c_str(), frame);
char c = cvWaitKey(33);
if (c == 27) break; //User hits ESC key - ASCII value 27
}
cvReleaseCapture( &capture );
cvDestroyWindow(name.c_str());
}
I find myself wondering why I ever see more than a single frame. Everything I read online about cvQueryFrame says it retrieves the current frame. No where have I seen anything about how/when/where the "current" frame advances.
Does cvQueryFrame act more like reading from a file or stream, in that it reads data and then prepares to read the next piece of data, or does the current frame advance in some other way?

Error opencv & openframework While cropping image

I have the following code:
IplImage* f( IplImage* src )
{
// Must have dimensions of output image
IplImage* cropped = cvCreateImage( cvSize(1280,500), src->depth, src->nChannels );
// Say what the source region is
cvSetImageROI( src, cvRect( 0,0, 1280,500 ) );
// Do the copy
cvCopy( src, cropped );
cvResetImageROI( src );
return cropped;
}
void testApp::setup(){
img.loadImage("test.jpg");
finder.setup("haarcascade_frontalface_default.xml");
finder.findHaarObjects(img);
}
//--------------------------------------------------------------
void testApp::update(){
}
//--------------------------------------------------------------
ofRectangle cur;
void testApp::draw(){
img = f(img);
img.draw(0, 0);
ofNoFill();
for(int i = 0; i < finder.blobs.size(); i++) {
cur = finder.blobs[i].boundingRect;
ofRect(cur.x-20, cur.y-20, cur.width+50, cur.height+50);
}
}
It produces an error. I think it's because I don't convert IplImage to ofImage. Can someone please tell me how to do it?
I would imagine that your instance of img, that your passing to f(), is an instance of ofxCVImage or similar. As far as I know ofx store a protected variable of iplimage, as such you can't cast ofxCVImage to an iplimage.
You might try
img = f(img.getCvImage()) // ofxCvImage::getCvImage() returns IplImage

Opencv: image, retrieved from camera capture is always gray

I am always getting a grey screen when showing image using opencv, the image is captured from camera.
capture = cvCaptureFromCAM(-1);
cvGrabFrame(capture);
image = cvRetrieveFrame(capture);
cvShowImage("name", image);
after this I see the grey screen, even if I do in cycle. But the same code works well on another computer. What is the problem? The same opencv library version is used on both computers. Working in the Visual Studio 2010, C++
Opencv version 2.2.0
EDIT 1: The camera used in both computers is the same.
And I have tried to rebuild the opencv on the computer where the problem happens, it didn't help.
I had the same problem in OpenCvSharp. I don't know what's the cause, but for some reason, calling the "WaitKey" method after displaying the image solved it.
CvCapture mov = new CvCapture(filepath);
IplImage frame = mov.QueryFrame();
CvWindow win1 = new CvWindow(window name);
win1.ShowImage(frame);
CvWindow.WaitKey(1);
Your problem sounds very weird.
Try to use cvQueryFrame instead of cvRetrieveFrame() and let me know if it does make a difference.
Here is a code of using opencv for face detection, the concept of capturing an image is very similar:
int main( int argc, const char** argv )
{
CvCapture* capture;
Mat frame;
//-- 1. Load the cascades
if( !face_cascade.load( face_cascade_name ) ){ printf("--(!)Error loading\n"); return -1; };
if( !eyes_cascade.load( eyes_cascade_name ) ){ printf("--(!)Error loading\n"); return -1; };
//-- 2. Read the video stream
capture = cvCaptureFromCAM( -1 );
if( capture )
{
while( true )
{
frame = cvQueryFrame( capture );
//-- 3. Apply the classifier to the frame
if( !frame.empty() )
{ detectAndDisplay( frame ); }
else
{ printf(" --(!) No captured frame -- Break!"); break; }
int c = waitKey(10);
if( (char)c == 'c' ) { break; }
}
}return 0;
}

Resources