Below is the code for a tracking module. A detector is launched and when it detects the object of interest, it creates a tracker object to track the object using camshift on a number of frames until the detector finds another object. The code seems to work fine when I comment out imshow and waitkey in the tracker. But when I call those functions, I get the following error when a new tracker (apart from the first one) is created:
QMetaMethod::invoke: Unable to invoke methods with return values in queued connections
QObject::startTimer: QTimer can only be used with threads started with QThread
I don't know if this is something happening within boost or opencv. Any ideas how I can fix this problem? Is there a better way to go about showing the user the position of the object of interest? Thanks a lot!
main:
#define FACE_DETECT_RATE 10
Tracker *currentTracker;
boost::mutex displayedImageMutex;
Mat imageToShow; // image displayed by the main thread
void updateDisplayedImage(Mat image){
if (displayedImageMutex.try_lock()){
image.copyTo(imageToShow);
displayedImageMutex.unlock()
}
}
Rect detectorCallback(Rect faceRect){
// the detector object returns the face it found here
// a tracker is supposed to track the face in the next set of frames
Tracker tracker(faceRect);
tracker.start(&updateDisplayedImage);
currentTracker = &tracker;
currentTracker->join();
}
int main(int argc, char **argv){
VideoCapture capture(0);
currentTracker = NULL;
int frameCount = 0;
while (true){
Mat frame;
capture >> frame;
if (frameCount % FACE_DETECT_RATE == 0){
Detector detector;
detector.start(frame, &detectorCallback);
}
if (displayedImageMutex.try_lock()){
if (imageToShow.data){
imshow("Results", imageToShow);
waitKey(1);
}
displayedImageMutex.unlock();
}
}
}
Tracker:
class Tracker{
private:
boost::thread *trackerThread;
void run(void (*imageUpdateFunc)(Mat)){
while (true){
try{
...
//do camshift and stuff
//show results
//imshow("Stream", imageWithFace);
//waitKey(10);
imageUpdateFunc(imageWithFace);
...
boost::this_thread::interruption_point();
} catch (const boost::thread::interrupted&){
break;
}
}
}
public:
Tracker(Rect faceRect){
...
}
void start(void (*imageUpdateFunc)(Mat)){
trackerThread = new boost::thread(&Tracker::run, this, imageUpdateFunc);
}
void stop(){
trackerThread->interrupt();
}
void join(){
trackerThread->join();
}
};