bazar  1.3.1
affinity.cpp
Go to the documentation of this file.
1 /*
2 Copyright 2005, 2006 Computer Vision Lab,
3 Ecole Polytechnique Federale de Lausanne (EPFL), Switzerland.
4 All rights reserved.
5 
6 This file is part of BazAR.
7 
8 BazAR is free software; you can redistribute it and/or modify it under the
9 terms of the GNU General Public License as published by the Free Software
10 Foundation; either version 2 of the License, or (at your option) any later
11 version.
12 
13 BazAR is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
15 PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License along with
18 BazAR; if not, write to the Free Software Foundation, Inc., 51 Franklin
19 Street, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21 #include "affinity.h"
22 
23 
25 {
26  initialize();
27 }
28 
29 affinity::affinity(float u1, float v1, float up1, float vp1,
30  float u2, float v2, float up2, float vp2,
31  float u3, float v3, float up3, float vp3)
32 {
33  initialize();
34 
35  estimate(u1, v1, up1, vp1,
36  u2, v2, up2, vp2,
37  u3, v3, up3, vp3);
38 }
39 
40 void affinity::initialize(void)
41 {
42  AA = cvCreateMat(6, 6, CV_32FC1);
43  X = cvCreateMat(6, 1, CV_32FC1);
44  B = cvCreateMat(6, 1, CV_32FC1);
45  type = CV_32FC1;
46 
47  type = CV_MAT_MAGIC_VAL | CV_MAT_CONT_FLAG | CV_MAT_TYPE(type);
48  cols = 3;
49  rows = 3;
50  step = cols * CV_ELEM_SIZE(type);
51  data.ptr = (uchar*)new float[cols * rows];
52  refcount = NULL;
53 
54  cvmSet(2, 0, 0.);
55  cvmSet(2, 1, 0.);
56  cvmSet(2, 2, 1.);
57 }
58 
60 {
61  cvReleaseMat(&AA);
62  cvReleaseMat(&X);
63  cvReleaseMat(&B);
64  delete [] data.ptr;
65 }
66 
67 ostream& operator<< (ostream& o, const affinity& A)
68 {
69  o << cvmGet(&A, 0, 0) << "\t" << cvmGet(&A, 0, 1) << "\t" << cvmGet(&A, 0, 2) << endl;
70  o << cvmGet(&A, 1, 0) << "\t" << cvmGet(&A, 1, 1) << "\t" << cvmGet(&A, 1, 2) << endl;
71 
72  return o;
73 }
74 
75 bool affinity::estimate(float u1, float v1, float up1, float vp1,
76  float u2, float v2, float up2, float vp2,
77  float u3, float v3, float up3, float vp3)
78 {
79  ::cvmSet(AA, 0, 0, u1); ::cvmSet(AA, 0, 1, v1); ::cvmSet(AA, 0, 2, 1.); ::cvmSet(AA, 0, 3, 0.); ::cvmSet(AA, 0, 4, 0.); ::cvmSet(AA, 0, 5, 0.);
80  ::cvmSet(AA, 1, 0, 0.); ::cvmSet(AA, 1, 1, 0.); ::cvmSet(AA, 1, 2, 0.); ::cvmSet(AA, 1, 3, u1); ::cvmSet(AA, 1, 4, v1); ::cvmSet(AA, 1, 5, 1.);
81 
82  ::cvmSet(AA, 2, 0, u2); ::cvmSet(AA, 2, 1, v2); ::cvmSet(AA, 2, 2, 1.); ::cvmSet(AA, 2, 3, 0.); ::cvmSet(AA, 2, 4, 0.); ::cvmSet(AA, 2, 5, 0.);
83  ::cvmSet(AA, 3, 0, 0.); ::cvmSet(AA, 3, 1, 0.); ::cvmSet(AA, 3, 2, 0.); ::cvmSet(AA, 3, 3, u2); ::cvmSet(AA, 3, 4, v2); ::cvmSet(AA, 3, 5, 1.);
84 
85  ::cvmSet(AA, 4, 0, u3); ::cvmSet(AA, 4, 1, v3); ::cvmSet(AA, 4, 2, 1.); ::cvmSet(AA, 4, 3, 0.); ::cvmSet(AA, 4, 4, 0.); ::cvmSet(AA, 4, 5, 0.);
86  ::cvmSet(AA, 5, 0, 0.); ::cvmSet(AA, 5, 1, 0.); ::cvmSet(AA, 5, 2, 0.); ::cvmSet(AA, 5, 3, u3); ::cvmSet(AA, 5, 4, v3); ::cvmSet(AA, 5, 5, 1.);
87 
88  ::cvmSet(B, 0, 0, up1);
89  ::cvmSet(B, 1, 0, vp1);
90 
91  ::cvmSet(B, 2, 0, up2);
92  ::cvmSet(B, 3, 0, vp2);
93 
94  ::cvmSet(B, 4, 0, up3);
95  ::cvmSet(B, 5, 0, vp3);
96 
97  int ok = cvSolve(AA, B, X, CV_SVD);
98 
99  if (ok != 1)
100  {
101  cerr << "affinity::estimate: cvSolve failure" << endl;
102  return false;
103  }
104 
105  cvmSet(0, 0, ::cvmGet(X, 0, 0));
106  cvmSet(0, 1, ::cvmGet(X, 1, 0));
107  cvmSet(0, 2, ::cvmGet(X, 2, 0));
108 
109  cvmSet(1, 0, ::cvmGet(X, 3, 0));
110  cvmSet(1, 1, ::cvmGet(X, 4, 0));
111  cvmSet(1, 2, ::cvmGet(X, 5, 0));
112 
113  return true;
114 }
115 
116 void affinity::transform_point(float u, float v, float * up, float * vp)
117 {
118  *up = float(cvmGet(0, 0) * u + cvmGet(0, 1) * v + cvmGet(0, 2));
119  *vp = float(cvmGet(1, 0) * u + cvmGet(1, 1) * v + cvmGet(1, 2));
120 }
121 
122 void affinity::transform_point(double u, double v, double * up, double * vp)
123 {
124  *up = cvmGet(0, 0) * u + cvmGet(0, 1) * v + cvmGet(0, 2);
125  *vp = cvmGet(1, 0) * u + cvmGet(1, 1) * v + cvmGet(1, 2);
126 }
127 
129 {
130  float det = float(cvmGet(0, 0) * cvmGet(1, 1) - cvmGet(1, 0) * cvmGet(0, 1));
131 
132  ::cvmSet(A_q, 0, 0, cvmGet(1, 1) / det);
133  ::cvmSet(A_q, 0, 1, -cvmGet(0, 1) / det);
134  ::cvmSet(A_q, 1, 0, -cvmGet(1, 0) / det);
135  ::cvmSet(A_q, 1, 1, cvmGet(0, 0) / det);
136 
137  ::cvmSet(A_q, 0, 2, ::cvmGet(A_q, 0, 0) * (w / 2 - cvmGet(0, 2)) + ::cvmGet(A_q, 0, 1) * (h / 2 - cvmGet(1, 2)));
138  ::cvmSet(A_q, 1, 2, ::cvmGet(A_q, 1, 0) * (w / 2 - cvmGet(0, 2)) + ::cvmGet(A_q, 1, 1) * (h / 2 - cvmGet(1, 2)));
139 }
140 
141 void mcvGetQuadrangleSubPix(IplImage * src, IplImage * dest, affinity * A,
142  int /*fill_outliers*/, CvScalar /*fill_value*/)
143 {
144  A->rows = 2;
145  cvGetQuadrangleSubPix(src, dest, A);
146  A->rows = 3;
147 }
148