-
Notifications
You must be signed in to change notification settings - Fork 36
/
match_two_curves.cpp
136 lines (106 loc) · 3.77 KB
/
match_two_curves.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
using namespace cv;
#include "CurveCSS.h"
#include "CurveSignature.h"
int main(int argc, char** argv) {
vector<Point> a,b;
Mat src = imread("deer-18.png");
if (src.empty()) {
cerr << "can't read image" << endl; exit(0);
}
GetCurveForImage(src, a, false);
ResampleCurve(a, a, 200, false);
vector<Point2d> a_p2d;
ConvertCurve(a, a_p2d);
//create the target curve
{
//rotate and scale
Scalar meanpt = mean(a);
Mat_<double> trans_to = getRotationMatrix2D(Point2f(meanpt[0],meanpt[1]), 5, 0.65);
//trasnlate
trans_to(0,2) += 40;
trans_to(1,2) += 40;
vector<Point2d> b_p2d;
cv::transform(a_p2d,b_p2d,trans_to);
// everybody in the house - make some noise!
cv::RNG rng(27628);
for (int i=0; i<b_p2d.size(); i++) {
b_p2d[i].x += (rng.uniform(0.0,1.0) - 0.5) * 20;
b_p2d[i].y += (rng.uniform(0.0,1.0) - 0.5) * 20;
}
ConvertCurve(b_p2d, b);
// occlude
vector<Point> b_occ;
for (int i=50; i<130; i++) {
b_occ.push_back(b[i]);
}
ResampleCurve(b_occ, b, 200, true);
}
//Compare curves
int a_len,a_off,b_len,b_off;
double db_compare_score;
CompareCurvesUsingSignatureDB(a,
b,
a_len,
a_off,
b_len,
b_off,
db_compare_score
);
//Get matched subsets of curves
vector<Point> a_subset(a.begin() + a_off, a.begin() + a_off + a_len);
vector<Point> b_subset(b.begin() + b_off, b.begin() + b_off + b_len);
//Normalize to equal length
ResampleCurve(a_subset, a_subset, 200, true);
ResampleCurve(b_subset, b_subset, 200, true);
//Visualize the original and target
Mat outout(src.size(),CV_8UC3,Scalar::all(0));
{
//draw small original
vector<Point2d> tmp_curve;
cv::transform(a_p2d,tmp_curve,getRotationMatrix2D(Point2f(0,0),0,0.2));
Mat tmp_curve_m(tmp_curve); tmp_curve_m += Scalar(25,0);
drawOpenCurve(outout, tmp_curve, Scalar(255), 1);
//draw small matched subset of original
ConvertCurve(a_subset, tmp_curve);
cv::transform(tmp_curve,tmp_curve,getRotationMatrix2D(Point2f(0,0),0,0.2));
Mat tmp_curve_m1(tmp_curve); tmp_curve_m1 += Scalar(25,0);
drawOpenCurve(outout, tmp_curve, Scalar(255,255), 2);
//draw small target
ConvertCurve(b, tmp_curve);
cv::transform(tmp_curve,tmp_curve,getRotationMatrix2D(Point2f(0,0),0,0.2));
Mat tmp_curve_m2(tmp_curve); tmp_curve_m2 += Scalar(outout.cols - 150,0);
drawOpenCurve(outout, tmp_curve, Scalar(255,0,255), 1);
//draw big target
drawOpenCurve(outout, b, Scalar(0,0,255), 1);
//draw big matched subset of target
drawOpenCurve(outout, b_subset, Scalar(0,255,255), 1);
}
//Prepare the curves for finding the transformation
vector<Point2f> seq_a_32f,seq_b_32f,seq_a_32f_,seq_b_32f_;
ConvertCurve(a_subset, seq_a_32f_);
ConvertCurve(b_subset, seq_b_32f_);
assert(seq_a_32f_.size() == seq_b_32f_.size());
seq_a_32f.clear(); seq_b_32f.clear();
for (int i=0; i<seq_a_32f_.size(); i++) {
// if(i%2 == 0) { // you can use only part of the points to find the transformation
seq_a_32f.push_back(seq_a_32f_[i]);
seq_b_32f.push_back(seq_b_32f_[i]);
// }
}
assert(seq_a_32f.size() == seq_b_32f.size()); //just making sure
vector<Point2d> seq_a_trans(a.size());
//Find the fitting transformation
// Mat affineT = estimateRigidTransform(seq_a_32f,seq_b_32f,false); //may wanna use Affine here..
Mat trans = Find2DRigidTransform(seq_a_32f, seq_b_32f);
cout << trans;
cv::transform(a_p2d,seq_a_trans,trans);
//draw the result matching : the complete original curve as matched to the target
drawOpenCurve(outout, seq_a_trans, Scalar(0,255,0), 2);
//May want to visualize point-by-point matching
// cv::transform(seq_a_32f,seq_a_32f,trans);
// for (int i=0; i<seq_a_32f.size(); i++) {
// line(outout, seq_a_32f[i], seq_b_32f[i], Scalar(0,0,255), 1);
// }
imshow("outout", outout);
waitKey();
}