Video Grabbing doesn't work OpenCV - c++

I am using this piece of code to grab frames off a video :
#include <stdio.h>
#include <stdlib.h>
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <iostream>
using namespace cv;
using namespace std;
int main (int argc, char** argv)
{
//initializing capture from file
CvCapture * capture = cvCaptureFromAVI ("/home/<some_file>.avi");
//Capturing a frame
IplImage* img = 0;
if(!cvGrabFrame(capture)) //capture a frame
{
cout << Could not grab a frame\n\7";
exit(0);
}
img=cvRetrieveFrame(capture); //retrieve the captured frame
//free resources
cvReleaseCapture(&capture);
}
Which is returning :
Could not grab a frame
Additional details :
I had used code to save webcam video feed to the file from which i want to grab frames .
I used this code :
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
int main( int argc, char** argv ) {
CvCapture* capture;
capture = cvCreateCameraCapture(0);
assert( capture != NULL );
IplImage* bgr_frame = cvQueryFrame( capture );
CvSize size = cvSize(
(int)cvGetCaptureProperty( capture,
CV_CAP_PROP_FRAME_WIDTH),
(int)cvGetCaptureProperty( capture,
CV_CAP_PROP_FRAME_HEIGHT)
);
cvNamedWindow( "Webcam", CV_WINDOW_AUTOSIZE );
CvVideoWriter *writer = cvCreateVideoWriter( "/Users/user/Desktop/OpenCV_trial/OpenCV_trial/vidtry.AVI",
CV_FOURCC('D','I','V','X'),
30,
size
);
while( (bgr_frame = cvQueryFrame( capture )) != NULL )
{
cvWriteFrame(writer, bgr_frame );
cvShowImage( "Webcam", bgr_frame );
char c = cvWaitKey( 33 );
if( c == 27 ) break;
}
cvReleaseVideoWriter( &writer );
cvReleaseCapture( &capture );
cvDestroyWindow( "Webcam" );
return( 0 );
}
Does anyone know where I might be going wrong ? I am running OpenCV-2.4.3 on a Beagleboard -xM with Ubuntu Quantal.

I am not quite sure what your exactly question is, but if you want to grab frames from a video, you should at least have a loop.
A reason for your error could be, that your video file is not available. Have you tried another one? The full path of the file? Or put the file directly into your working directory and check it.
Another reason could be a problem with the first frame (this sometimes happens). So try to remove your exit and enclose your code with a loop over all frames.
Here is an example that shows the given video file (Consider to use the C++-interface):
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <iostream>
using namespace cv;
using namespace std;
int main (int argc, char** argv)
{
//initializing capture from file
Mat img;
VideoCapture capture("a.avi");
if(!capture.isOpened())
{
cout<<"Could not open video!\n";
return 1;
}
while(true)
{
//Capturing a frame
capture >> img;
if(!img.empty())
{
imshow("Video",img);
}
else
{
cout <<"Could not grab a frame\n";
break;
}
if(waitKey(5) >= 0)
break;
}
return 0;
}
This program runs on my PC if the file "a.avi" is in the current working directory of the program.

Related

Trying to Locate Aruco Fiducials with USB camera Ubuntu 18.04

I have some code I think should be working using open CV to detect a set of fiducials. For some reason, I cant get my code to run. It gives the error "Unable to stop the stream: Invalid argument"
#include "opencv2/opencv.hpp"
using namespace cv;
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/aruco.hpp>
int main(int argc, char** argv)
{
Mat markerImage;
VideoCapture cap;
// open the default camera, use something different from 0 otherwise;
// Check VideoCapture documentation.
if(!cap.open(1))
return 0;
for(;;)
{
Mat frame;
cap >> frame;
if( frame.empty() ) break; // end of video stream
std::vector<int> markerIds;
std::vector<std::vector<cv::Point2f>> markerCorners, rejectedCandidates;
cv::Ptr<cv::aruco::DetectorParameters> parameters = cv::aruco::DetectorParameters::create();
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_5X5_50);
cv::aruco::detectMarkers(frame, dictionary, markerCorners, markerIds, parameters, rejectedCandidates);
cv::aruco::drawDetectedMarkers(frame, markerCorners, markerIds);
imshow("Camera)", frame);
if( waitKey(10) == 27 ) break; // stop capturing by pressing ESC
}
// the camera will be closed automatically upon exit
// cap.close();
return 0;
}

OpenCV C++ - Not able to show a video

Linux Debian 10 + OpenCV 320.
Very basic sample to play a video but the application soon ends without open a new window and witout errors.
My tests with same videos but in different types: mp4 and webm. The video are correctly shown by VLC and other video players.
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
int main(int argc, char** argv )
{
// check
if ( argc != 2 )
{
printf("usage: %s <Video_Path>\n", argv[0]);
return -1;
}
printf("Video: %s\n", argv[1]);
// load video
VideoCapture cap ( argv[1]);
if (!cap.isOpened()){
printf("Error opening video\n");
}
Mat frame;
while(1){
// cap.read(frame);
cap >> frame;
if (frame.empty()){
printf(".. frame err\n");
return -1;
}
imshow("Live", frame);
if (waitKey(5)>=0) break;
}
printf("end\n");
return 0;
}
The output is:
$ ./DisplayVideo 20200313_152914.webm
Video: 20200313_152914.webm
end
I solved casting to char:
if ((char)(waitKey(1))>=0){

delay in ouput of combined c++ program

i have two programs in c++. one is to communicate with arduino(pgm1),while the other is an openCV program reading a webcam(pgm2). independently, they work at moral speed.
if we open them simultaneously in different terminals they work perfect.i wanted to join them as a single program, i tried a program (pgm3). i can get images perfectly in real time.. but the data from arduino delays about 7-10 seconds. unfortunately i know only c/c++/embedded c. so kindly refer me a solution in any one of these languages
pgm1
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
char ch;
ifstream f;
f.open("/dev/ttyACM0");
while (f.get(ch))
{
cout<<ch;
if(ch=='#')
cout<<endl;
}
return 0;
pgm2
#include "opencv2/objdetect.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
/** Function Headers */
String window_name = "webcam c170 preview";
/** #function main */
int main( void )
{
VideoCapture capture;
Mat frame;
capture.open( 1 );
if ( ! capture.isOpened() ) { printf("--(!)Error opening video capture\n"); return -1; }
while ( capture.read(frame) )
{
if( frame.empty() )
{
printf(" --(!) No captured frame -- Break!");
break;
}
//-- 3. show frames
imshow( window_name, frame );
int c = waitKey(30);
if( (char)c == 27 ) { break; } // escape
}
return 0;
}
}
pgm3
#include "opencv2/objdetect.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include<fstream>
using namespace std;
using namespace cv;
void spi_read(void);
/** Global variables */
char ch;
ifstream f;
String window_name = "webcam c170 preview";
/** #function main */
int main( void )
{
VideoCapture capture;
Mat frame;
f.open("/dev/ttyACM0");
capture.open( 1 );
if ( ! capture.isOpened() ) { printf("--(!)Error opening video capture\n"); return -1; }
while ( capture.read(frame) )
{
if( frame.empty() )
{
printf(" --(!) No captured frame -- Break!");
break;
}
//-- 3. show frames
imshow( window_name, frame );
int c = waitKey(30);
if( (char)c == 27 ) { break; } // escape
spi_read();
}
return 0;
}
void spi_read()
{
String str_spi;
do
{
f.get(ch);
str_spi=str_spi+ch;
}while(ch!='#');
cout<<str_spi<<endl;
}
Do not just merge to code into one function - of course it will cause your second program to "delay" - because its starts to execute after ur previos code is done.
You should create separate thread to simulate ur pgm1/pgm2 programs and then maybe process data received by them in ur main thread - depending on your needs.
Most straighforward solution using boost/thread:
void do_what_pgm1_does() {..}
void do_what_pgm2_does() {..}
int main()
{
boost::thread t1(do_what_pgm1_does);
boost::thread t2(do_what_pgm2_does);
t1.join();
t2.join();
}
this will give you similar execution as you had with 2 processes.

opencv saving image captured from webcam

I receive an error "SIGABRT ERROR" when the code is trying to save the image on the HD.
I'm working with a MacBook Pro Mountain Lion on last XCODE and the libraries are well reconfigured.
Someone has a solution or some ideas?
#include "cv.h"
#include "highgui.h"
#include <stdio.h>
using namespace cv;
// A Simple Camera Capture Framework
int main() {
CvCapture* capture = cvCaptureFromCAM( CV_CAP_ANY );
if ( !capture ) {
fprintf( stderr, "ERROR: capture is NULL \n" );
getchar();
return -1;
}
// Create a window in which the captured images will be presented
cvNamedWindow( "mywindow", CV_WINDOW_AUTOSIZE );
// Show the image captured from the camera in the window and repeat
while ( 1 ) {
// Get one frame
IplImage* frame = cvQueryFrame( capture );
if ( !frame ) {
fprintf( stderr, "ERROR: frame is null...\n" );
getchar();
break;
}
cvShowImage( "mywindow", frame );
// Do not release the frame!
if ( (cvWaitKey(10) & 255) == 's' ) {
CvSize size = cvGetSize(frame);
IplImage* img= cvCreateImage(size, IPL_DEPTH_16S, 1);
img = frame;
cvSaveImage("matteo.jpg",&img);
}
if ( (cvWaitKey(10) & 255) == 27 ) break;
}
// Release the capture device housekeeping
cvReleaseCapture( &capture );
cvDestroyWindow( "mywindow" );
return 0;
}
The problem is that you are mixing your pointer syntax. You are creating a new IplImage with IplImage* img= cvCreateImage(size, IPL_DEPTH_16S, 1); but on the following line, you lose this structure as you overwrite the pointer img with frame.
The code causing your sigabrt is where you're sending a pointer to a pointer in
cvSaveImage("matteo.jpg",&img);. You should not do &img as img already is a pointer. The following is correct:
cvSaveImage("matteo.jpg",img);
There is actually no reason for you to create a new IplImage unless you want to do some preprocessing before saving it to file.
I modified your if-clause to the following which works fine on my computer:
if ( cvWaitKey(10) < 0 ) {
cvSaveImage("matteo.jpg",frame);
}
I have spent several days searching the internet for the right solution with simple keyboard input. There was always some lag / delay while using cv::waitKey.
The solution I have found is with adding Sleep(5) just after capturing the frame from webcam.
The below example is a combination of different forum threads.
It works without any lag / delay. Windows OS.
Press "q" to capture and save the frame.
There is a webcam feed always present. You can change the sequence to show the captured frame / image.
PS "tipka" - means "key" on the keyboard.
Regards, Andrej
#include <opencv2/opencv.hpp>
#include <iostream>
#include <stdio.h>
#include <windows.h> // For Sleep
using namespace cv;
using namespace std;
int ct = 0;
char tipka;
char filename[100]; // For filename
int c = 1; // For filename
int main(int, char**)
{
Mat frame;
//--- INITIALIZE VIDEOCAPTURE
VideoCapture cap;
// open the default camera using default API
cap.open(0);
// OR advance usage: select any API backend
int deviceID = 0; // 0 = open default camera
int apiID = cv::CAP_ANY; // 0 = autodetect default API
// open selected camera using selected API
cap.open(deviceID + apiID);
// check if we succeeded
if (!cap.isOpened()) {
cerr << "ERROR! Unable to open camera\n";
return -1;
}
//--- GRAB AND WRITE LOOP
cout << "Start grabbing" << endl
<< "Press a to terminate" << endl;
for (;;)
{
// wait for a new frame from camera and store it into 'frame'
cap.read(frame);
if (frame.empty()) {
cerr << "ERROR! blank frame grabbed\n";
break;
}
Sleep(5); // Sleep is mandatory - for no leg!
// show live and wait for a key with timeout long enough to show images
imshow("CAMERA 1", frame); // Window name
tipka = cv::waitKey(30);
if (tipka == 'q') {
sprintf_s(filename, "C:/Images/Frame_%d.jpg", c); // select your folder - filename is "Frame_n"
cv::waitKey(10);
imshow("CAMERA 1", frame);
imwrite(filename, frame);
cout << "Frame_" << c << endl;
c++;
}
if (tipka == 'a') {
cout << "Terminating..." << endl;
Sleep(2000);
break;
}
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}

Storing and retrieving IplImages from vector?

I want to store IplImage's ( grabbed from a video file) into a vector and then playback from this iplimage vector.
#include <iostream>
#include "highgui.h"
using namespace std;
int main()
{
CvCapture* capture=cvCreateFileCapture("D:\\Video\\Hands tracking.avi");
vector<IplImage*> imagesNames[2];
//playing video
while(1)
{
IplImage* img=cvQueryFrame(capture);
cvShowImage("Video Opencv example nd testing purpose",img);
imagesNames[0].push_back(img);
char c = cvWaitKey(30);
if(c==27) break;
}
cvDestroyWindow( "Video Opencv example nd testing purpose" );
cvReleaseCapture(&capture);
// play back grabbed IplImages
for(unsigned i=0; imagesNames[0].size();i++)
{
cvShowImage("PlayBack from IplImages vector",imagesNames[0][i]);
char c = cvWaitKey(30);
if(c==27) break;
}
return 0;
}
But the playback part of the above program is not working and showing error at runtime.
#include <iostream>
#include "highgui.h"
using namespace std;
int main()
{
CvCapture* capture=cvCreateFileCapture("D:\\Video\\Hands tracking.avi");
vector<IplImage*> imagesNames;
//playing video
while(1)
{
IplImage* img=cvQueryFrame(capture);
cvShowImage("Video Opencv example nd testing purpose",img);
imagesNames.push_back(img);
char c = cvWaitKey(30);
if(c==27)
break;
}
cvDestroyWindow( "Video Opencv example nd testing purpose" );
cvReleaseCapture(&capture);
// play back grabbed IplImages
for(unsigned i=0; i < imagesNames.size();i++)
{
cvShowImage("PlayBack from IplImages vector",imagesNames[i]);
char c = cvWaitKey(30);
if(c==27)
break;
}
return 0;
}