Subversion Repositories seema-scanner

Rev

Rev 81 | Rev 83 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 81 Rev 82
Line 219... Line 219...
219
 
219
 
220
    cv::Mat err_tau = b - (A*cv::Mat(tau));
220
    cv::Mat err_tau = b - (A*cv::Mat(tau));
221
    std::cout << err_tau << std::endl;
221
    std::cout << err_tau << std::endl;
222
}
222
}
223
 
223
 
-
 
224
// Function to solve for the rotation axis from sets of 3D point coordinates of flat pattern feature points
-
 
225
// Algorithm according to Chen et al., Rotation axis calibration of a turntable using constrained global optimization, Optik 2014
-
 
226
// DTU, 2014, Jakob Wilm
-
 
227
void rotationAxisCalibration(const std::vector< std::vector<cv::Point3f> > Qcam, const std::vector<cv::Point3f> Qobj, cv::Vec3f &axis, cv::Vec3f &point){
-
 
228
 
-
 
229
    // number of frames (points on each arch)
-
 
230
    int l = Qcam.size();
-
 
231
 
-
 
232
    // number of points in each frame
-
 
233
    int mn = Qobj.size();
-
 
234
 
-
 
235
    assert(mn == Qcam[0].size());
-
 
236
 
-
 
237
    // construct matrix for axis determination
-
 
238
    cv::Mat M(6, 6, CV_32F, cv::Scalar(0));
-
 
239
 
-
 
240
    for(int k=0; k<l; k++){
-
 
241
        for(int idx=0; idx<mn; idx++){
-
 
242
 
-
 
243
            float i = Qobj[idx].x+4;
-
 
244
            float j = Qobj[idx].y+4;
-
 
245
 
-
 
246
            float x = Qcam[k][idx].x;
-
 
247
            float y = Qcam[k][idx].y;
-
 
248
            float z = Qcam[k][idx].z;
-
 
249
 
-
 
250
            M += (cv::Mat_<float>(6,6) << x*x, x*y, x*z, x, i*x, j*x,
-
 
251
                                            0, y*y, y*z, y, i*y, j*y,
-
 
252
                                            0,   0, z*z, z, i*z, j*z,
-
 
253
                                            0,   0,   0, 1,   i,   j,
-
 
254
                                            0,   0,   0, 0, i*i, i*j,
-
 
255
                                            0,   0,   0, 0,   0, j*j);
-
 
256
 
-
 
257
        }
-
 
258
    }
-
 
259
//std::cout << M << std::endl;
-
 
260
    //M *= 1.0/(l*mn);
-
 
261
    cv::completeSymm(M, false);
-
 
262
//std::cout << M << std::endl;
-
 
263
    // solve for axis
-
 
264
    std::vector<float> lambda;
-
 
265
    cv::Mat u;
-
 
266
    cv::eigen(M, lambda, u);
-
 
267
 
-
 
268
    float minLambda = abs(lambda[0]);
-
 
269
    int idx = 0;
-
 
270
    for(int i=1; i<lambda.size(); i++){
-
 
271
        if(abs(lambda[i]) < minLambda){
-
 
272
            minLambda = lambda[i];
-
 
273
            idx = i;
-
 
274
        }
-
 
275
    }
-
 
276
 
-
 
277
std::cout << "u:" <<  u << std::endl;
-
 
278
 
-
 
279
    axis = u.row(idx).colRange(0, 3);
-
 
280
    axis /= cv::norm(axis);
-
 
281
 
-
 
282
    float nx = u.at<float>(5, 0);
-
 
283
    float ny = u.at<float>(5, 1);
-
 
284
    float nz = u.at<float>(5, 2);
-
 
285
    float d  = u.at<float>(5, 3);
-
 
286
    float dh = u.at<float>(5, 4);
-
 
287
    float dv = u.at<float>(5, 5);
-
 
288
 
-
 
289
    cv::Mat A(l*mn, mn+2, CV_32F, cv::Scalar(0.0));
-
 
290
    cv::Mat b(l*mn, 1, CV_32F);
-
 
291
 
-
 
292
    for(int k=0; k<l; k++){
-
 
293
        for(int idx=0; idx<mn; idx++){
-
 
294
 
-
 
295
            float i = Qobj[idx].x;
-
 
296
            float j = Qobj[idx].y;
-
 
297
 
-
 
298
            float x = Qcam[k][idx].x;
-
 
299
            float y = Qcam[k][idx].y;
-
 
300
            float z = Qcam[k][idx].z;
-
 
301
 
-
 
302
            float f = x*x + y*y + z*z + (2*x*nx + 2*y*ny + 2*z*nz)*(i*dh + j*dv);
-
 
303
 
-
 
304
            int row = k*mn+idx;
-
 
305
            A.at<float>(row, 0) = 2*x - (2*z*nx)/nz;
-
 
306
            A.at<float>(row, 1) = 2*y - (2*z*ny)/nz;
-
 
307
            A.at<float>(row, idx+2) = 1.0;
-
 
308
 
-
 
309
            b.at<float>(row, 0) = f + (2*z*d)/nz;
-
 
310
        }
-
 
311
    }
-
 
312
 
-
 
313
    // solve for point
-
 
314
    cv::Mat abe;
-
 
315
    cv::solve(A, b, abe, cv::DECOMP_SVD);
-
 
316
 
-
 
317
    point[0] = abe.at<float>(0, 0);
-
 
318
    point[1] = abe.at<float>(1, 0);
-
 
319
    point[2] = abe.at<float>(2, 0);
-
 
320
 
-
 
321
}
-
 
322
 
224
// Function to fit two sets of corresponding pose data.
323
// Function to fit two sets of corresponding pose data.
225
// Finds [Omega | tau], to minimize ||[R_mark | t_mark] - [Omega | tau][R | t]||^2
324
// Finds [Omega | tau], to minimize ||[R_mark | t_mark] - [Omega | tau][R | t]||^2
226
// Algorithm and notation according to Mili Shah, Comparing two sets of corresponding six degree of freedom data, CVIU 2011.
325
// Algorithm and notation according to Mili Shah, Comparing two sets of corresponding six degree of freedom data, CVIU 2011.
227
// DTU, 2013, Oline V. Olesen, Jakob Wilm
326
// DTU, 2013, Oline V. Olesen, Jakob Wilm
228
void fitSixDofData(const std::vector<cv::Matx33f> R, const std::vector<cv::Vec3f> t, const std::vector<cv::Matx33f> R_mark, const std::vector<cv::Vec3f> t_mark, cv::Matx33f &Omega, cv::Vec3f &tau){
327
void fitSixDofData(const std::vector<cv::Matx33f> R, const std::vector<cv::Vec3f> t, const std::vector<cv::Matx33f> R_mark, const std::vector<cv::Vec3f> t_mark, cv::Matx33f &Omega, cv::Vec3f &tau){