temp.cpp
1 | |
---|---|
2 | #include <iostream> |
3 | #include "opencv2/highgui/highgui.hpp" |
4 | #include <opencv2/core/core.hpp> |
5 | #include <opencv2/imgproc/imgproc.hpp> |
6 | #include <string> |
7 | #include <thread> |
8 | #include <mutex> |
9 | |
10 | using namespace std; |
11 | using namespace cv; |
12 | //The main canvas (a background image)
|
13 | Mat canvas=imread("canvas.jpg", CV_LOAD_IMAGE_COLOR);
|
14 | // the mutex for accessing the canvas variable
|
15 | mutex mu; |
16 | // The function that plays a video on a predefined ROI on the canvas
|
17 | void play(string n, Point p) //this function could be called n number of times as its own thread |
18 | { |
19 | VideoCapture cap(n); //open a local video file
|
20 | int fps=cap.get(CV_CAP_PROP_FPS); // get it's frames per-seconds frame rates |
21 | char k; // for exiting the frame fetching loop |
22 | Mat temp; // a temporary holding variable for each frame from the stream
|
23 | while(1) |
24 | { |
25 | unique_lock<mutex> locker(mu); // lock the mutex (shared memory is the canvas matrix)
|
26 | cap>>temp; // get a frame from the stream to the temporary buffer
|
27 | if(temp.empty())// if stream is empty get out of this loop |
28 | { |
29 | locker.unlock(); // unlock the mutex first before exiting this loop
|
30 | break; // exit the loop now. |
31 | } |
32 | // syntax= src_image.copyto(dst_image(Rect(Point(x,y), size(src_image))))
|
33 | //dest_image is the shared object between the threads.
|
34 | temp.copyTo(canvas(Rect(p.x, p.y, temp.cols, temp.rows))); // past a frame onto the canvas at location (x,y) and size(of the frame)
|
35 | locker.unlock();// done interacting with the shared variable, so unlock the mutex
|
36 | } |
37 | } |
38 | int main()
|
39 | { |
40 | char k; // for breaking out of the main loop ( the display image loop) |
41 | namedWindow("MainWindow", WINDOW_AUTOSIZE); // create the main window |
42 | // create and start the first thread, pass a filename and a coordinates to place the frame on the canvas
|
43 | thread P1(play, "video-copy.mp4", Point(0,0)); |
44 | // create and start the second thread, they should both be able to access the canvas variable (one at a time ofcourse)
|
45 | thread P2(play, "video.mp4", Point(200,300)); |
46 | while(1) // keep displaying the canvas as it is changing. |
47 | { |
48 | |
49 | unique_lock<mutex> locker(mu); // lock the mutex again, because we are using the canvas (shared object) again,
|
50 | imshow("MainWindow", canvas); // show image |
51 | locker.unlock(); // unlock the mutex again.
|
52 | k=waitKey(10); // flush the buffer and wait for 10 milliseconds |
53 | if(k==27) //exit the display image loop. |
54 | break;
|
55 | } |
56 | // Join the child threads back with the parrent thread before exiting.
|
57 | P1.join(); |
58 | P2.join(); |
59 | //and finally
|
60 | destroyWindow("MainWindow"); // destroy the main window |
61 | return 0; // end the main. |
62 | } |
63 | /* The errors I always get but cant find what is causing it
|
64 | |
65 | (MainWindow:3157): GLib-GObject-CRITICAL **: g_object_remove_weak_pointer: assertion `G_IS_OBJECT (object)' failed |
66 | |
67 | |
68 | [NULL @ 0xb1b06ca0] insufficient thread locking around avcodec_open/close() |
69 | [NULL @ 0xb1b07aa0] insufficient thread locking around avcodec_open/close() |
70 | [NULL @ 0xb1b06ca0] insufficient thread locking around avcodec_open/close() |
71 | [NULL @ 0xb1b07aa0] insufficient thread locking around avcodec_open/close() |
72 | [IMGUTILS @ 0xb28fde64] Picture size 0x0 is invalid |
73 | [IMGUTILS @ 0xb28fde94] Picture size 0x0 is invalid |
74 | [swscaler @ 0xad180300] bad dst image pointers |
75 | |
76 | */ |