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.
Related
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;
}
Good afternoon to all!
I've been using Visual Studio 2010 with OpenCV to develop a code for Face recognition. I'm trying to reach the task by two Threads (I need to do it this way, because i´m going to apply it on a bigger project), one (the main) to show the frames and the second to capture (from the Webcam of my laptop) and store the frames on a Mat object (Fast Capture).
The inconvenient here is that the second Thread is capturing the frames, but the main is not showing them. I think there is a problem with copying the Mat from the capture Thread to the Mat on the main thread ("current_frame" seems to be empty after I do the assignation)
Here is the code (I'm using Boost::Thread for Multithreading)
New code with suggestions
Global declarations
#include <iostream>
#include <stdio.h>
#include <boost\thread.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
boost::mutex mtx;
The function
void camCapture(VideoCapture& cap, Mat& frame, bool* Capture)
{
while (*Capture==true)
{
mtx.lock();
cap >> frame;
mtx.unlock();
if(frame.empty())
{
cout<<"No hay captura"<<endl;
}
else
{
cout<<"Frame capturado"<<endl;
}
}cout << "camCapture finished\n";
return;}
The main
int main() {
try{
VideoCapture cap(0); // open the default camera
Mat frame,current_frame, SFI, Input;
bool *Capture = new bool;
*Capture = true;
if (!cap.isOpened()) // check if we succeeded
return -1;
//your capture thread has started
boost::thread captureThread(camCapture, cap, frame, Capture);
while(1)
{
if(frame.empty())
{
cout<<"Frame en hilo principal vacio"<<endl;
}
else{
cout<<"Frame en hilo principal capturado"<<endl;
}
mtx.lock();
current_frame = frame.clone();
mtx.unlock();
if(current_frame.empty())
{
cout<<"Current_Frame vacio"<<endl;
}
else{
imshow("Streaming",current_frame);
if(waitKey(10)==27)break;
}
}
//Terminate the thread
captureThread.join();
}
catch(Exception & e)
{
cout<<e.what()<<endl;
}
return 0;}
according to Boost threads - passing parameters by reference you have to use boost::ref(v) if you want to pass a variable by reference to a boost::thread function. But you could use pointers instead.
In addition you should share the mutex to the thread by passing it as pointer or reference variable instead of using it as global:
#include <iostream>
#include <stdio.h>
#include <boost/thread.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
boost::mutex mtx;
void camCapture(VideoCapture& cap, Mat& frame, bool* Capture)
{
while (*Capture == true)
{
mtx.lock();
cap >> frame;
mtx.unlock();
if (frame.empty())
{
cout << "No hay captura" << endl;
}
else
{
cout << "Frame capturado" << endl;
}
}cout << "camCapture finished\n";
return;
}
int main() {
try{
VideoCapture cap(0); // open the default camera
Mat frame, current_frame, SFI, Input;
bool *Capture = new bool; // better not use a pointer here, but use a bool and pass the address or by reference.
*Capture = true;
if (!cap.isOpened()) // check if we succeeded
return -1;
//your capture thread has started
boost::thread captureThread(camCapture, boost::ref(cap), boost::ref(frame), Capture);
while (1)
{
mtx.lock();
current_frame = frame.clone();
mtx.unlock();
if (current_frame.empty())
{
cout << "Current_Frame vacio" << endl;
}
else{
imshow("Streaming", current_frame);
if (waitKey(10) == 27)
{
// TODO: you should use a mutex (or an atomic type) here, too, maybe setting a bool is thread-safe, but this can't be guaranteed for each hardware!
*Capture = false;
break;
}
}
}
//Terminate the thread
captureThread.join();
// give memory free:
delete Capture;
}
catch (Exception & e)
{
cout << e.what() << endl;
}
return 0;
}
I used a for loop for reading 300 frames and for accumulating them.I gave an imshow command inside to print the frames continuously but they are not printed during the for loop is processing but it comes as a single image
Here's my code:
enter code here
#include<iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include<stdlib.h>
#include<stdio.h>
using namespace cv;
using namespace std;
int main()
{
char k;
int learningframes=300;
VideoCapture cap(0);
if(cap.isOpened()==0)
{
cout<<"ERROR";
return -1;
}
//while(1)
//{
Mat frame;
cap>>frame;
Mat frameaccF,frameacc,framethr32,framehsv,framethr;
frameaccF=Mat::zeros(frame.size(),CV_32FC1);
for(int i=0;i<=learningframes;i++)
{
cap>>frame;
imshow("nn",frame);
cvtColor(frame,framehsv,CV_BGR2HSV);
inRange(framehsv,Scalar(0,30,0),Scalar(50,150,255),framethr);
framethr.convertTo(framethr,CV_32F);
accumulate(framethr,frameaccF);
}
frameaccF=frameaccF/300;
frameaccF.convertTo(frameaccF,CV_8U);
imshow("frame",frame);
imshow("frameacc",frameaccF);
waitKey(0);
//if(k=='q')
//break;
//}
return 0;
}
You need to put the waiKey() inside the for loop
for(int i=0;i<=learningframes;i++)
{
cap>>frame;
imshow("nn",frame);
cvtColor(frame,framehsv,CV_BGR2HSV);
inRange(framehsv,Scalar(0,30,0),Scalar(50,150,255),framethr);
framethr.convertTo(framethr,CV_32F);
accumulate(framethr,frameaccF);
waitKey(0);
}
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.
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;
}