├── README.md └── main.cpp /README.md: -------------------------------------------------------------------------------- 1 | rtObjectRecognition 2 | =================== 3 | 4 | Real Time Object Recognition using SURF algorithm in OpenCV EEL6562 Course Project. 5 | 6 | Note: OpenCV libraries must be installed to use code. See link below on how to install OpenCV 7 | 8 | http://nenadbulatovic.blogspot.com/2013/07/configuring-opencv-245-eclipse-cdt-juno.html 9 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * EEL6562 Project 3 | * Real Time Object Recognition using SURF 4 | * 5 | * Created on: Nov 15, 2013 6 | * Author: Frank 7 | */ 8 | 9 | //Include statements 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include "opencv2/features2d/features2d.hpp" 17 | #include "opencv2/imgproc/imgproc.hpp" 18 | #include "opencv2/calib3d/calib3d.hpp" 19 | #include "opencv2/nonfree/nonfree.hpp" 20 | 21 | //Name spaces used 22 | using namespace cv; 23 | using namespace std; 24 | 25 | int main() 26 | { 27 | //Turn on performance analysis functions for generating metrics if generateMetricsForReport = true 28 | bool generateMetricsForReport=false; 29 | double t; //timing variable 30 | string resourceFilePath = "C:/School/Image Processing/"; 31 | string trainingImageFilePath = resourceFilePath + "book.jpg"; 32 | 33 | //load training image 34 | Mat object = imread (trainingImageFilePath, CV_LOAD_IMAGE_GRAYSCALE); 35 | if (!object.data){ 36 | cout<<"Can't open image"; 37 | return -1; 38 | } 39 | namedWindow("Good Matches", CV_WINDOW_AUTOSIZE); 40 | 41 | //SURF Detector, and descriptor parameters 42 | int minHess=3000; 43 | vector kpObject, kpImage; 44 | Mat desObject, desImage; 45 | 46 | //Performance measures calculations for report 47 | if (generateMetricsForReport) 48 | { 49 | //Calculate integral image 50 | cout< obj_corners(4); 129 | obj_corners[0] = cvPoint(0,0); 130 | obj_corners[1] = cvPoint( object.cols, 0 ); 131 | obj_corners[2] = cvPoint( object.cols, object.rows ); 132 | obj_corners[3] = cvPoint( 0, object.rows ); 133 | 134 | //video loop 135 | char escapeKey='k'; 136 | double frameCount = 0; 137 | float thresholdMatchingNN=0.7; 138 | unsigned int thresholdGoodMatches=4; 139 | unsigned int thresholdGoodMatchesV[]={4,5,6,7,8,9,10}; 140 | 141 | for (int j=0; j<7;j++){ 142 | thresholdGoodMatches=thresholdGoodMatchesV[j]; 143 | //thresholdGoodMatches=8; 144 | cout<>frame; 157 | cvtColor(frame, image, CV_RGB2GRAY); 158 | 159 | Mat des_image, img_matches, H; 160 | vector kp_image; 161 | vector > matches; 162 | vector good_matches; 163 | vector obj; 164 | vector scene; 165 | vector scene_corners(4); 166 | 167 | detector.detect( image, kp_image ); 168 | extractor.compute( image, kp_image, des_image ); 169 | matcher.knnMatch(desObject, des_image, matches, 2); 170 | 171 | for(int i = 0; i < min(des_image.rows-1,(int) matches.size()); i++) //THIS LOOP IS SENSITIVE TO SEGFAULTS 172 | { 173 | if((matches[i][0].distance < thresholdMatchingNN*(matches[i][1].distance)) && ((int) matches[i].size()<=2 && (int) matches[i].size()>0)) 174 | { 175 | good_matches.push_back(matches[i][0]); 176 | } 177 | } 178 | 179 | //Draw only "good" matches 180 | drawMatches( object, kpObject, image, kp_image, good_matches, img_matches, Scalar::all(-1), Scalar::all(-1), vector(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS ); 181 | 182 | if (good_matches.size() >= thresholdGoodMatches) 183 | { 184 | //Display that the object is found 185 | putText(img_matches, "Object Found", cvPoint(10,50),FONT_HERSHEY_COMPLEX_SMALL, 2, cvScalar(0,0,250), 1, CV_AA); 186 | for(unsigned int i = 0; i < good_matches.size(); i++ ) 187 | { 188 | //Get the keypoints from the good matches 189 | obj.push_back( kpObject[ good_matches[i].queryIdx ].pt ); 190 | scene.push_back( kp_image[ good_matches[i].trainIdx ].pt ); 191 | } 192 | 193 | H = findHomography( obj, scene, CV_RANSAC ); 194 | perspectiveTransform( obj_corners, scene_corners, H); 195 | 196 | //Draw lines between the corners (the mapped object in the scene image ) 197 | line( img_matches, scene_corners[0] + Point2f( object.cols, 0), scene_corners[1] + Point2f( object.cols, 0), Scalar(0, 255, 0), 4 ); 198 | line( img_matches, scene_corners[1] + Point2f( object.cols, 0), scene_corners[2] + Point2f( object.cols, 0), Scalar( 0, 255, 0), 4 ); 199 | line( img_matches, scene_corners[2] + Point2f( object.cols, 0), scene_corners[3] + Point2f( object.cols, 0), Scalar( 0, 255, 0), 4 ); 200 | line( img_matches, scene_corners[3] + Point2f( object.cols, 0), scene_corners[0] + Point2f( object.cols, 0), Scalar( 0, 255, 0), 4 ); 201 | } 202 | else 203 | { 204 | putText(img_matches, "", cvPoint(10,50), FONT_HERSHEY_COMPLEX_SMALL, 3, cvScalar(0,0,250), 1, CV_AA); 205 | } 206 | 207 | //Show detected matches 208 | imshow( "Good Matches", img_matches ); 209 | escapeKey=cvWaitKey(10); 210 | //imwrite(resourceFilePath + "bookIP3.jpg", img_matches); 211 | 212 | if(frameCount>10) 213 | escapeKey='q'; 214 | } 215 | 216 | //average frames per second 217 | if(true) 218 | { 219 | t = ((double)getTickCount() - t)/getTickFrequency(); 220 | cout<