auto_init.cpp
Go to the documentation of this file.
00001 // Software License Agreement (BSD License)
00002 // 
00003 //   Copyright (c) 2011, Shulei Zhu <schuleichu@gmail.com>
00004 //   All rights reserved.
00005 // 
00006 //   Redistribution and use in source and binary forms, with or without
00007 //   modification, are permitted provided that the following conditions
00008 //   are met:
00009 // 
00010 //    * Redistributions of source code must retain the above copyright
00011 //      notice, this list of conditions and the following disclaimer.
00012 //    * Redistributions in binary form must reproduce the above
00013 //      copyright notice, this list of conditions and the following
00014 //      disclaimer in the documentation and/or other materials provided
00015 //      with the distribution.
00016 //    * Neither the name of Shulei Zhu nor the names of its
00017 //      contributors may be used to endorse or promote products derived
00018 //      from this software without specific prior written permission.
00019 // 
00020 //   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021 //   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022 //   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00023 //   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00024 //   COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00025 //   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00026 //   BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027 //   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00028 //   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029 //   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00030 //   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00031 //   POSSIBILITY OF SUCH DAMAGE.
00032 // 
00033 // 
00034 // auto_init.cpp --- 
00035 // File            : auto_init.cpp
00036 // Created: Sa Jun 18 14:04:15 2011 (+0200)
00037 // Author: Shulei Zhu
00038 
00039 // Code:
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     // ( double magnification=SIFT::DescriptorParams::GET_DEFAULT_MAGNIFICATION(),
00058     //   bool isNormalize=true, bool recalculateAngles=true,
00059     //   int nOctaves=SIFT::CommonParams::DEFAULT_NOCTAVES,
00060     //   int nOctaveLayers=SIFT::CommonParams::DEFAULT_NOCTAVE_LAYERS,
00061     //   int firstOctave=SIFT::CommonParams::DEFAULT_FIRST_OCTAVE,
00062     //   int angleMode=SIFT::CommonParams::FIRST_ANGLE )
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     // dm->add(descriptors2);
00086     // dm->train();
00087     // dm->match(descriptors1, matches);
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     // cvLine( stacked, cvPoint(cvRound( points1->data.db[i*2] ), cvRound( points1->data.db[i*2+1])),
00116     //         cvPoint( cvRound( points2->data.db[i*2] ), cvRound( points2->data.db[i*2+1]) + tpl->height ),
00117     //         CV_RGB(255,0,255), 1, 8, 0 );
00118   }
00119 
00120   // namedWindow("SIFTFEATUREdetector");
00121   // imshow("SIFTFEATUREdetector", stacked);
00122   // cvWaitKey( 0 );
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       // (ptr+i*step)[0] = 0;
00148       // (ptr+i*step)[1] = row;
00149       // (ptr+i*step)[2] = 1;
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   // for (row = 0; row < H.rows; ++row){
00205   //   ptr = H.ptr<double>(row);
00206   //   std::cout << ptr[0] << " " << ptr[1] << " " << ptr[2] << std::endl;
00207   // }
00208   /* printf("cont_n = %d\n", control_points_count); */
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     // std::cout << ptr[0] << " " << ptr[1] << " "<< ptr[2] << std::endl;
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 // void stack_imgs( cv::Mat &tpl,
00232 //                  cv::Mat &training_img,
00233 //                  cv::Mat &stacked)
00234 // {
00235 //   int max_width = MAX(tpl.cols, training_img.cols);
00236 //   int x_start = (max_width - tpl.cols)*0.5;
00237 //   stacked = cv::Mat::zeros( cv::Size( max_width, tpl.rows + training_img.rows), CV_8UC3);
00238 //   // int i,j;
00239 //   // for (i = 0; i < tpl->height; i++)
00240 //   // {
00241 //   //   uchar* ptr = (uchar*) (stacked->imageData + i * stacked->widthStep);
00242 //   //   for (j = 0; j < x_start; j++)
00243 //   //   {
00244 //   //     ptr[3*j] = 100;
00245 //   //     ptr[3*j + 1] = 100;
00246 //   //     ptr[3*j + 2] = 100;
00247 //   //   }
00248 //   //   for (j = max_width - x_start; j < max_width; j++)
00249 //   //   {
00250 //   //     ptr[3*j] = 100;
00251 //   //     ptr[3*j + 1] = 100;
00252 //   //     ptr[3*j + 2] = 100;
00253 //   //   }
00254 //   // }
00255 //   cv::Mat roi1(stacked, cv::Rect( x_start, 0, tpl.cols, tpl.rows ) );
00256 //   roi1 = tpl;
00257 //   cv::Mat roi2( stacked, cv::Rect(0, tpl.rows, training_img.cols, training_img.rows) );
00258 //   roi2 = training_img;
00259 // }


contracting_curve_density_algorithm
Author(s): Shulei Zhu, Dejan Pangercic
autogenerated on Mon Oct 6 2014 10:42:02