Ask Your Question
0

flip and thread play Video error

asked 2016-11-05 05:13:00 -0600

Mike Kao gravatar image

updated 2016-11-05 08:46:59 -0600

berak gravatar image

Hi,

I have a function(assume the function is A) that capture image from my webcam, and another function play a video (assume the function is B). Both of them can run independently well. but when I mix them by using thread mThead(B) in function A. The B function will fail. 
I have found that in function A if I execute the flip(...), the program can run into function B but it cannot play the video. If without flip(), the function B will correctly run.

Is there anyone know what happen to this? And how can I fix it?

Thank you very much.

This is some of my code:

using namespace cv;
using namespace std;

// Global variables
Mat frame; //current frame
int keyboard; //input from keyboard

void processVideo();
void playVideo();

int main()
{

    //create GUI windows
    namedWindow("Frame");
    processVideo();

    //destroy GUI windows
    destroyAllWindows();
    return EXIT_SUCCESS;
}

void playVideo(){
    VideoCapture cap("A.avi");
    Mat myframe;

    if (!cap.isOpened()) {
        cout << "Cannot open the video file on C++ API" << std::endl;
        exit(EXIT_FAILURE);
    }

    for (;;) {
        cap >> myframe;
        if (myframe.empty())
            break;
        imshow("Video Frame", myframe);
        int c = waitKey(10);
        if ((char)c == 27) { break; }
    }
    cap.release();
}

void processVideo() {
    Mat dst;

    //create the capture object
    VideoCapture cap(0);
    //open capture
    if (!cap.isOpened()){
        cout << "Open camera failed";
        exit(EXIT_FAILURE);
    }

    //read input data. ESC or 'q' for quitting
    while ((char)keyboard != 'q' && (char)keyboard != 27){
        //read the current frame
        if (!cap.read(dst)) {
            cerr << "Unable to read next frame." << endl;
            cerr << "Exiting..." << endl;
            exit(EXIT_FAILURE);
        }

        flip(dst, frame, 1);   //something image processing

        if (condition is true){
            thread mThread(playVideo);
            // wait the thread stop
            mThread.join();
        }

        //show the current frame and the fg masks
        imshow("Frame", frame);

        //get the input from the keyboard
        keyboard = waitKey(30);
    }

    //delete capture object
    cap.release();
}
edit retag flag offensive close merge delete

Comments

can you show your code ?

(also, try to avoid naive multi-threading as much as possible. neither the capture(youhave to wait for it, so no gain), nor the gui(you're messing with your os there) should go into a thread)

berak gravatar imageberak ( 2016-11-05 06:26:00 -0600 )edit

again, you should NOT use multi-threading here, simply.

berak gravatar imageberak ( 2016-11-05 08:29:54 -0600 )edit
1

all I need is performing some image processing and when some condition happens, it play a video, but the processing should continue. So, can you give me any advice? Thank you much. I'm a newer for OpenCV.

Mike Kao gravatar imageMike Kao ( 2016-11-05 08:40:23 -0600 )edit

ah, good to know. then, let's see, how it can be simplified, and running in a single thread !

btw, how do you get your condition ?

berak gravatar imageberak ( 2016-11-05 08:44:50 -0600 )edit

I count a variable, when this variable is greater than a threshold, the condition is true. btw, this variable will be reset when it has called the playVideo().

Mike Kao gravatar imageMike Kao ( 2016-11-05 09:00:54 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2016-11-05 09:26:14 -0600

berak gravatar image

updated 2016-11-05 09:27:25 -0600

you can do all of this in the main thread:

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;


int err(String message) {
    cout << message << endl;
    return (1);
}

int main()
{
    VideoCapture playback("A.avi"); // playback video
    if (!playback.isOpened()) return err("playback did not open");
    VideoCapture cam(0); // camera
    if (!cam.isOpened()) return err("camera did not open");

    // create GUI windows
    namedWindow("Frame");
    namedWindow("Video Frame");

    // please *avoid* Global variables
    Mat cam_frame, pb_frame; // current frames
    int keyboard = 0; // input from keyboard (raii)
    bool condition = false; // ???
    while ((char)keyboard != 'q' && (char)keyboard != 27) {
        cam >> cam_frame;
        if (cam_frame.empty())
            break;

        flip(cam_frame, cam_frame, 1);

        // no idea, what you have in mind, i'll use the space bar:
        if (keyboard==' ') condition = ! condition;
        if (condition) {
            playback >> pb_frame;
            if (pb_frame.empty()) { // end of movie, what now ? just rewind ?
                playback.set(CAP_PROP_POS_FRAMES, 0);
            } else { // only show, if valid
                imshow("Video Frame", pb_frame);
            }
        }

        imshow("Frame", cam_frame);
        keyboard = waitKey(30);
    }

    //destroy GUI windows
    destroyAllWindows();
    return EXIT_SUCCESS;
}
edit flag offensive delete link more

Comments

Dear berak, It do capture from cam and play Video simultaneously, thank you.But there is a little difference, each time when the condition is true, I want to play the video entirely, not only play a frame. Thanks again.

I have isolated the playVideo into a function. It can work, but when the playVideo function is playing, the while loop in main is suspended. How can I run playVideo function and no-suspend the mail loop?

Mike Kao gravatar imageMike Kao ( 2016-11-06 01:04:03 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2016-11-05 05:13:00 -0600

Seen: 233 times

Last updated: Nov 05 '16