00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include <opencv/cv.h>
00042 #include <opencv/cvaux.h>
00043 #include <opencv/highgui.h>
00044 #include "ccd/auto_init.h"
00045 #include <iostream>
00046
00047 AutoInit::AutoInit():dp_extract_method(0),dp_match_method(0), inteval(0){}
00048 AutoInit::AutoInit(int dpem, int dpmm, int itv):dp_extract_method(dpem>=0 ? dpem : 0), dp_match_method(dpmm >= 0 ? dpmm : 0),inteval(itv){}
00049 void AutoInit::extract_descriptors(cv::Mat& tpl, cv::Mat& training_img)
00050 {
00051 cv::FeatureDetector *fd = 0;
00052 cv::DescriptorExtractor *de = 0;
00053 if(dp_extract_method == DP_EXTRACT_SIFT)
00054 {
00055 fd = new cv::SiftFeatureDetector(cv::SIFT::DetectorParams::GET_DEFAULT_THRESHOLD(),
00056 cv::SIFT::DetectorParams::GET_DEFAULT_EDGE_THRESHOLD());
00057
00058
00059
00060
00061
00062
00063 de = new cv::SiftDescriptorExtractor;
00064 }
00065 else if(dp_extract_method == DP_EXTRACT_SURF)
00066 {
00067 fd = new cv::SurfFeatureDetector(400);
00068 de = new cv::SurfDescriptorExtractor(4,2,false);
00069 }
00070 fd->detect(tpl, keypoints1);
00071 fd->detect(training_img, keypoints2);
00072 cv::Mat query;
00073 descriptors2.push_back(query);
00074
00075 de->compute( tpl, keypoints1, descriptors1);
00076 de->compute( training_img, keypoints2, descriptors2[0]);
00077 }
00078
00079 void AutoInit::match_descriptors()
00080 {
00081 cv::DescriptorMatcher *dm = 0;
00082 if(dp_match_method == DP_MATCH_FLANN)
00083 {
00084 dm = new cv::FlannBasedMatcher;
00085
00086
00087
00088 }
00089 else if(dp_match_method == DP_MATCH_BRUTE)
00090 {
00091 cv::BruteForceMatcher<cv::L2<float> > bfm;
00092 dm = &bfm;
00093 }
00094 dm->add(descriptors2);
00095 dm->train();
00096 dm->match(descriptors1, matches);
00097 std::cout << "Found total matches: " << matches.size() << std::endl;
00098 }
00099
00100 cv::Mat AutoInit::compute_homography(
00101 cv::Mat& tpl,
00102 cv::Mat& training_img)
00103 {
00104 cv::Mat points1 = cv::Mat(1,matches.size(),CV_64FC2);
00105 cv::Mat points2 = cv::Mat(1,matches.size(),CV_64FC2);
00106 cv::Mat_<cv::Vec2d>& ptr1 = (cv::Mat_<cv::Vec2d>&)points1;
00107 cv::Mat_<cv::Vec2d>& ptr2 = (cv::Mat_<cv::Vec2d>&)points2;
00108
00109 for (size_t i = 0; i < matches.size(); ++i)
00110 {
00111 ptr1(0, i)[0] = keypoints1[matches[i].queryIdx].pt.x;
00112 ptr1(0, i)[1] = keypoints1[matches[i].queryIdx].pt.y;
00113 ptr2(0, i)[0] = keypoints2[matches[i].trainIdx].pt.x;
00114 ptr2(0, i)[1] = keypoints2[matches[i].trainIdx].pt.y;
00115
00116
00117
00118 }
00119
00120
00121
00122
00123
00124 cv::Mat status;
00125 return cv::findHomography(points1, points2, CV_RANSAC, 3.0);
00126 }
00127
00128 void AutoInit::set_control_points(cv::Mat &tpl)
00129 {
00130 int row, col;
00131 if(inteval <= 0)
00132 {
00133 cv::FileStorage fs("contour.xml", cv::FileStorage::READ);
00134 fs["contour_points"] >> control_points ;
00135
00136 printf("contour_points number : %d\n", control_points.rows);
00137 }
00138 else
00139 {
00140 int control_points_count = ceil((double)tpl.rows/inteval)*2+ ceil((double)tpl.cols/inteval)*2;
00141 control_points = cv::Mat::zeros(control_points_count, 3 , CV_64FC1);
00142 int i = 0;
00143 for (row = inteval; row < tpl.rows; row+=inteval){
00144 control_points.ptr<double>(i)[0] = 0;
00145 control_points.ptr<double>(i)[1] = row;
00146 control_points.ptr<double>(i)[2] = 1;
00147
00148
00149
00150 i++;
00151 }
00152 control_points.ptr<double>(i)[0] = 0;
00153 control_points.ptr<double>(i)[1] = tpl.rows;
00154 control_points.ptr<double>(i)[2] = 1;
00155 i++;
00156 for (col = inteval; col < tpl.cols; col+=inteval){
00157 control_points.ptr<double>(i)[0] = col;
00158 control_points.ptr<double>(i)[1] = tpl.rows;
00159 control_points.ptr<double>(i)[2] = 1;
00160 i++;
00161 }
00162 control_points.ptr<double>(i)[0] = tpl.cols;
00163 control_points.ptr<double>(i)[1] = tpl.rows;
00164 control_points.ptr<double>(i)[2] = 1;
00165 i++;
00166
00167 for (row = tpl.rows - inteval; row > 0 ; row-=inteval){
00168 control_points.ptr<double>(i)[0] = tpl.cols;
00169 control_points.ptr<double>(i)[1] = row;
00170 control_points.ptr<double>(i)[2] = 1;
00171 i++;
00172 }
00173 control_points.ptr<double>(i)[0] = tpl.cols;
00174 control_points.ptr<double>(i)[1] = 0;
00175 control_points.ptr<double>(i)[2] = 1;
00176 i++;
00177 for (col = tpl.cols-inteval; col > 0; col-=inteval){
00178 control_points.ptr<double>(i)[0] = col;
00179 control_points.ptr<double>(i)[1] = 0;
00180 control_points.ptr<double>(i)[2] = 1;
00181 i++;
00182 }
00183 control_points.ptr<double>(i)[0] = 0;
00184 control_points.ptr<double>(i)[1] = 0;
00185 control_points.ptr<double>(i)[2] = 1;
00186 i++;
00187 }
00188 }
00189
00190 void AutoInit::init(cv::Mat &tpl,
00191 cv::Mat &training_img)
00192 {
00193 char key;
00194 double *ptr;
00195 cv::Mat H, control_points_t, xformed;
00196 std::vector<cv::DMatch> matches;
00197
00198 extract_descriptors(tpl, training_img);
00199 match_descriptors();
00200 H = compute_homography(tpl, training_img);
00201 set_control_points(tpl);
00202 cv::gemm(H, control_points, 1, cv::Mat(), 0, control_points_t, cv::GEMM_2_T);
00203
00204
00205
00206
00207
00208
00209
00210 xformed = cv::Mat( training_img.size(), CV_8UC3);
00211 cv::warpPerspective( tpl, xformed, H, xformed.size(), cv::INTER_LINEAR , cv::BORDER_CONSTANT, cv::Scalar());
00212 control_points = control_points_t.t();
00213 for (int row = 0; row < control_points.rows; ++row){
00214 ptr = control_points.ptr<double>(row);
00215
00216 cv::circle(xformed, cvPoint(ptr[0]/ptr[2], ptr[1]/ptr[2]), 2, CV_RGB(0,255,0), 2, 8, 0);
00217 }
00218 cv::namedWindow( "CCD", 1 );
00219 cv::imshow( "CCD", xformed);
00220 while (1)
00221 {
00222 key = cv::waitKey(10);
00223 if (key == 27) break;
00224 }
00225 xformed.release();
00226 H.release();
00227 control_points_t.release();
00228 }
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259