00001 #include "ccd_panin.h"
00002 using namespace cv;
00003 cv::Mat img1;
00004
00005 inline double ccd_det(uchar *ptr, int offset)
00006 {
00007 return ptr[offset+0]*(ptr[offset+4]*ptr[offset+8] - ptr[offset+5]*ptr[offset+7])
00008 *ptr[offset+1]*(ptr[offset+5]*ptr[offset+6] - ptr[offset+3]*ptr[offset+8])
00009 *ptr[offset+2]*(ptr[offset+3]*ptr[offset+7] - ptr[offset+4]*ptr[offset+6]);
00010 }
00011
00012 int main (int argc, char * argv[])
00013 {
00014
00015
00016
00017
00018
00019
00020
00021 const int resolution = 50;
00022
00023
00024 int t = 3;
00025
00026
00027
00028
00029
00030 img1 = imread("../data/ball.png", 1);
00031 cv::Mat img = imread("../data/ball.png", 1);
00032
00033
00034
00035
00036 CvPoint2D64f pts_tmp;
00037
00039
00041 cv::namedWindow("Original", 1);
00042
00043
00044 cv::imshow("Original", img1);
00045 char key ;
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 cv::Mat Sigma_Phi;
00063 Sigma_Phi = Mat::zeros(6,6, CV_64F);
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 cv::Mat mean_vic(resolution, 6, CV_64F);
00083
00084
00085
00086
00087
00088 cv::Mat cov_vic(resolution, 18, CV_64F);
00089
00090
00091
00092
00093 cv::Mat nabla_E(6,1, CV_64F);
00094
00095
00096
00097
00098 cv::Mat hessian_E(6,6, CV_64F);
00099
00100
00101 cv::Mat tmp_cov(3, 3, CV_64F);
00102
00103
00104 cv::Mat tmp_cov_inv(3,3, CV_64F);
00105
00106
00107 cv::Mat tmp_jacobian(6,3,CV_64F);
00108 cv::Mat tmp_pixel_diff(3,1,CV_64F);
00109
00110 cv::Mat nv(resolution, 2, CV_64F);
00111
00112
00113
00114 CvPoint tmp1, tmp2;
00115
00116
00117
00118 CvPoint2D64f tmp_dis1, tmp_dis2;
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 int h = 40, delta_h = 2;
00129
00130
00131
00132 double sigma_hat = h/2.5;
00133
00134
00135 double gamma_1 = 0.5, gamma_2 = 4, gamma_3 = 4;
00136
00137
00138 double sigma = sigma_hat/gamma_3;
00139
00140
00141
00142
00143 double kappa = 0.5;
00144
00145
00146
00147
00148
00149
00150
00151
00152 int normal_points_number = floor(h/delta_h);
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 cv::Mat vic(resolution, 20*normal_points_number, CV_64F);
00172
00173
00174
00175
00176
00177 cv::Mat normalized_param(resolution, 2, CV_64F);
00178
00179
00180
00181
00182
00183
00185 std::vector<CvPoint2D64f> pts;
00186 pts_tmp.x = 173, pts_tmp.y = 299;
00187 pts.push_back(pts_tmp);
00188 pts_tmp.x = 177, pts_tmp.y = 323;
00189 pts.push_back(pts_tmp);
00190 pts_tmp.x = 189, pts_tmp.y = 343;
00191 pts.push_back(pts_tmp);
00192 pts_tmp.x = 206, pts_tmp.y = 353;
00193 pts.push_back(pts_tmp);
00194 pts_tmp.x = 223, pts_tmp.y = 360;
00195 pts.push_back(pts_tmp);
00196 pts_tmp.x = 246, pts_tmp.y = 362;
00197 pts.push_back(pts_tmp);
00198 pts_tmp.x = 267, pts_tmp.y = 352;
00199 pts.push_back(pts_tmp);
00200 pts_tmp.x = 282, pts_tmp.y = 335;
00201 pts.push_back(pts_tmp);
00202 pts_tmp.x = 295, pts_tmp.y = 315;
00203 pts.push_back(pts_tmp);
00204 pts_tmp.x = 294, pts_tmp.y = 290;
00205 pts.push_back(pts_tmp);
00206 pts_tmp.x = 289, pts_tmp.y = 268;
00207 pts.push_back(pts_tmp);
00208 pts_tmp.x = 276, pts_tmp.y = 249;
00209 pts.push_back(pts_tmp);
00210 pts_tmp.x = 248, pts_tmp.y = 238;
00211 pts.push_back(pts_tmp);
00212 pts_tmp.x = 214, pts_tmp.y = 239;
00213 pts.push_back(pts_tmp);
00214 pts_tmp.x = 192, pts_tmp.y = 254;
00215 pts.push_back(pts_tmp);
00216 pts_tmp.x = 177, pts_tmp.y = 276;
00217 pts.push_back(pts_tmp);
00218 pts_tmp.x = 173, pts_tmp.y = 299;
00219 pts.push_back(pts_tmp);
00220 pts_tmp.x = 177, pts_tmp.y = 323;
00221 pts.push_back(pts_tmp);
00222 pts_tmp.x = 189, pts_tmp.y = 343;
00223 pts.push_back(pts_tmp);
00224
00225 std::cout<< "number of points: " << pts.size() << std::endl;
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 #ifdef DEBUG
00238 for (size_t i = 0; i < pts.size(); ++i)
00239 {
00240 std::cout<< pts[i].x << " " << pts[i].y << std::endl;
00241 }
00242 #endif
00243
00244
00245
00246
00247
00248 cv::Mat Phi = Mat::zeros(6,1, CV_64F);
00249
00250
00251
00252
00253
00254 cv::Mat delta_Phi = Mat::zeros(6,1, CV_64F);
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 for (int i = 0; i < 6; ++i)
00270 Phi.at<double>(i,0) = Phi.at<double>(i,0) - delta_Phi.at<double>(i,0);
00271
00272 for (size_t i = 0; i < pts.size(); ++i)
00273 {
00274 pts_tmp.x = Phi.at<double>(0,0) + (1+Phi.at<double>(2,0))*pts[i].x + Phi.at<double>(5,0)*pts[i].y;
00275 pts_tmp.y = Phi.at<double>(1,0) + (1+Phi.at<double>(3,0))*pts[i].y + Phi.at<double>(4,0)*pts[i].x;
00276
00277 pts[i].x = round(pts_tmp.x);
00278 pts[i].y = round(pts_tmp.y);
00279 }
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00295
00296
00297
00298
00299 for (size_t i = 0; i < pts.size(); ++i)
00300 {
00301
00302
00303
00304
00305
00306 pts_tmp.x = Phi.at<double>(0,0) + (1+Phi.at<double>(2,0))*pts[i].x + Phi.at<double>(5,0)*pts[i].y;
00307 pts_tmp.y = Phi.at<double>(1,0) + (1+Phi.at<double>(3,0))*pts[i].y + Phi.at<double>(4,0)*pts[i].x;
00308 pts[i].x = round(pts_tmp.x);
00309 pts[i].y = round(pts_tmp.y);
00310 }
00311
00312 nv = Mat::zeros(resolution, 2, CV_64F);
00313 mean_vic = Mat::zeros(resolution, 6, CV_64F);
00314 cov_vic = Mat::zeros(resolution, 18, CV_64F);
00315 nabla_E = Mat::zeros(6,1, CV_64F);
00316 hessian_E = Mat::zeros(6,6, CV_64F);
00317
00318
00319
00320
00321
00322
00323 BSpline bs(t , resolution, pts);
00324
00325
00326
00327
00328
00329
00330
00331
00332 for(int i=0;i < resolution;i++)
00333 {
00334
00335 cv::circle( img1, bs[i], 2, CV_RGB(0,0, 255),2);
00336
00337 #ifdef DEBUG
00338 std::cout << bs[i].x << " " << bs[i].y << std::endl;
00339
00340 #endif
00341
00342
00343
00344 nv.at<double>(i,0) = -bs.dt(i).y/cvSqrt(bs.dt(i).x*bs.dt(i).x + bs.dt(i).y*bs.dt(i).y);
00345 nv.at<double>(i,1) = bs.dt(i).x/cvSqrt(bs.dt(i).x*bs.dt(i).x + bs.dt(i).y*bs.dt(i).y);
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357 int k = 0;
00358 double alpha = 0.5;
00359 for (int j = delta_h; j <= h; j+=delta_h, k++)
00360 {
00362
00364
00365
00366 tmp1.x = round(bs[i].x + j*nv.at<double>(i,0));
00367
00368
00369 tmp1.y = round(bs[i].y + j*nv.at<double>(i,1));
00370
00371
00372
00373 tmp_dis1.x = (tmp1.x-bs[i].x)*nv.at<double>(i,0) + (tmp1.y-bs[i].y)*nv.at<double>(i,1);
00374
00375
00376
00377 tmp_dis1.y = (tmp1.x-bs[i].x)*nv.at<double>(i,1) - (tmp1.y-bs[i].y)*nv.at<double>(i,0);
00378
00379 vic.at<double>(i,10*k + 0) = tmp1.y;
00380 vic.at<double>(i,10*k + 1) = tmp1.x;
00381 vic.at<double>(i,10*k + 2) = tmp_dis1.x;
00382 vic.at<double>(i,10*k + 3) = tmp_dis1.y;
00383
00384
00385 vic.at<double>(i,10*k + 4) = 0.5*(erf((tmp_dis1.x)/(sqrt(2)*sigma)) + 1);
00386
00387
00388 double wp1 = (vic.at<double>(i,10*k + 4) - gamma_1)/(1-gamma_1);
00389
00390
00391 vic.at<double>(i,10*k + 5) = wp1*wp1*wp1*wp1;
00392
00393
00394
00395 double wp2 = (1-vic.at<double>(i,10*k + 4) - 0.25);
00396 vic.at<double>(i,10*k + 6) = -64*wp2*wp2*wp2*wp2 + 0.25;
00397
00398
00399 vic.at<double>(i,10*k + 7) = max((exp(-0.5*tmp_dis1.x*tmp_dis1.x/(sigma_hat*sigma_hat)) - exp(-gamma_2)), 0.0);
00400
00401
00402 vic.at<double>(i, 10*k + 8) = 0.5*exp(-abs(tmp_dis1.y)/alpha)/alpha;
00403
00404
00405 vic.at<double>(i, 10*k + 9) = exp(-tmp_dis1.x*tmp_dis1.x/(2*sigma*sigma))/(sqrt(2*CV_PI)*sigma);
00406
00407
00408 normalized_param.at<double>(i, 0) += vic.at<double>(i, 10*k + 7);
00409
00410 #ifdef DEBUG
00411 if(i == 0)
00412 std::cout << "tmp1 " << tmp1.x << " " << tmp1.y << std::endl;
00413 #endif
00414
00415
00416
00418
00420 tmp2.x = round(bs[i].x - j*nv.at<double>(i,0));
00421 tmp2.y = round(bs[i].y - j*nv.at<double>(i,1));
00422
00423 #ifdef DEBUG
00424 if(i == 0)
00425 std::cout << "tmp2 " << tmp2.x << " " << tmp2.y << std::endl;
00426 #endif
00427
00428
00429 tmp_dis2.x = (tmp2.x-bs[i].x)*nv.at<double>(i,0) + (tmp2.y-bs[i].y)*nv.at<double>(i,1);
00430 tmp_dis2.y = (tmp2.x-bs[i].x)*nv.at<double>(i,1) - (tmp2.y-bs[i].y)*nv.at<double>(i,0);
00431 int negative_normal = k+normal_points_number;
00432 vic.at<double>(i,10*negative_normal + 0) = tmp2.y;
00433 vic.at<double>(i,10*negative_normal + 1) = tmp2.x;
00434 vic.at<double>(i,10*negative_normal + 2) = tmp_dis2.x;
00435 vic.at<double>(i,10*negative_normal + 3) = tmp_dis2.y;
00436 vic.at<double>(i,10*negative_normal + 4) = 0.5*(erf(tmp_dis2.x/(cvSqrt(2)*sigma)) + 1);
00437 wp1 = (vic.at<double>(i,10*negative_normal + 4) - 0.25);
00438 vic.at<double>(i,10*negative_normal + 5) = -64*wp1*wp1*wp1*wp1 + 0.25;
00439 wp2 = (1 - vic.at<double>(i,10*negative_normal + 4) - gamma_1)/(1-gamma_1);
00440 vic.at<double>(i,10*negative_normal + 6) = wp2*wp2*wp2*wp2;
00441 vic.at<double>(i,10*negative_normal + 7) = max((exp(-0.5*vic.at<double>(i,10*negative_normal + 2)*vic.at<double>(i,10*negative_normal + 2)/(sigma_hat*sigma_hat)) - exp(-gamma_2)), 0.0);
00442 vic.at<double>(i, 10*negative_normal + 8) = 0.5*exp(-abs(tmp_dis2.x)/alpha)/alpha;
00443 vic.at<double>(i, 10*negative_normal + 9) = exp(-tmp_dis2.x*tmp_dis2.x/(2*sigma*sigma))/(sqrt(2*CV_PI)*sigma);
00444
00445 normalized_param.at<double>(i, 1) += vic.at<double>(i, 10*negative_normal + 7);
00446
00447 }
00448 }
00449
00450
00451
00452 printf("%-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s %-5s\n",
00453 "x", "y", "dist_x", "dist_y", "a", "w1^4", "w2^4", "prox", "edf", "erf'"
00454 );
00455 for (int i = 0; i < 20*normal_points_number; ++i)
00456 {
00457
00458 printf("%-5f ", vic.at<double>(0,i));
00459 if((i+1)%10 == 0)
00460 std::cout << std::endl;
00461 }
00462
00463
00465
00466 cv::imshow("Original", img1);
00467
00468
00469 while (1)
00470 {
00471 key = cvWaitKey(10);
00472 if (key == 27) break;
00473 }
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490 for (int i = 0; i < resolution; ++i)
00491 {
00492 int k = 0;
00493
00494 double w1 =0.0 , w2 = 0.0;
00495
00496
00497 vector<double> m1(3,0.0), m2(3,0.0);
00498
00499
00500 vector<double> m1_o2(9,0.0), m2_o2(9,0.0);
00501
00503
00504
00505
00506 for (int j = delta_h; j <= h; j+=delta_h, k++)
00507 {
00508 double wp1 = 0.0, wp2 = 0.0;
00509
00510 int negative_normal = k + normal_points_number;
00511
00512
00513 wp1 = vic.at<double>(i, 10*k+ 5)*vic.at<double>(i, 10*k+ 7)*vic.at<double>(i, 10*k+ 8) / normalized_param.at<double>(i,0);
00514
00515
00516 wp2 = vic.at<double>(i, 10*k+ 6)*vic.at<double>(i, 10*k+ 7)*vic.at<double>(i, 10*k+ 8) / normalized_param.at<double>(i,1);
00517
00518
00519 w1 += wp1;
00520
00521
00522 w2 += wp2;
00523
00524
00525
00526 m1[0] += wp1*img.at<Vec3b>(vic.at<double>(i, 10*k + 0 ), vic.at<double>(i, 10*k + 1 ))[0];
00527 m1[1] += wp1*img.at<Vec3b>(vic.at<double>(i, 10*k + 0 ), vic.at<double>(i, 10*k + 1 ))[1];
00528 m1[2] += wp1*img.at<Vec3b>(vic.at<double>(i, 10*k + 0 ), vic.at<double>(i, 10*k + 1 ))[2];
00529 m2[0] += wp2*img.at<Vec3b>(vic.at<double>(i, 10*k + 0 ), vic.at<double>(i, 10*k + 1 ))[0];
00530 m2[1] += wp2*img.at<Vec3b>(vic.at<double>(i, 10*k + 0 ), vic.at<double>(i, 10*k + 1 ))[1];
00531 m2[2] += wp2*img.at<Vec3b>(vic.at<double>(i, 10*k + 0 ), vic.at<double>(i, 10*k + 1 ))[2];
00532
00533
00534
00535
00536 for (int m = 0; m < 3; ++m)
00537 {
00538 for (int n =0; n < 3; ++n)
00539 {
00540 m1_o2[m*3+n] += wp1*img.at<Vec3b>(vic.at<double>(i, 10*k + 0 ), vic.at<double>(i, 10*k + 1 ))[m]
00541 *img.at<Vec3b>(vic.at<double>(i, 10*k + 0 ), vic.at<double>(i, 10*k + 1 ))[n];
00542 m2_o2[m*3+n] += wp2*img.at<Vec3b>(vic.at<double>(i, 10*k + 0 ), vic.at<double>(i, 10*k + 1 ))[m]
00543 *img.at<Vec3b>(vic.at<double>(i, 10*k + 0 ), vic.at<double>(i, 10*k + 1 ))[n];
00544 }
00545 }
00546
00547 wp2 = vic.at<double>(i, 10*negative_normal+ 5)*vic.at<double>(i, 10*negative_normal+ 7)*vic.at<double>(i, 10*negative_normal+ 8);
00548 wp1 = vic.at<double>(i, 10*negative_normal+ 6)*vic.at<double>(i, 10*negative_normal+ 7)*vic.at<double>(i, 10*negative_normal+ 8);
00549
00550 w1 += wp1;
00551 w2 += wp2;
00552
00553 m1[0] += wp1*img.at<Vec3b>(vic.at<double>(i, 10*negative_normal + 0 ), vic.at<double>(i, 10*negative_normal + 1 ))[0];
00554 m1[1] += wp1*img.at<Vec3b>(vic.at<double>(i, 10*negative_normal + 0 ), vic.at<double>(i, 10*negative_normal + 1 ))[1];
00555 m1[2] += wp1*img.at<Vec3b>(vic.at<double>(i, 10*negative_normal + 0 ), vic.at<double>(i, 10*negative_normal + 1 ))[2];
00556 m2[0] += wp2*img.at<Vec3b>(vic.at<double>(i, 10*negative_normal + 0 ), vic.at<double>(i, 10*negative_normal + 1 ))[0];
00557 m2[1] += wp2*img.at<Vec3b>(vic.at<double>(i, 10*negative_normal + 0 ), vic.at<double>(i, 10*negative_normal + 1 ))[1];
00558 m2[2] += wp2*img.at<Vec3b>(vic.at<double>(i, 10*negative_normal + 0 ), vic.at<double>(i, 10*negative_normal + 1 ))[2];
00559
00560 for (int m = 0; m < 3; ++m)
00561 {
00562 for (int n =0; n < 3; ++n)
00563 {
00564 m1_o2[m*3+n] += wp1*img.at<Vec3b>(vic.at<double>(i, 10*negative_normal + 0 ), vic.at<double>(i, 10*negative_normal + 1 ))[m]
00565 *img.at<Vec3b>(vic.at<double>(i, 10*negative_normal + 0 ), vic.at<double>(i, 10*negative_normal + 1 ))[n];
00566 m2_o2[m*3+n] += wp2*img.at<Vec3b>(vic.at<double>(i, 10*negative_normal + 0 ), vic.at<double>(i, 10*negative_normal + 1 ))[m]
00567 *img.at<Vec3b>(vic.at<double>(i, 10*negative_normal + 0 ), vic.at<double>(i, 10*negative_normal + 1 ))[n];
00568 }
00569 }
00570 }
00571
00572 mean_vic.at<double>(i, 0) = m1[0]/w1;
00573 mean_vic.at<double>(i, 1) = m1[1]/w1;
00574 mean_vic.at<double>(i, 2) = m1[2]/w1;
00575 mean_vic.at<double>(i, 3) = m2[0]/w2;
00576 mean_vic.at<double>(i, 4) = m2[1]/w2;
00577 mean_vic.at<double>(i, 5) = m2[2]/w2;
00578
00579 for (int m = 0; m < 3; ++m)
00580 {
00581 for (int n = 0 ; n < 3; ++n)
00582 {
00583 cov_vic.at<double>(i, m*3+n) = m1_o2[m*3+n]/w1 -m1[m]*m1[n]/(w1*w1);
00584 cov_vic.at<double>(i, 9+m*3+n) = m2_o2[m*3+n]/w2 -m2[m]*m2[n]/(w2*w2);
00585 if(m == n)
00586 {
00587 cov_vic.at<double>(i, m*3+n) += kappa;
00588 cov_vic.at<double>(i, 9+m*3+n) += kappa;
00589 }
00590 }
00591 }
00592 }
00593
00594
00595
00596 for (int i = 0; i < resolution; ++i)
00597 {
00598 std::cout << mean_vic.at<double>(i, 0) << " "
00599 << mean_vic.at<double>(i, 1) << " "
00600 << mean_vic.at<double>(i, 2) << " "
00601 << mean_vic.at<double>(i, 3) << " "
00602 << mean_vic.at<double>(i, 4) << " "
00603 << mean_vic.at<double>(i, 5) << " "
00604 << std::endl;
00605 }
00606
00608
00609 double cost1 = 0.0, cost2 = 0.0;
00610 for (int i = 0; i < resolution; ++i)
00611 {
00612 for (int j = 0; j < 2*normal_points_number; ++j)
00613 {
00614 tmp_cov = Mat::zeros(3,3,CV_64F);
00615 tmp_cov_inv = Mat::zeros(3,3,CV_64F);
00616
00617
00618 for (int m = 0; m < 3; ++m)
00619 {
00620 for (int n = 0; n < 3; ++n)
00621 {
00622 tmp_cov.at<double>(m, n) = vic.at<double>(i,10*j+4) * cov_vic.at<double>(i,m*3+n)
00623 +(1-vic.at<double>(i,10*j+4))* cov_vic.at<double>(i,m*3+n+9);
00624 }
00625 }
00626
00627 tmp_cov_inv = tmp_cov.inv(DECOMP_SVD);
00628 tmp_pixel_diff = Mat::zeros(3, 1, CV_64F);
00629
00630
00631
00632 for (int m = 0; m < 3; ++m)
00633 {
00634 tmp_pixel_diff.at<double>(m,0) = img.at<Vec3b>(vic.at<double>(i,10*j+0), vic.at<double>(i,10*j+1))[m]- vic.at<double>(i,10*j+4) * mean_vic.at<double>(i,m)- (1-vic.at<double>(i,10*j+4))* mean_vic.at<double>(i,m+3);
00635 }
00636
00637 cv::Mat tmp_res = Mat::zeros(1,1, CV_64F);
00638 tmp_res = tmp_pixel_diff.t()*tmp_cov_inv*tmp_pixel_diff;
00639 cost2 += exp(-0.5*tmp_res.at<double>(0,0))/cv::determinant(tmp_cov);
00640 }
00641 }
00642
00643 std::cout << "cost 2 : " << cost2 << std::endl;
00644
00645 Phi.release();
00646 delta_Phi.release();
00647
00648 return 0;
00649 }