1 #include <opencv2/opencv.hpp>
2 #include <opencv2/dnn.hpp>
3 #include <iostream>
4
5 using namespace cv;
6 using namespace cv::dnn;
7 using namespace std;
8
9 String goturn_model = "D:/opencv3.3/opencv/sources/samples/data/dnn/goturn.caffemodel";
10 String goturn_prototxt = "D:/opencv3.3/opencv/sources/samples/data/dnn/goturn.prototxt";
11
12 Net net;
13 void initGoturn();
14 Rect trackObjects(Mat& frame, Mat& prevFrame);
15 Mat frame, prevFrame;
16 Rect prevBB;
17 int main(int argc, char** argv) {
18 initGoturn();
19 VideoCapture capture;
20 capture.open("01.mp4");
21 capture.read(frame);
22 frame.copyTo(prevFrame);
23 prevBB = selectROI(frame, true, true);
24 namedWindow("frame", CV_WINDOW_AUTOSIZE);
25 while (capture.read(frame)) {
26 Rect currentBB = trackObjects(frame, prevFrame);
27 rectangle(frame, currentBB, Scalar(0, 0, 255), 2, 8, 0);
28
29 // ready for next frame
30 frame.copyTo(prevFrame);
31 prevBB.x = currentBB.x;
32 prevBB.y = currentBB.y;
33 prevBB.width = currentBB.width;
34 prevBB.height = currentBB.height;
35
36 imshow("frame", frame);
37 char c = waitKey(50);
38 if (c == 27) {
39 break;
40 }
41 }
42 }
43
44 void initGoturn() {
45 Ptr<Importer> importer;
46 importer = createCaffeImporter(goturn_prototxt, goturn_model);
47 importer->populateNet(net);
48 importer.release();
49 }
50
51 Rect trackObjects(Mat& frame, Mat& prevFrame) {
52 Rect rect;
53 int INPUT_SIZE = 227;
54 //Using prevFrame & prevBB from model and curFrame GOTURN calculating curBB
55 Mat curFrame = frame.clone();
56 Rect2d curBB;
57
58 float padTargetPatch = 2.0;
59 Rect2f searchPatchRect, targetPatchRect;
60 Point2f currCenter, prevCenter;
61 Mat prevFramePadded, curFramePadded;
62 Mat searchPatch, targetPatch;
63
64 prevCenter.x = (float)(prevBB.x + prevBB.width / 2);
65 prevCenter.y = (float)(prevBB.y + prevBB.height / 2);
66
67 targetPatchRect.width = (float)(prevBB.width * padTargetPatch);
68 targetPatchRect.height = (float)(prevBB.height * padTargetPatch);
69 targetPatchRect.x = (float)(prevCenter.x - prevBB.width * padTargetPatch / 2.0 + targetPatchRect.width);
70 targetPatchRect.y = (float)(prevCenter.y - prevBB.height * padTargetPatch / 2.0 + targetPatchRect.height);
71
72 copyMakeBorder(prevFrame, prevFramePadded, (int)targetPatchRect.height, (int)targetPatchRect.height, (int)targetPatchRect.width, (int)targetPatchRect.width, BORDER_REPLICATE);
73 targetPatch = prevFramePadded(targetPatchRect).clone();
74
75 copyMakeBorder(curFrame, curFramePadded, (int)targetPatchRect.height, (int)targetPatchRect.height, (int)targetPatchRect.width, (int)targetPatchRect.width, BORDER_REPLICATE);
76 searchPatch = curFramePadded(targetPatchRect).clone();
77
78 //Preprocess
79 //Resize
80 resize(targetPatch, targetPatch, Size(INPUT_SIZE, INPUT_SIZE));
81 resize(searchPatch, searchPatch, Size(INPUT_SIZE, INPUT_SIZE));
82
83 //Mean Subtract
84 targetPatch = targetPatch - 128;
85 searchPatch = searchPatch - 128;
86
87 //Convert to Float type
88 targetPatch.convertTo(targetPatch, CV_32F);
89 searchPatch.convertTo(searchPatch, CV_32F);
90
91 Mat targetBlob = blobFromImage(targetPatch);
92 Mat searchBlob = blobFromImage(searchPatch);
93
94 net.setInput(targetBlob, ".data1");
95 net.setInput(searchBlob, ".data2");
96
97 Mat res = net.forward("scale");
98 Mat resMat = res.reshape(1, 1);
99 //printf("width : %d, height : %d\n", (resMat.at<float>(2) - resMat.at<float>(0)), (resMat.at<float>(3) - resMat.at<float>(1)));
100
101 curBB.x = targetPatchRect.x + (resMat.at<float>(0) * targetPatchRect.width / INPUT_SIZE) - targetPatchRect.width;
102 curBB.y = targetPatchRect.y + (resMat.at<float>(1) * targetPatchRect.height / INPUT_SIZE) - targetPatchRect.height;
103 curBB.width = (resMat.at<float>(2) - resMat.at<float>(0)) * targetPatchRect.width / INPUT_SIZE;
104 curBB.height = (resMat.at<float>(3) - resMat.at<float>(1)) * targetPatchRect.height / INPUT_SIZE;
105
106 //Predicted BB
107 Rect boundingBox = curBB;
108 return boundingBox;
109 }