I already wrote a program that detects different objects, and i'm now working on a tracking module to track the objects of interest. Because the detection isn't as fast, I'm hoping to pass in one frame with the detected objects about every 10-30 frames, and have the tracking module use camshift + kalman filtering to track the objects in the video stream until another new image with the detected objects is received from the detection module.
I'm pretty new to boost and c++ multi-threading in general and I wrote the following code just to see if I can be passing in frames from the detection module to the tracking module. For some reason, everything just freezes after the tracking module has received two imags. Any ideas why? Is there a better way to go about this? Thanks!
Main Thread (Detection module might work in a similar manner)
int main(int argc, char *argv[]){
cout << "main started" << endl;
Tracker tracker("Tracker");
tracker.start(imread("/home/cosyco/Desktop/images/lambo1.jpeg", CV_LOAD_IMAGE_COLOR));
boost::posix_time::seconds sleepTime(5);
cout << "main starting sleep" << endl;
boost::this_thread::sleep(sleepTime);
cout << "main just woke up, switching image" << endl;
tracker.resetImage(imread("/home/cosyco/Desktop/images/lambo2.jpeg", CV_LOAD_IMAGE_COLOR));
cout << "main sleeping second time" << endl;
boost::this_thread::sleep(sleepTime);
cout << "main just woke up, switching image" << endl;
tracker.resetImage(imread("/home/cosyco/Desktop/images/lambo3.jpeg", CV_LOAD_IMAGE_COLOR));
cout << "main sleeping third time" << endl;
boost::this_thread::sleep(sleepTime);
cout << "main just woke up, switching image" << endl;
tracker.resetImage(imread("/home/cosyco/Desktop/images/lambo4.jpeg", CV_LOAD_IMAGE_COLOR));
tracker.join();
cout << "main done" << endl;
return 0;
}
Tracker:
#include <iostream>
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
class Tracker{
private:
string name;
Mat trackerImage;
boost::thread trackerThread;
public:
Tracker (string newName){
cout << "creating tracker : " << newName << "created" << endl;
name = newName;
}
void track(Mat image){
image.copyTo(trackerImage);
informUpdate();
// use this new image to generate a histogram for camshift on the next
//few images in the video stream before a new image with the detected object is received
for (; ; ){
// cout << "tracking" << endl;
}
}
void start(Mat image){
cout << "in tracker's start" << endl;
// trackerThread = boost::thread(&Tracker::track, this, trackLimit);
trackerThread = boost::thread(&Tracker::track, this, image);
}
void join(){
trackerThread.join();
}
void resetImage(Mat image){
track(image);
}
void informUpdate(){
cout << "\033[1;31m image updated \033[0m" << endl;
}
};
Related
I'm trying to use a function to set a text to display on SFML based on the input parameters.
The function is of type Text and returns a text object. I've added cout statements to determine where the error is occurring. The text is as follows:
#include <string>
#include <iostream>
#include "functions.h"
using namespace std;
#include <SFML/Graphics.hpp> // include the SFML Graphics Library
using namespace sf;
Text showPoints(int& points, bool addPoints, bool isPlayer){
cout << "Function called " << endl;
string disPoints;
Text toDisp;
Font pointFont;
if(addPoints){
points += 1;
}
cout << "Points added" << endl;
if(!pointFont.loadFromFile("data/arial.ttf") ){
cout << "could not load font" << endl;
}
cout << "Loaded fonts" << endl;
if(isPlayer){
cout << "isPlayer conditional" << endl;
disPoints = "Player Points: ";
toDisp.setPosition(50, 800);
toDisp.setFont(pointFont);
toDisp.setString(disPoints);
toDisp.setFillColor(Color::White);
toDisp.setCharacterSize(30);
}
else if(!isPlayer){
cout << "isAI conditional" << endl;
disPoints = "AI Points: ";
toDisp.setPosition(1000, 200);
toDisp.setFont(pointFont);
toDisp.setString(disPoints);
toDisp.setFillColor(Color::White);
toDisp.setCharacterSize(30);
}
cout << "Conditions passed" << endl;
return toDisp;
}
//usual SFML stuff... under the while(window.isOpen()), before the
//window.display() and events check
cout << "Error on function?" << endl;
window.draw(showPoints(playerPoints, 0, 1));
cout << "First function passed" << endl;
window.draw(showPoints(AIPoints, 0, 0));
I expect that the text would show in the appropriate positions in the SFML window. However, the terminal outputs this and the window crashes:
Error on function?
Function called
Points added
Loaded fonts
isPlayer conditional
Conditions passed
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
It must be a problem with the window.draw() function as the second draw function is not called. So is it legal to call a function of type Text in the window.draw()? If not, how should I go about this? Google searches yielded nothing helpful on this issue.
I am trying to integrate a code already written in ROS with some basic Visp lines so as to display a camera feed using Visp functions. I am a beginner in visp and hence I am trying something basic.I am attaching the relevant code lines here
//Lots of lines of code above and blow this code block
cv::Mat src_gray;
cv::cvtColor(imageLeft, src_gray, CV_RGB2GRAY );//imageLeft is a colour image got from the camera through another node
vpImage<unsigned char> I;
vpImageConvert::convert(src_gray,I) ;
vpDisplayOpenCV display;
if(this->lt == false)//this if loop is to prevent from infinite windows coming out
{display.init(I, 100, 100, "Line tracking");
this->lt = true;}
vpDisplay::display(I);
vpDisplay::flush(I);
Let me ensure you that this piece of code is in a callback and hence it is equivalent to an infinte while loop unless the process is stopped.
I am not able to get the camera output in the window.When I run the node the window opens but no image.Any ideas?
The ViSP-ROS interfece has been changing recently. While ViSP Bridge provides low level interface between ROS and ViSP, Visp ROS is a better and higher level interface. From there you can reach to this tutorial where a regular ViSP code is modified to use ROS.
The ViSP code similar to yours:
#include <visp/vp1394TwoGrabber.h>
#include <visp/vpDisplayX.h>
#include <visp/vpImage.h>
int main()
{
#ifdef VISP_HAVE_DC1394_2
try {
vpImage<unsigned char> I; // Create a gray level image container
bool reset = true; // Enable bus reset during construction (default)
vp1394TwoGrabber g(reset); // Create a grabber based on libdc1394-2.x third party lib
g.setVideoMode(vp1394TwoGrabber::vpVIDEO_MODE_640x480_MONO8);
g.setFramerate(vp1394TwoGrabber::vpFRAMERATE_60);
g.open(I);
std::cout << "Image size: " << I.getWidth() << " " << I.getHeight() << std::endl;
#ifdef VISP_HAVE_X11
vpDisplayX d(I);
#else
std::cout << "No image viewer is available..." << std::endl;
#endif
while(1) {
g.acquire(I);
vpDisplay::display(I);
vpDisplay::flush(I);
if (vpDisplay::getClick(I, false))
break;
}
}
catch(vpException e) {
std::cout << "Catch an exception: " << e << std::endl;
}
#endif
}
And the ROS enabled code:
#include <visp/vpDisplayX.h>
#include <visp/vpImage.h>
#include <visp_ros/vpROSGrabber.h>
int main()
{
try {
//vpImage<unsigned char> I; // Create a gray level image container
vpImage<vpRGBa> I; // Create a color image container
vpROSGrabber g; // Create a grabber based on ROS
g.setCameraInfoTopic("/camera/camera_info");
g.setImageTopic("/camera/image_raw");
g.setRectify(true);
g.open(I);
std::cout << "Image size: " << I.getWidth() << " " << I.getHeight() << std::endl;
#ifdef VISP_HAVE_X11
vpDisplayX d(I);
#else
std::cout << "No image viewer is available..." << std::endl;
#endif
while(1) {
g.acquire(I);
vpDisplay::display(I);
vpDisplay::flush(I);
if (vpDisplay::getClick(I, false))
break;
}
}
catch(vpException e) {
std::cout << "Catch an exception: " << e << std::endl;
}
}
Hope this helps!
I have a library written in C++. The library has a function which accepts commands as a string and executes them. If an error is encountered (either in the command or while running the command) an "error function" is called which does some cleanup and finally calls exit(1). I am now trying to implement a graphical user interface (using Qt) to the library. The problem is that when an error is encountered, exit is called and my application crashes. I have access to the library source code but I would like to keep modifying the source code to minimum.
I am thinking of rewriting the error function such that it just stops executing code and stays in an idle state until another command is passed to the library from the user-interface. The problem is I am not sure how to go about doing it. I am basically looking for a function call equivalent to exit system call (so that the error function never returns to the code which generated the error) except that I do not want the application to exit but instead just go to an idle state and wait for calls from the user interface.
If there is another way to implement this please let me know. Please also let me know if you need more details.
Thanks in advance,
Here is some code which shows what my problem is
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
void error_func(string error);
void create_sphere(float radius);
void create_rect(float length, float width);
int main()
{
string command;
while(1) {
cout << "Enter command: ";
cin >> command;
if(command.compare("create_sphere") == 0) {
float radius;
cout << "Enter radius: ";
cin >> radius;
create_sphere(radius);
}
else if(command.compare("create_rect") == 0) {
float l, w;
cout << "Enter length and width: ";
cin >> l >> w;
create_rect(l, w);
}
else if(command.compare("quit") == 0)
break;
}
}
void create_sphere(float radius)
{
if(radius < 0)
error_func(string("Radius must be positive"));
cout << "Created sphere" << endl;
}
void create_rect(float length, float width)
{
if(length < 0)
error_func(string("Length must be positive"));
if(width < 0)
error_func(string("Width must be positive"));
cout << "Created rectangle" << endl;
}
void error_func(string error)
{
// do some cleanup
cout << "ERROR: " << error << endl;
exit(1);
}
Assume that create_sphere, create_rect and error_func are provided by the library. I can modify error_func as required but not the other functions (since there are many such functions).
Now when an error is encountered, I would like to go back to the while loop in main so that I can keep accepting other commands.
I am basically looking for a function call equivalent to exit system call (so that the error function never returns to the code which generated the error) except that I do not want the application to exit but instead just go to an idle state and wait for calls from the user interface.
Basically, you are looking for an event loop. The typical minimal Qt program is as follows:
#include <QApplication>
#include <QMainWindow>
int main(int argc, char **argv)
{
QApplication(argc, argv);
QMainWindow w;
w.show();
return application.exec(); // What you want instead of exit
}
Now, you could replace QMainWindow with your own class, and declare a slot in that which gets called when you are trying to handle a command from the user interface.
#include <QWidget>
...
class MyWidget : public QWidget
{
Q_OBJECT
public:
explicit MyWidget(QWidget *parent) : QWidget(parent)
{
connect(sender, SIGNAL(mySignal()), SLOT(handleCommand()));
}
public slots:
void handleCommand()
{
// Handle your command here.
// Print the error code.
qDebug() << error_func(string("Radius must be positive"));
// or simply:
qDebug() << "Radius must be positive";
} // Leaving the scope, and getting back to the event loop
}
As for the bogus library, well, if it exits, it does. There is not much you can do about that without fixint the library. It is a very bad behavior from most of the libraries.
The modification would be not to exit, but return an error code - which is a general practice in Qt software - and leave it with the application when to exit if they wish.
The application would not quit in your case. Again, It is a very bad idea for a library function to exit. Even Qt does not do except 1-2 times in a few million LOC.
I would suggest not to throw an exception. It is generally not common in Qt software, and you could make your software consistent by just using error codes like the rest of Qt does for you.
Invent an error state (idle state) and make the function never fail. The error state should become visible and be resolvable by some means.
If you can not reach a resolvable error state, it might be possible to rollback to some prior (initial) state.
If the options above are not possible you have some serious failure (software, hardware, data) and you might terminate the program.
All above can be achieved with return values or a getter function (indicating the current state) and a setter manipulating the current state - an exit call is a poor solution in a library. If you have an unresolvable state or can not rollback to a prior state you might throw an exception, catch it in the user interface and terminate the program after displaying the issue.
You should install a message handler which will automatically reduce a lot of your work.
Additionally it will help in reducing your debugging too. Here is my message handler for my Qt5 application. It will need a little tweaking if you are using Qt4:
QFile *logFile = NULL;//The file in which you will output the debug info to
QTextStream *logStream = NULL;//text stream for your log file
QMutex *mutex = NULL;//Always use mutex if you are multi threading your application
bool *debugMode = NULL;//it just a flag in case you want to turn off debugging
bool errorMsg = false;//use the value of this variable after QApplication::exec() if you need to show an error message
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
if(((logFile != NULL) && (debugMode != NULL)))
{
mutex->lock();
switch (type)
{
case QtDebugMsg:
if(!*debugMode)
{
mutex->unlock();
return;
}
*logStream << msg;
logStream->flush();
break;
case QtWarningMsg:
if(!((QString)context.function).contains("setGeometry"))
{
*logStream << "\n*** Warning ***\n";
*logStream << msg << endl;
*logStream << "Category: " << context.category << endl;
*logStream << "File: " << context.file << endl;
*logStream << "Function: " << context.function << endl;
*logStream << "Line: " << context.line << endl;
*logStream << "Version: " << context.version;
*logStream << "\n*** Warning Complete ***\n";
logStream->flush();
errorMsg = true;
SessionManager::get_obj()->saveCurrentSession();
}
break;
case QtCriticalMsg:
*logStream << "\n*** Critical ***\n";
*logStream << msg << endl;
*logStream << "Category: " << context.category << endl;
*logStream << "File: " << context.file << endl;
*logStream << "Function: " << context.function << endl;
*logStream << "Line: " << context.line << endl;
*logStream << "Version: " << context.version;
*logStream << "\n*** Critical Complete ***\n";
logStream->flush();
errorMsg = true;
SessionManager::get_obj()->saveCurrentSession();
break;
case QtFatalMsg:
*logStream << "\n*** Fatal ***\n";
*logStream << msg << endl;
*logStream << "Category: " << context.category << endl;
*logStream << "File: " << context.file << endl;
*logStream << "Function: " << context.function << endl;
*logStream << "Line: " << context.line << endl;
*logStream << "Version: " << context.version;
*logStream << "\n*** Fatal Complete ***\n";
logStream->flush();
errorMsg = false;
SessionManager::get_obj()->saveCurrentSession();
ShowErrorMsg(SessionManager::getSessionName());
exit(0);
}
mutex->unlock();
}
}
To install a message handler add the following code in the main() of your GUI.
qInstallMessageHandler(myMessageOutput);
You can ignore the check for setGeometry if you want to but I find that this warning is emitted unnecessarily. So you can keep it.
Also you may want to have a Session Manager which will automatically save the current session whenever an error is encountered.
When you have done this, you can safely call qFatal() when you want to terminate your application, or else use qCritical() if you want some other functionality.
I have the book "beyond the C++ standard library" and there are no examples of multithreading using boost. Would somebody be kind enough to show me a simple example where two threads are executed using boost- lets say asynchronously?
This is my minimal Boost threading example.
#include <boost/thread.hpp>
#include <iostream>
using namespace std;
void ThreadFunction()
{
int counter = 0;
for(;;)
{
cout << "thread iteration " << ++counter << " Press Enter to stop" << endl;
try
{
// Sleep and check for interrupt.
// To check for interrupt without sleep,
// use boost::this_thread::interruption_point()
// which also throws boost::thread_interrupted
boost::this_thread::sleep(boost::posix_time::milliseconds(500));
}
catch(boost::thread_interrupted&)
{
cout << "Thread is stopped" << endl;
return;
}
}
}
int main()
{
// Start thread
boost::thread t(&ThreadFunction);
// Wait for Enter
char ch;
cin.get(ch);
// Ask thread to stop
t.interrupt();
// Join - wait when thread actually exits
t.join();
cout << "main: thread ended" << endl;
return 0;
}
I'm trying to display a video file at 25fps smoothly without any lag. The code below does this, but only achieves about 10fps, taking about 0.1ms to execute. With cvWaitKey(1) I get around 0.03 to 0.04ms, which would be perfect, but the named window just stays grey and doesn't show the video!
Is this because cvShowImage() is too slow? Is there any other way to speed up the code and output the video smoothly?
See my code below.
Thanks a lot in advance,
Adrian
#include <cv.h>
#include <iostream>
#include <highgui.h>
#include <cxcore.h>
#include <cvaux.h>
#include <sstream>
#include <time.h>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
CvCapture* vid = 0;
IplImage* input; //Input image
int fps;
int i=0;
clock_t start, end;
/*Creates the GUI to output the processed images*/
cvNamedWindow("Video input", 0);
/*Open input video*/
if (argc!=2)
{
cout << "Please specify an input video." << endl;
return -1;
}
else
{
vid=cvCreateFileCapture(argv[1]);
if (!vid)
{
cout << "Could not extract frame." << endl;
return -1;
}
}
input = cvQueryFrame(vid);
fps = (int)cvGetCaptureProperty(vid, CV_CAP_PROP_FPS);
cout << fps << endl;
cout << "Video found." << endl;
/*Extraction loop */
while (input)
{
start = clock();
cout << flush;
cout << i << "\r";
i++;
/*Show image*/
cvShowImage("Video input", input);
cvWaitKey(2); //Wait is needed or else we see a grey box
input = cvQueryFrame(vid); //Read next frame from video
end = clock();
cout << (double)(end-start)/CLOCKS_PER_SEC << " s" << endl;
};
/*Release the allocated memory for the frames */
cvReleaseImage(&input);
cvDestroyWindow("Video input");
return 1;
}
Have you tried this without all the cout stuff?
The debug build of the Microsoft STL has cout handling which is almost unbelievably slow.
Try calling cvWaitKey with 1000 / fps wanted, in your case :
cvWaitKey(1000/25)
You could try something like:
char key = cvWaitKey(10); //waits 10 milliseconds
if (key == 27) //and if ESC is pressed, get out of the loop
break;