Ask Your Question
0

Using multithreading in opencv

asked 2017-10-06 00:17:48 -0600

kimchiboy03 gravatar image

updated 2017-10-06 17:22:54 -0600

Hello, I am currently trying to use multithreading in opencv. However, this code is not working.

#include <iostream>
#include <thread>

#include "opencv2/nonfree/features2d.hpp"

#include "FeatureMatching.h"
#include "FaceDetection.h"
#include "AugmentedReality.h"

Mat colorImg;
VideoCapture capture(0);

//Captures image from camera
void doCapture(VideoCapture capture)
{
    while (true)
    {
        capture.read(colorImg);
        imshow("HUD", colorImg);
        cvWaitKey(1);
    }
}

//Deicides what to do
void doDecision()
{
    while (true)
    {
        int k = waitKey(1);
        if (k == 49)
        {
            cout << "Detecting..." << endl;
            doMatch(colorImg);
        }
        else if (k == 50)
        {
            cout << "Detecting..." << endl;
            doDetect(colorImg);
        }
        else if (k == 51)
        {
            cout << "Displaying..." << endl;
            while (waitKey(1) != 51)
            {
                doAR(capture);
            }
        }
        else if (k == 27)
        {
            cout << "Stop";
        }
    }
}

//Main function
int main()
{
    thread t1(doCapture, capture);
    thread t2(doDecision);

    //cvNamedWindow("HUD", 0);
    //cvSetWindowProperty("HUD", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);

    initMatch();
    initFace();
    initAR();

    t1.join();
    t2.join();
}

If anyone needs to see more of my code, I'll will do so. Can someone please tell what's the problem? Thanks in advance.

edit retag flag offensive close merge delete

Comments

2

naive multithreading & global variables -- just don't !

all your gui calls (imshow(), waitKey(), etc) have to stay in the main thread !

berak gravatar imageberak ( 2017-10-06 00:24:53 -0600 )edit

@berak However, the imshow still works. I can still see the camera output. It's just that the methods in the doDecision() method isn't being called...

kimchiboy03 gravatar imagekimchiboy03 ( 2017-10-06 00:52:34 -0600 )edit

please explain the reason for using multithreading in the 1st place

berak gravatar imageberak ( 2017-10-06 00:55:28 -0600 )edit

@berak So, I am trying to display a live video from a camera which is then displayed onto a cvNamedWindow(). While this is happening, I want to enable user input via cvWaitKey() which triggers certain functions.

kimchiboy03 gravatar imagekimchiboy03 ( 2017-10-06 01:00:01 -0600 )edit

maybe all you need is a better programming logic, not multithreading.

and please do not use cvNamedWindow(c-api) but cv::namedWindow(c++ api) !

(same for all those cv calls)

berak gravatar imageberak ( 2017-10-06 01:09:15 -0600 )edit

why does doAR(capture); need the capture? (wouldn't you wrongly read twice from it ? (see doCapture())

if you can rewrite all your doSomething functions to take a single image, you'd only need a single, linear state machine in the main thread.

berak gravatar imageberak ( 2017-10-06 02:15:45 -0600 )edit

@berak Oops, I have removed that bit of the code

kimchiboy03 gravatar imagekimchiboy03 ( 2017-10-06 02:30:45 -0600 )edit

@berak When I debugged this code, I saw that in the doDecision() method, the waitKey() was not able to pick up the keyboard input, which was why the methods couldn't be called. Is there an alternative to waitKey()?

kimchiboy03 gravatar imagekimchiboy03 ( 2017-10-06 02:38:08 -0600 )edit

again, you cannot have waitKey() in a thread

berak gravatar imageberak ( 2017-10-06 03:07:49 -0600 )edit
2

If you want to use waitkey in a thread you must write your own function and answer to the question : when you pressed a key which threads wil receive keyboard input? if answer is all thread don't write a new function and inser waitkey in main thread

In a multiapplication the answer is easy keyboard input are redirected to active application (selected by user).

in multithread program thread activation is less than 1 ms. Be fast when you press a key

LBerger gravatar imageLBerger ( 2017-10-06 03:51:20 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2017-10-07 03:13:01 -0600

berak gravatar image

updated 2017-10-07 04:24:32 -0600

imho, you should not overcomplicate it, and switch to a much simpler design.

have a single while loop, a single waitKey() call, and dispatch to your tasks from there:

#include <iostream>

#include "opencv2/nonfree/features2d.hpp"

#include "FeatureMatching.h"
#include "FaceDetection.h"
#include "AugmentedReality.h"

//Main function
int main()
{
    VideoCapture capture(0);
    while (cap.isOpened()) // (CHECK!!)
    {
        Mat colorImg;
        capture.read(colorImg);
        if (colorImg.empty())
            break;

        int k = waitKey(10);
        switch (k) 
        {
            case 27:  return 0;
            case 49:  doMatch(colorImg); break;
            case 50:  doDetect(colorImg); break;
            case 51:  doAR(colorImg); break;
        }
        imshow("HUD", colorImg);
    }
    return 0;
}
edit flag offensive delete link more

Comments

Thank you. I just realised I didn't really need to use threads.

kimchiboy03 gravatar imagekimchiboy03 ( 2017-10-08 00:30:19 -0600 )edit

why you don't need to use threads?

jsxyhelu gravatar imagejsxyhelu ( 2017-10-08 09:53:29 -0600 )edit
1

@jsxyhelu, sure you can use threads, but be wise , where (or when) to apply those.

in this case, there is no need for it. it's more like the original design was broken

berak gravatar imageberak ( 2017-10-08 10:03:35 -0600 )edit

Question Tools

2 followers

Stats

Asked: 2017-10-06 00:17:48 -0600

Seen: 6,020 times

Last updated: Oct 07 '17