├── README ├── include ├── .svn │ ├── all-wcprops │ ├── entries │ └── text-base │ │ ├── pkmImageFeatureDetector.cpp.svn-base │ │ └── pkmImageFeatureDetector.h.svn-base ├── pkmImageFeatureDetector.cpp └── pkmImageFeatureDetector.h └── src ├── .DS_Store ├── .svn ├── all-wcprops ├── entries └── text-base │ ├── main.cpp.svn-base │ ├── testApp.cpp.svn-base │ └── testApp.h.svn-base ├── main.cpp ├── testApp.cpp └── testApp.h /README: -------------------------------------------------------------------------------- 1 | 213016311HNETLT -------------------------------------------------------------------------------- /include/.svn/all-wcprops: -------------------------------------------------------------------------------- 1 | K 25 2 | svn:wc:ra_dav:version-url 3 | V 47 4 | /svn/map01pm_pkm/!svn/ver/1/pkmDetector/include 5 | END 6 | pkmImageFeatureDetector.cpp 7 | K 25 8 | svn:wc:ra_dav:version-url 9 | V 75 10 | /svn/map01pm_pkm/!svn/ver/1/pkmDetector/include/pkmImageFeatureDetector.cpp 11 | END 12 | pkmImageFeatureDetector.h 13 | K 25 14 | svn:wc:ra_dav:version-url 15 | V 73 16 | /svn/map01pm_pkm/!svn/ver/1/pkmDetector/include/pkmImageFeatureDetector.h 17 | END 18 | -------------------------------------------------------------------------------- /include/.svn/entries: -------------------------------------------------------------------------------- 1 | 10 2 | 3 | dir 4 | 1 5 | https://igor.gold.ac.uk/svn/map01pm_pkm/pkmDetector/include 6 | https://igor.gold.ac.uk/svn/map01pm_pkm 7 | 8 | 9 | 10 | 2012-01-24T11:47:12.462839Z 11 | 1 12 | map01pm 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 2089ce31-29c5-48d7-9183-149702831269 28 | 29 | pkmImageFeatureDetector.cpp 30 | file 31 | 32 | 33 | 34 | 35 | 2011-09-29T13:42:54.000000Z 36 | 79916ec021fbafd067a1b815e0e5d70b 37 | 2012-01-24T11:47:12.462839Z 38 | 1 39 | map01pm 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 9111 62 | 63 | pkmImageFeatureDetector.h 64 | file 65 | 66 | 67 | 68 | 69 | 2011-09-29T13:42:59.000000Z 70 | 7e480232725c787b21f6d89957efcb9e 71 | 2012-01-24T11:47:12.462839Z 72 | 1 73 | map01pm 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 4534 96 | 97 | -------------------------------------------------------------------------------- /include/.svn/text-base/pkmImageFeatureDetector.cpp.svn-base: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Parag K. Mital - http://pkmital.com 3 | * Contact: parag@pkmital.com 4 | * 5 | * Copyright 2011 Parag K. Mital. All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #include "pkmImageFeatureDetector.h" 30 | 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | pkmImageFeatureDetector::pkmImageFeatureDetector() 39 | { 40 | bSetImageSearch = false; 41 | bSetImageTemplate = false; 42 | bShowImage = true; 43 | bTracking = false; 44 | bInitialized = false; 45 | 46 | winName = "correspondences"; 47 | 48 | ransacReprojThreshold = 4; 49 | 50 | detector = cv::FeatureDetector::create( "DynamicSURF" ); // [“Grid”, “Pyramid”, “Dynamic”] SIFT, SURF, FAST, GFTT, MSER and HARRIS 51 | descriptorExtractor = cv::DescriptorExtractor::create( "SURF" ); // ["Opponent"] SIFT, SURF and BRIEF 52 | descriptorMatcher = cv::DescriptorMatcher::create( "FlannBased" ); // “FlannBased”, “BruteForceMatcher”, “BruteForce-L1” and “BruteForce-HammingLUT” 53 | matcherFilterType = CROSS_CHECK_FILTER; 54 | 55 | } 56 | 57 | 58 | void pkmImageFeatureDetector::setImageTemplate(IplImage *img_t) 59 | { 60 | if(bSetImageTemplate) { 61 | bSetImageTemplate = false; 62 | img_template_keypoints.clear(); 63 | img_template_boundingbox.clear(); 64 | } 65 | 66 | img_template = cv::Mat(img_t); 67 | 68 | detector->detect( img_template, img_template_keypoints ); 69 | 70 | int n = img_template_keypoints.size(); 71 | if(n > 1) 72 | { 73 | printf("[OK] Found %d keypoints.\n", n); 74 | bSetImageTemplate = true; 75 | 76 | 77 | CvPoint dst[] = { cvPoint(0, 0), 78 | cvPoint(0, img_t->height), 79 | cvPoint(img_t->width, img_t->height), 80 | cvPoint(img_t->width, 0) }; 81 | 82 | for (int i = 0; i < 4; i++) { 83 | img_template_boundingbox.push_back(dst[i]); 84 | } 85 | } 86 | else { 87 | printf("[ERROR] No keypoints found!\n"); 88 | img_template_keypoints.clear(); 89 | img_template_boundingbox.clear(); 90 | bSetImageTemplate = false; 91 | } 92 | 93 | descriptorExtractor->compute( img_template, img_template_keypoints, img_template_descriptors ); 94 | 95 | 96 | } 97 | 98 | void pkmImageFeatureDetector::setImageSearch(IplImage *img_s) 99 | { 100 | if (bSetImageSearch) { 101 | bSetImageSearch = false; 102 | img_search_keypoints.clear(); 103 | } 104 | 105 | img_search = cv::Mat(img_s); 106 | 107 | detector->detect( img_search, img_search_keypoints ); 108 | 109 | int n = img_search_keypoints.size(); 110 | if(n > 1) 111 | { 112 | printf("[OK] Found %d keypoints.\n", n); 113 | bSetImageSearch = true; 114 | } 115 | else { 116 | printf("[ERROR] No keypoints found!\n"); 117 | img_search_keypoints.clear(); 118 | bSetImageSearch = false; 119 | } 120 | 121 | // compute descriptors for all computed keypoints 122 | descriptorExtractor->compute( img_search, img_search_keypoints, img_search_descriptors ); 123 | 124 | } 125 | 126 | void pkmImageFeatureDetector::simpleMatching( cv::Ptr& descriptorMatcher, 127 | const cv::Mat& descriptors1, const cv::Mat& descriptors2, 128 | vector& matches12 ) 129 | { 130 | vector matches; 131 | descriptorMatcher->match( descriptors1, descriptors2, matches12 ); 132 | } 133 | 134 | void pkmImageFeatureDetector::crossCheckMatching( cv::Ptr& descriptorMatcher, 135 | const cv::Mat& descriptors1, const cv::Mat& descriptors2, 136 | vector& filteredMatches12, int knn ) 137 | { 138 | filteredMatches12.clear(); 139 | vector > matches12, matches21; 140 | descriptorMatcher->knnMatch( descriptors1, descriptors2, matches12, knn ); 141 | descriptorMatcher->knnMatch( descriptors2, descriptors1, matches21, knn ); 142 | for( size_t m = 0; m < matches12.size(); m++ ) 143 | { 144 | bool findCrossCheck = false; 145 | for( size_t fk = 0; fk < matches12[m].size(); fk++ ) 146 | { 147 | cv::DMatch forward = matches12[m][fk]; 148 | 149 | for( size_t bk = 0; bk < matches21[forward.trainIdx].size(); bk++ ) 150 | { 151 | cv::DMatch backward = matches21[forward.trainIdx][bk]; 152 | if( backward.trainIdx == forward.queryIdx ) 153 | { 154 | filteredMatches12.push_back(forward); 155 | findCrossCheck = true; 156 | break; 157 | } 158 | } 159 | if( findCrossCheck ) break; 160 | } 161 | } 162 | } 163 | 164 | void pkmImageFeatureDetector::update() 165 | { 166 | if (bSetImageSearch && bSetImageTemplate) 167 | { 168 | if (!bInitialized) 169 | { 170 | 171 | 172 | // do matching between the template and image search 173 | // without tracking previous features since none initialized 174 | filteredMatches.clear(); 175 | switch( matcherFilterType ) 176 | { 177 | case CROSS_CHECK_FILTER : 178 | crossCheckMatching( descriptorMatcher, img_template_descriptors, img_search_descriptors, filteredMatches, 1 ); 179 | break; 180 | default : 181 | simpleMatching( descriptorMatcher, img_template_descriptors, img_search_descriptors, filteredMatches ); 182 | } 183 | 184 | // reindex based on found matches 185 | vector queryIdxs( filteredMatches.size() ), trainIdxs( filteredMatches.size() ); 186 | for( size_t i = 0; i < filteredMatches.size(); i++ ) 187 | { 188 | queryIdxs[i] = filteredMatches[i].queryIdx; 189 | trainIdxs[i] = filteredMatches[i].trainIdx; 190 | } 191 | 192 | // build homograhpy w/ ransac 193 | vector points1; cv::KeyPoint::convert(img_template_keypoints, points1, queryIdxs); 194 | vector points2; cv::KeyPoint::convert(img_search_keypoints, points2, trainIdxs); 195 | if (points1.size() < 4 || points2.size() < 4) { 196 | printf("Not enough keypoints.\n"); 197 | return; 198 | } 199 | H12 = findHomography( cv::Mat(points1), cv::Mat(points2), CV_RANSAC, ransacReprojThreshold ); 200 | 201 | // create a mask of the current inliers based on transform distance 202 | vector matchesMask( filteredMatches.size(), 0 ); 203 | 204 | printf("Matched %d features.\n", filteredMatches.size()); 205 | 206 | // convert previous image points to current image points via homography 207 | // although this is a transformation from image to world coordinates 208 | // it should estimate the current image points 209 | cv::Mat points1t; perspectiveTransform(cv::Mat(points1), points1t, H12); 210 | for( size_t i1 = 0; i1 < points1.size(); i1++ ) 211 | { 212 | if( norm(points2[i1] - points1t.at((int)i1,0)) < 4 ) // inlier 213 | { 214 | matchesMask[i1] = 1; 215 | img_search_points_inliers[1].push_back(points2[i1]); 216 | } 217 | else { 218 | img_search_points_outliers[1].push_back(points2[i1]); 219 | } 220 | } 221 | 222 | 223 | // update bounding box 224 | cv::Mat bb; 225 | perspectiveTransform(cv::Mat(img_template_boundingbox), bb, H12); 226 | for( int i = 0; i < 4; i++ ) 227 | { 228 | dst_corners[i] = bb.at(i,0); 229 | //img_template_boundingbox[i] = bb.at(i,0); 230 | } 231 | 232 | /* 233 | // draw inliers 234 | drawMatches( img_search, img_template_keypoints, 235 | img_template, img_search_keypoints, 236 | filteredMatches, drawImg, 237 | CV_RGB(0, 255, 0), CV_RGB(0, 0, 255), matchesMask 238 | #if DRAW_RICH_KEYPOINTS_MODE 239 | , DrawMatchesFlags::DRAW_RICH_KEYPOINTS 240 | #endif 241 | ); 242 | 243 | #if DRAW_OUTLIERS_MODE 244 | // draw outliers 245 | for( size_t i1 = 0; i1 < matchesMask.size(); i1++ ) 246 | matchesMask[i1] = !matchesMask[i1]; 247 | drawMatches( img_template, img_template_keypoints, 248 | img_search, img_search_keypoints, filteredMatches, drawImg, CV_RGB(0, 0, 255), CV_RGB(255, 0, 0), matchesMask, 249 | DrawMatchesFlags::DRAW_OVER_OUTIMG | DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS ); 250 | 251 | #endif 252 | 253 | imshow( winName, drawImg ); 254 | */ 255 | 256 | } 257 | else { 258 | // track features from previous frame into the current frame and see which 259 | // features are inliers, and which are outliers. among the features that 260 | // are outliers, see if any were marked as inliers in the previous frame and 261 | // remark then as outliers 262 | 263 | // mark decsriptors on new features marked as outliers once the number of 264 | // inliers drops to a certain threshold and perform matching on the template. 265 | 266 | // patch based seems powerful as well. creating a manifold or detecting planes 267 | // in the set of inliers and tracking them as a whole may be more powerful. 268 | //<#statements#> 269 | } 270 | 271 | //std::swap(current_template_points, previous_template_points); 272 | std::swap(img_search_points_inliers[1], img_search_points_inliers[0]); 273 | std::swap(img_search_points_outliers[1], img_search_points_outliers[0]); 274 | swap(prev_img_search, img_search); 275 | } // end bSetImageSearch && bSetImageTemplate 276 | 277 | } 278 | -------------------------------------------------------------------------------- /include/.svn/text-base/pkmImageFeatureDetector.h.svn-base: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Parag K. Mital - http://pkmital.com 3 | * Contact: parag@pkmital.com 4 | * 5 | * Copyright 2011 Parag K. Mital. All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | #pragma once 29 | 30 | #include 31 | #include 32 | 33 | //#include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | using namespace cv; 40 | using namespace std; 41 | 42 | #define DRAW_RICH_KEYPOINTS_MODE 1 43 | #define DRAW_OUTLIERS_MODE 1 44 | 45 | class pkmImageFeatureDetector 46 | { 47 | 48 | enum { NONE_FILTER = 0, CROSS_CHECK_FILTER = 1 }; 49 | 50 | public: 51 | 52 | pkmImageFeatureDetector(); 53 | 54 | void setImageTemplate(IplImage *img_t); 55 | vector getImageTemplateKeypoints() 56 | { 57 | if (bSetImageTemplate) { 58 | return img_template_keypoints; 59 | } 60 | else { 61 | vector empty; 62 | return empty; 63 | } 64 | } 65 | cv::Mat getImageTemplateDescriptors() 66 | { 67 | if (bSetImageTemplate) { 68 | return img_template_descriptors; 69 | } 70 | else { 71 | cv::Mat empty; 72 | return empty; 73 | } 74 | } 75 | 76 | void setImageSearch(IplImage *img_s); 77 | vector getImageSearchKeypoints() 78 | { 79 | if (bSetImageSearch) { 80 | return img_search_keypoints; 81 | } 82 | else { 83 | vector empty; 84 | return empty; 85 | } 86 | } 87 | cv::Mat getImageSearchDescriptors() 88 | { 89 | if (bSetImageSearch) { 90 | return img_search_descriptors; 91 | } 92 | else { 93 | cv::Mat empty; 94 | return empty; 95 | } 96 | } 97 | 98 | void simpleMatching( cv::Ptr& descriptorMatcher, 99 | const cv::Mat& descriptors1, const cv::Mat& descriptors2, 100 | vector& matches12 ); 101 | void crossCheckMatching( cv::Ptr& descriptorMatcher, 102 | const cv::Mat& descriptors1, const cv::Mat& descriptors2, 103 | vector& filteredMatches12, int knn=1 ); 104 | 105 | void update(); 106 | void doIteration( const cv::Mat& img1, Mat& img2, 107 | vector& keypoints1, const cv::Mat& descriptors1, 108 | cv::Ptr& detector, cv::Ptr& descriptorExtractor, 109 | cv::Ptr& descriptorMatcher, int matcherFilter, 110 | double ransacReprojThreshold); 111 | 112 | 113 | vector img_search_points_inliers[2], img_search_points_outliers[2]; 114 | vector img_template_boundingbox; 115 | cv::Point2f src_corners[4], dst_corners[4], prev_dst_corners[4]; 116 | 117 | private: 118 | 119 | int matcherFilterType; 120 | 121 | bool bSetImageTemplate, bSetImageSearch; 122 | 123 | cv::Ptr detector; 124 | cv::Ptr descriptorExtractor; 125 | cv::Ptr descriptorMatcher; 126 | 127 | cv::Mat img_template, img_search; 128 | 129 | bool bInitialized, bTracking; 130 | cv::Mat prev_img_search; 131 | 132 | vector img_search_keypoints, img_template_keypoints; 133 | vector img_search_keypoints_inliers[2], img_search_keypoints_outliers[2]; 134 | 135 | cv::Mat img_search_descriptors, img_template_descriptors; 136 | 137 | vector filteredMatches; 138 | 139 | float ransacReprojThreshold; 140 | 141 | 142 | cv::Mat H12; 143 | 144 | bool bShowImage; 145 | cv::Mat drawImg; 146 | string winName; 147 | 148 | }; -------------------------------------------------------------------------------- /include/pkmImageFeatureDetector.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Parag K. Mital - http://pkmital.com 3 | * Contact: parag@pkmital.com 4 | * 5 | * Copyright 2011 Parag K. Mital. All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #include "pkmImageFeatureDetector.h" 30 | 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | pkmImageFeatureDetector::pkmImageFeatureDetector() 39 | { 40 | bSetImageSearch = false; 41 | bSetImageTemplate = false; 42 | bShowImage = true; 43 | bTracking = false; 44 | bInitialized = false; 45 | 46 | winName = "correspondences"; 47 | 48 | ransacReprojThreshold = 4; 49 | 50 | detector = cv::FeatureDetector::create( "DynamicSURF" ); // [“Grid”, “Pyramid”, “Dynamic”] SIFT, SURF, FAST, GFTT, MSER and HARRIS 51 | descriptorExtractor = cv::DescriptorExtractor::create( "SURF" ); // ["Opponent"] SIFT, SURF and BRIEF 52 | descriptorMatcher = cv::DescriptorMatcher::create( "FlannBased" ); // “FlannBased”, “BruteForceMatcher”, “BruteForce-L1” and “BruteForce-HammingLUT” 53 | matcherFilterType = CROSS_CHECK_FILTER; 54 | 55 | } 56 | 57 | 58 | void pkmImageFeatureDetector::setImageTemplate(IplImage *img_t) 59 | { 60 | if(bSetImageTemplate) { 61 | bSetImageTemplate = false; 62 | img_template_keypoints.clear(); 63 | img_template_boundingbox.clear(); 64 | } 65 | 66 | img_template = cv::Mat(img_t); 67 | 68 | detector->detect( img_template, img_template_keypoints ); 69 | 70 | int n = img_template_keypoints.size(); 71 | if(n > 1) 72 | { 73 | printf("[OK] Found %d keypoints.\n", n); 74 | bSetImageTemplate = true; 75 | 76 | 77 | CvPoint dst[] = { cvPoint(0, 0), 78 | cvPoint(0, img_t->height), 79 | cvPoint(img_t->width, img_t->height), 80 | cvPoint(img_t->width, 0) }; 81 | 82 | for (int i = 0; i < 4; i++) { 83 | img_template_boundingbox.push_back(dst[i]); 84 | } 85 | } 86 | else { 87 | printf("[ERROR] No keypoints found!\n"); 88 | img_template_keypoints.clear(); 89 | img_template_boundingbox.clear(); 90 | bSetImageTemplate = false; 91 | } 92 | 93 | descriptorExtractor->compute( img_template, img_template_keypoints, img_template_descriptors ); 94 | 95 | 96 | } 97 | 98 | void pkmImageFeatureDetector::setImageSearch(IplImage *img_s) 99 | { 100 | if (bSetImageSearch) { 101 | bSetImageSearch = false; 102 | img_search_keypoints.clear(); 103 | } 104 | 105 | img_search = cv::Mat(img_s); 106 | 107 | detector->detect( img_search, img_search_keypoints ); 108 | 109 | int n = img_search_keypoints.size(); 110 | if(n > 1) 111 | { 112 | printf("[OK] Found %d keypoints.\n", n); 113 | bSetImageSearch = true; 114 | } 115 | else { 116 | printf("[ERROR] No keypoints found!\n"); 117 | img_search_keypoints.clear(); 118 | bSetImageSearch = false; 119 | } 120 | 121 | // compute descriptors for all computed keypoints 122 | descriptorExtractor->compute( img_search, img_search_keypoints, img_search_descriptors ); 123 | 124 | } 125 | 126 | void pkmImageFeatureDetector::simpleMatching( cv::Ptr& descriptorMatcher, 127 | const cv::Mat& descriptors1, const cv::Mat& descriptors2, 128 | vector& matches12 ) 129 | { 130 | vector matches; 131 | descriptorMatcher->match( descriptors1, descriptors2, matches12 ); 132 | } 133 | 134 | void pkmImageFeatureDetector::crossCheckMatching( cv::Ptr& descriptorMatcher, 135 | const cv::Mat& descriptors1, const cv::Mat& descriptors2, 136 | vector& filteredMatches12, int knn ) 137 | { 138 | filteredMatches12.clear(); 139 | vector > matches12, matches21; 140 | descriptorMatcher->knnMatch( descriptors1, descriptors2, matches12, knn ); 141 | descriptorMatcher->knnMatch( descriptors2, descriptors1, matches21, knn ); 142 | for( size_t m = 0; m < matches12.size(); m++ ) 143 | { 144 | bool findCrossCheck = false; 145 | for( size_t fk = 0; fk < matches12[m].size(); fk++ ) 146 | { 147 | cv::DMatch forward = matches12[m][fk]; 148 | 149 | for( size_t bk = 0; bk < matches21[forward.trainIdx].size(); bk++ ) 150 | { 151 | cv::DMatch backward = matches21[forward.trainIdx][bk]; 152 | if( backward.trainIdx == forward.queryIdx ) 153 | { 154 | filteredMatches12.push_back(forward); 155 | findCrossCheck = true; 156 | break; 157 | } 158 | } 159 | if( findCrossCheck ) break; 160 | } 161 | } 162 | } 163 | 164 | void pkmImageFeatureDetector::update() 165 | { 166 | if (bSetImageSearch && bSetImageTemplate) 167 | { 168 | if (!bInitialized) 169 | { 170 | 171 | 172 | // do matching between the template and image search 173 | // without tracking previous features since none initialized 174 | filteredMatches.clear(); 175 | switch( matcherFilterType ) 176 | { 177 | case CROSS_CHECK_FILTER : 178 | crossCheckMatching( descriptorMatcher, img_template_descriptors, img_search_descriptors, filteredMatches, 1 ); 179 | break; 180 | default : 181 | simpleMatching( descriptorMatcher, img_template_descriptors, img_search_descriptors, filteredMatches ); 182 | } 183 | 184 | // reindex based on found matches 185 | vector queryIdxs( filteredMatches.size() ), trainIdxs( filteredMatches.size() ); 186 | for( size_t i = 0; i < filteredMatches.size(); i++ ) 187 | { 188 | queryIdxs[i] = filteredMatches[i].queryIdx; 189 | trainIdxs[i] = filteredMatches[i].trainIdx; 190 | } 191 | 192 | // build homograhpy w/ ransac 193 | vector points1; cv::KeyPoint::convert(img_template_keypoints, points1, queryIdxs); 194 | vector points2; cv::KeyPoint::convert(img_search_keypoints, points2, trainIdxs); 195 | if (points1.size() < 4 || points2.size() < 4) { 196 | printf("Not enough keypoints.\n"); 197 | return; 198 | } 199 | H12 = findHomography( cv::Mat(points1), cv::Mat(points2), CV_RANSAC, ransacReprojThreshold ); 200 | 201 | // create a mask of the current inliers based on transform distance 202 | vector matchesMask( filteredMatches.size(), 0 ); 203 | 204 | printf("Matched %d features.\n", filteredMatches.size()); 205 | 206 | // convert previous image points to current image points via homography 207 | // although this is a transformation from image to world coordinates 208 | // it should estimate the current image points 209 | cv::Mat points1t; perspectiveTransform(cv::Mat(points1), points1t, H12); 210 | for( size_t i1 = 0; i1 < points1.size(); i1++ ) 211 | { 212 | if( norm(points2[i1] - points1t.at((int)i1,0)) < 4 ) // inlier 213 | { 214 | matchesMask[i1] = 1; 215 | img_search_points_inliers[1].push_back(points2[i1]); 216 | } 217 | else { 218 | img_search_points_outliers[1].push_back(points2[i1]); 219 | } 220 | } 221 | 222 | 223 | // update bounding box 224 | cv::Mat bb; 225 | perspectiveTransform(cv::Mat(img_template_boundingbox), bb, H12); 226 | for( int i = 0; i < 4; i++ ) 227 | { 228 | dst_corners[i] = bb.at(i,0); 229 | //img_template_boundingbox[i] = bb.at(i,0); 230 | } 231 | 232 | /* 233 | // draw inliers 234 | drawMatches( img_search, img_template_keypoints, 235 | img_template, img_search_keypoints, 236 | filteredMatches, drawImg, 237 | CV_RGB(0, 255, 0), CV_RGB(0, 0, 255), matchesMask 238 | #if DRAW_RICH_KEYPOINTS_MODE 239 | , DrawMatchesFlags::DRAW_RICH_KEYPOINTS 240 | #endif 241 | ); 242 | 243 | #if DRAW_OUTLIERS_MODE 244 | // draw outliers 245 | for( size_t i1 = 0; i1 < matchesMask.size(); i1++ ) 246 | matchesMask[i1] = !matchesMask[i1]; 247 | drawMatches( img_template, img_template_keypoints, 248 | img_search, img_search_keypoints, filteredMatches, drawImg, CV_RGB(0, 0, 255), CV_RGB(255, 0, 0), matchesMask, 249 | DrawMatchesFlags::DRAW_OVER_OUTIMG | DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS ); 250 | 251 | #endif 252 | 253 | imshow( winName, drawImg ); 254 | */ 255 | 256 | } 257 | else { 258 | // track features from previous frame into the current frame and see which 259 | // features are inliers, and which are outliers. among the features that 260 | // are outliers, see if any were marked as inliers in the previous frame and 261 | // remark then as outliers 262 | 263 | // mark decsriptors on new features marked as outliers once the number of 264 | // inliers drops to a certain threshold and perform matching on the template. 265 | 266 | // patch based seems powerful as well. creating a manifold or detecting planes 267 | // in the set of inliers and tracking them as a whole may be more powerful. 268 | //<#statements#> 269 | } 270 | 271 | //std::swap(current_template_points, previous_template_points); 272 | std::swap(img_search_points_inliers[1], img_search_points_inliers[0]); 273 | std::swap(img_search_points_outliers[1], img_search_points_outliers[0]); 274 | swap(prev_img_search, img_search); 275 | } // end bSetImageSearch && bSetImageTemplate 276 | 277 | } 278 | -------------------------------------------------------------------------------- /include/pkmImageFeatureDetector.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Parag K. Mital - http://pkmital.com 3 | * Contact: parag@pkmital.com 4 | * 5 | * Copyright 2011 Parag K. Mital. All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | #pragma once 29 | 30 | #include 31 | #include 32 | 33 | //#include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | using namespace cv; 40 | using namespace std; 41 | 42 | #define DRAW_RICH_KEYPOINTS_MODE 1 43 | #define DRAW_OUTLIERS_MODE 1 44 | 45 | class pkmImageFeatureDetector 46 | { 47 | 48 | enum { NONE_FILTER = 0, CROSS_CHECK_FILTER = 1 }; 49 | 50 | public: 51 | 52 | pkmImageFeatureDetector(); 53 | 54 | // Set the Image Template 55 | void setImageTemplate(IplImage *img_t); 56 | 57 | // Manually specify the Image Template 58 | void setImageTemplate(vector keypts, cv::Mat desc) 59 | { 60 | img_search_keypoints = keypts; 61 | img_template_descriptors = desc; 62 | } 63 | 64 | // Get the resulting Image Template's Keypoints 65 | vector getImageTemplateKeypoints() 66 | { 67 | if (bSetImageTemplate) { 68 | return img_template_keypoints; 69 | } 70 | else { 71 | vector empty; 72 | return empty; 73 | } 74 | } 75 | 76 | // Get the resulting Image Template's Descriptors 77 | cv::Mat getImageTemplateDescriptors() 78 | { 79 | if (bSetImageTemplate) { 80 | return img_template_descriptors; 81 | } 82 | else { 83 | cv::Mat empty; 84 | return empty; 85 | } 86 | } 87 | 88 | void setImageSearch(IplImage *img_s); 89 | 90 | void setImageSearch(vector keypts, cv::Mat desc) 91 | { 92 | img_search_keypoints = keypts; 93 | img_search_descriptors = desc; 94 | } 95 | 96 | vector getImageSearchKeypoints() 97 | { 98 | if (bSetImageSearch) { 99 | return img_search_keypoints; 100 | } 101 | else { 102 | vector empty; 103 | return empty; 104 | } 105 | } 106 | 107 | cv::Mat getImageSearchDescriptors() 108 | { 109 | if (bSetImageSearch) { 110 | return img_search_descriptors; 111 | } 112 | else { 113 | cv::Mat empty; 114 | return empty; 115 | } 116 | } 117 | 118 | cv::Ptr getMatcher() 119 | { 120 | return descriptorMatcher; 121 | } 122 | 123 | void simpleMatching( cv::Ptr& descriptorMatcher, 124 | const cv::Mat& descriptors1, const cv::Mat& descriptors2, 125 | vector& matches12 ); 126 | void crossCheckMatching( cv::Ptr& descriptorMatcher, 127 | const cv::Mat& descriptors1, const cv::Mat& descriptors2, 128 | vector& filteredMatches12, int knn=1 ); 129 | 130 | void update(); 131 | void doIteration( const cv::Mat& img1, Mat& img2, 132 | vector& keypoints1, const cv::Mat& descriptors1, 133 | cv::Ptr& detector, cv::Ptr& descriptorExtractor, 134 | cv::Ptr& descriptorMatcher, int matcherFilter, 135 | double ransacReprojThreshold); 136 | 137 | 138 | vector img_search_points_inliers[2], img_search_points_outliers[2]; 139 | vector img_template_boundingbox; 140 | cv::Point2f src_corners[4], dst_corners[4], prev_dst_corners[4]; 141 | 142 | private: 143 | 144 | int matcherFilterType; 145 | 146 | bool bSetImageTemplate, bSetImageSearch; 147 | 148 | cv::Ptr detector; 149 | cv::Ptr descriptorExtractor; 150 | cv::Ptr descriptorMatcher; 151 | 152 | cv::Mat img_template, img_search; 153 | 154 | bool bInitialized, bTracking; 155 | cv::Mat prev_img_search; 156 | 157 | vector img_search_keypoints, img_template_keypoints; 158 | vector img_search_keypoints_inliers[2], img_search_keypoints_outliers[2]; 159 | 160 | cv::Mat img_search_descriptors, img_template_descriptors; 161 | 162 | vector filteredMatches; 163 | 164 | float ransacReprojThreshold; 165 | 166 | 167 | cv::Mat H12; 168 | 169 | bool bShowImage; 170 | cv::Mat drawImg; 171 | string winName; 172 | 173 | }; -------------------------------------------------------------------------------- /src/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pkmital/Real-Time-Object-Detection/81b869b3b665d789ac34f7fded6229afa2f00b7c/src/.DS_Store -------------------------------------------------------------------------------- /src/.svn/all-wcprops: -------------------------------------------------------------------------------- 1 | K 25 2 | svn:wc:ra_dav:version-url 3 | V 43 4 | /svn/map01pm_pkm/!svn/ver/1/pkmDetector/src 5 | END 6 | testApp.cpp 7 | K 25 8 | svn:wc:ra_dav:version-url 9 | V 55 10 | /svn/map01pm_pkm/!svn/ver/1/pkmDetector/src/testApp.cpp 11 | END 12 | main.cpp 13 | K 25 14 | svn:wc:ra_dav:version-url 15 | V 52 16 | /svn/map01pm_pkm/!svn/ver/1/pkmDetector/src/main.cpp 17 | END 18 | testApp.h 19 | K 25 20 | svn:wc:ra_dav:version-url 21 | V 53 22 | /svn/map01pm_pkm/!svn/ver/1/pkmDetector/src/testApp.h 23 | END 24 | -------------------------------------------------------------------------------- /src/.svn/entries: -------------------------------------------------------------------------------- 1 | 10 2 | 3 | dir 4 | 1 5 | https://igor.gold.ac.uk/svn/map01pm_pkm/pkmDetector/src 6 | https://igor.gold.ac.uk/svn/map01pm_pkm 7 | 8 | 9 | 10 | 2012-01-24T11:47:12.462839Z 11 | 1 12 | map01pm 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 2089ce31-29c5-48d7-9183-149702831269 28 | 29 | testApp.cpp 30 | file 31 | 32 | 33 | 34 | 35 | 2011-09-28T19:00:55.000000Z 36 | d8321762fb509830e7d9513b386e9894 37 | 2012-01-24T11:47:12.462839Z 38 | 1 39 | map01pm 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 4878 62 | 63 | main.cpp 64 | file 65 | 66 | 67 | 68 | 69 | 2010-10-26T00:28:08.000000Z 70 | edea466e4ec066457c19b9c157ec6e83 71 | 2012-01-24T11:47:12.462839Z 72 | 1 73 | map01pm 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 433 96 | 97 | testApp.h 98 | file 99 | 100 | 101 | 102 | 103 | 2011-09-28T19:01:06.000000Z 104 | db542516e3967ca110451c192750ef03 105 | 2012-01-24T11:47:12.462839Z 106 | 1 107 | map01pm 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 2157 130 | 131 | -------------------------------------------------------------------------------- /src/.svn/text-base/main.cpp.svn-base: -------------------------------------------------------------------------------- 1 | #include "ofMain.h" 2 | #include "testApp.h" 3 | #include "ofAppGlutWindow.h" 4 | 5 | //======================================================================== 6 | int main( ){ 7 | 8 | ofAppGlutWindow window; 9 | ofSetupOpenGL(&window, SCREEN_WIDTH, SCREEN_HEIGHT, OF_WINDOW); // <-------- setup the GL context 10 | 11 | // this kicks off the running of my app 12 | // can be OF_WINDOW or OF_FULLSCREEN 13 | // pass in width and height too: 14 | ofRunApp( new testApp()); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/.svn/text-base/testApp.cpp.svn-base: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Parag K. Mital - http://pkmital.com 3 | * Contact: parag@pkmital.com 4 | * 5 | * Copyright 2011 Parag K. Mital. All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #include "testApp.h" 30 | //-------------------------------------------------------------- 31 | testApp::~testApp(){ 32 | } 33 | void testApp::setup(){ 34 | 35 | // init video input 36 | vidInput.initGrabber(CAM_WIDTH,CAM_HEIGHT); 37 | vidInput.setUseTexture(true); 38 | 39 | // window setup 40 | ofSetWindowShape(SCREEN_WIDTH, SCREEN_HEIGHT); 41 | ofSetVerticalSync(true); 42 | ofSetFrameRate(60); 43 | ofBackground(0,0,0); 44 | 45 | // allocate stuff 46 | colorImg.allocate(CAM_WIDTH, CAM_HEIGHT); 47 | grayImg.allocate(CAM_WIDTH, CAM_HEIGHT); 48 | 49 | choosing_img = false; 50 | chosen_img = false; 51 | 52 | } 53 | 54 | //-------------------------------------------------------------- 55 | void testApp::update(){ 56 | int i; 57 | 58 | vidInput.update(); 59 | if(vidInput.isFrameNew()) 60 | { 61 | // get camera img into iplimage 62 | colorImg.setFromPixels(vidInput.getPixels(), CAM_WIDTH, CAM_HEIGHT); 63 | 64 | if (chosen_img) { 65 | grayImg = colorImg; 66 | detector.setImageSearch(grayImg.getCvImage()); 67 | detector.update(); 68 | } 69 | 70 | 71 | } 72 | } 73 | 74 | //-------------------------------------------------------------- 75 | void testApp::draw(){ 76 | ofBackground(0,0,0); 77 | 78 | ofSetColor(255, 255, 255); 79 | 80 | // camera image 81 | vidInput.draw(0, 0); 82 | 83 | // draw a rectanlge around the current selection 84 | if (choosing_img) { 85 | int x = mouseX; 86 | int y = mouseY; 87 | 88 | ofNoFill(); 89 | ofRect(x_start < x ? x_start : x, 90 | y_start < y ? y_start : y, 91 | abs(x_start - x), 92 | abs(y_start - y)); 93 | 94 | } 95 | 96 | if (chosen_img) { 97 | 98 | ofPushMatrix(); 99 | ofTranslate(CAM_WIDTH, 0, 0); 100 | testImg.draw(0, 0); 101 | ofPopMatrix(); 102 | 103 | ofSetColor(200, 20, 50); 104 | 105 | ofLine(detector.dst_corners[0].x, detector.dst_corners[0].y, 106 | detector.dst_corners[1].x, detector.dst_corners[1].y); 107 | 108 | ofLine(detector.dst_corners[2].x, detector.dst_corners[2].y, 109 | detector.dst_corners[1].x, detector.dst_corners[1].y); 110 | 111 | ofLine(detector.dst_corners[2].x, detector.dst_corners[2].y, 112 | detector.dst_corners[3].x, detector.dst_corners[3].y); 113 | 114 | ofLine(detector.dst_corners[0].x, detector.dst_corners[0].y, 115 | detector.dst_corners[3].x, detector.dst_corners[3].y); 116 | 117 | } 118 | 119 | 120 | } 121 | 122 | 123 | //-------------------------------------------------------------- 124 | void testApp::keyPressed (int key){ 125 | 126 | switch (key){ 127 | case 's': 128 | vidInput.videoSettings(); 129 | break; 130 | case '1': 131 | break; 132 | case '2': 133 | break; 134 | 135 | case 'b': 136 | break; 137 | 138 | } 139 | } 140 | 141 | //-------------------------------------------------------------- 142 | void testApp::mouseMoved(int x, int y ){ 143 | } 144 | 145 | //-------------------------------------------------------------- 146 | void testApp::mouseDragged(int x, int y, int button){ 147 | } 148 | 149 | //-------------------------------------------------------------- 150 | void testApp::mousePressed(int x, int y, int button){ 151 | 152 | // start a rectangle selection 153 | if(!choosing_img) 154 | { 155 | choosing_img = true; 156 | x_start = x; 157 | y_start = y; 158 | } 159 | } 160 | 161 | //-------------------------------------------------------------- 162 | void testApp::mouseReleased(int x, int y, int button){ 163 | 164 | // end the rectangle selection 165 | if (choosing_img) { 166 | choosing_img = false; 167 | x_end = x; 168 | y_end = y; 169 | 170 | if(x_start > x_end) 171 | std::swap(x_start, x_end); 172 | if(y_start > y_end) 173 | std::swap(y_start, y_end); 174 | 175 | int w = x_end - x_start; 176 | int h = y_end - y_start; 177 | 178 | cvSetImageROI(colorImg.getCvImage(), 179 | cvRect(x_start, 180 | y_start, 181 | w, h)); 182 | 183 | if (testImg.bAllocated) { 184 | testImg.clear(); 185 | testGrayImg.clear(); 186 | } 187 | testImg.allocate(w, h); 188 | testGrayImg.allocate(w, h); 189 | testImg = colorImg; 190 | testGrayImg = testImg; 191 | cvResetImageROI(colorImg.getCvImage()); 192 | 193 | detector.setImageTemplate(testGrayImg.getCvImage()); 194 | chosen_img = true; 195 | } 196 | 197 | } 198 | 199 | //-------------------------------------------------------------- 200 | void testApp::windowResized(int w, int h){ 201 | 202 | } -------------------------------------------------------------------------------- /src/.svn/text-base/testApp.h.svn-base: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Parag K. Mital - http://pkmital.com 3 | * Contact: parag@pkmital.com 4 | * 5 | * Copyright 2011 Parag K. Mital. All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | #ifndef _TEST_APP 29 | #define _TEST_APP 30 | 31 | #include "ofMain.h" 32 | 33 | #include "pkmDetector.h" 34 | 35 | #include "ofxOpenCv.h" 36 | #include "ofShader.h" 37 | 38 | #include 39 | #include 40 | 41 | const int CAM_WIDTH = 320; 42 | const int CAM_HEIGHT = 240; 43 | const int SCREEN_WIDTH = CAM_WIDTH*2; 44 | const int SCREEN_HEIGHT = CAM_HEIGHT + 75; 45 | 46 | 47 | 48 | 49 | class testApp : public ofBaseApp { 50 | 51 | public: 52 | 53 | ~testApp(); 54 | void setup(); 55 | 56 | void update(); 57 | void draw(); 58 | 59 | void keyPressed (int key); 60 | void mouseMoved(int x, int y ); 61 | void mouseDragged(int x, int y, int button); 62 | void mousePressed(int x, int y, int button); 63 | void mouseReleased(int x, int y, int button); 64 | void windowResized(int w, int h); 65 | 66 | ofVideoGrabber vidInput; 67 | 68 | ofxCvColorImage colorImg, testImg; 69 | ofxCvGrayscaleImage grayImg, testGrayImg; 70 | 71 | int x_start, x_end, y_start, y_end; 72 | bool choosing_img, chosen_img; 73 | pkmDetector detector; 74 | int detection; 75 | 76 | }; 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofMain.h" 2 | #include "testApp.h" 3 | #include "ofAppGlutWindow.h" 4 | 5 | //======================================================================== 6 | int main( ){ 7 | 8 | ofAppGlutWindow window; 9 | ofSetupOpenGL(&window, SCREEN_WIDTH, SCREEN_HEIGHT, OF_WINDOW); // <-------- setup the GL context 10 | 11 | // this kicks off the running of my app 12 | // can be OF_WINDOW or OF_FULLSCREEN 13 | // pass in width and height too: 14 | ofRunApp( new testApp()); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/testApp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Parag K. Mital - http://pkmital.com 3 | * Contact: parag@pkmital.com 4 | * 5 | * Copyright 2011 Parag K. Mital. All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | 29 | #include "testApp.h" 30 | //-------------------------------------------------------------- 31 | testApp::~testApp(){ 32 | } 33 | void testApp::setup(){ 34 | 35 | // init video input 36 | vidInput.initGrabber(CAM_WIDTH,CAM_HEIGHT); 37 | vidInput.setUseTexture(true); 38 | 39 | // window setup 40 | ofSetWindowShape(SCREEN_WIDTH, SCREEN_HEIGHT); 41 | ofSetVerticalSync(true); 42 | ofSetFrameRate(60); 43 | ofBackground(0,0,0); 44 | 45 | // allocate stuff 46 | colorImg.allocate(CAM_WIDTH, CAM_HEIGHT); 47 | grayImg.allocate(CAM_WIDTH, CAM_HEIGHT); 48 | 49 | choosing_img = false; 50 | chosen_img = false; 51 | 52 | } 53 | 54 | //-------------------------------------------------------------- 55 | void testApp::update(){ 56 | int i; 57 | 58 | vidInput.update(); 59 | if(vidInput.isFrameNew()) 60 | { 61 | // get camera img into iplimage 62 | colorImg.setFromPixels(vidInput.getPixels(), CAM_WIDTH, CAM_HEIGHT); 63 | 64 | if (chosen_img) { 65 | grayImg = colorImg; 66 | detector.setImageSearch(grayImg.getCvImage()); 67 | detector.update(); 68 | } 69 | 70 | 71 | } 72 | } 73 | 74 | //-------------------------------------------------------------- 75 | void testApp::draw(){ 76 | ofBackground(0,0,0); 77 | 78 | ofSetColor(255, 255, 255); 79 | 80 | // camera image 81 | vidInput.draw(0, 0); 82 | 83 | // draw a rectanlge around the current selection 84 | if (choosing_img) { 85 | int x = mouseX; 86 | int y = mouseY; 87 | 88 | ofNoFill(); 89 | ofRect(x_start < x ? x_start : x, 90 | y_start < y ? y_start : y, 91 | abs(x_start - x), 92 | abs(y_start - y)); 93 | 94 | } 95 | 96 | if (chosen_img) { 97 | 98 | ofPushMatrix(); 99 | ofTranslate(CAM_WIDTH, 0, 0); 100 | testImg.draw(0, 0); 101 | ofPopMatrix(); 102 | 103 | ofSetColor(200, 20, 50); 104 | 105 | ofLine(detector.dst_corners[0].x, detector.dst_corners[0].y, 106 | detector.dst_corners[1].x, detector.dst_corners[1].y); 107 | 108 | ofLine(detector.dst_corners[2].x, detector.dst_corners[2].y, 109 | detector.dst_corners[1].x, detector.dst_corners[1].y); 110 | 111 | ofLine(detector.dst_corners[2].x, detector.dst_corners[2].y, 112 | detector.dst_corners[3].x, detector.dst_corners[3].y); 113 | 114 | ofLine(detector.dst_corners[0].x, detector.dst_corners[0].y, 115 | detector.dst_corners[3].x, detector.dst_corners[3].y); 116 | 117 | } 118 | 119 | 120 | } 121 | 122 | 123 | //-------------------------------------------------------------- 124 | void testApp::keyPressed (int key){ 125 | 126 | switch (key){ 127 | case 's': 128 | vidInput.videoSettings(); 129 | break; 130 | case '1': 131 | break; 132 | case '2': 133 | break; 134 | 135 | case 'b': 136 | break; 137 | 138 | } 139 | } 140 | 141 | //-------------------------------------------------------------- 142 | void testApp::mouseMoved(int x, int y ){ 143 | } 144 | 145 | //-------------------------------------------------------------- 146 | void testApp::mouseDragged(int x, int y, int button){ 147 | } 148 | 149 | //-------------------------------------------------------------- 150 | void testApp::mousePressed(int x, int y, int button){ 151 | 152 | // start a rectangle selection 153 | if(!choosing_img) 154 | { 155 | choosing_img = true; 156 | x_start = x; 157 | y_start = y; 158 | } 159 | } 160 | 161 | //-------------------------------------------------------------- 162 | void testApp::mouseReleased(int x, int y, int button){ 163 | 164 | // end the rectangle selection 165 | if (choosing_img) { 166 | choosing_img = false; 167 | x_end = x; 168 | y_end = y; 169 | 170 | if(x_start > x_end) 171 | std::swap(x_start, x_end); 172 | if(y_start > y_end) 173 | std::swap(y_start, y_end); 174 | 175 | int w = x_end - x_start; 176 | int h = y_end - y_start; 177 | 178 | cvSetImageROI(colorImg.getCvImage(), 179 | cvRect(x_start, 180 | y_start, 181 | w, h)); 182 | 183 | if (testImg.bAllocated) { 184 | testImg.clear(); 185 | testGrayImg.clear(); 186 | } 187 | testImg.allocate(w, h); 188 | testGrayImg.allocate(w, h); 189 | testImg = colorImg; 190 | testGrayImg = testImg; 191 | cvResetImageROI(colorImg.getCvImage()); 192 | 193 | detector.setImageTemplate(testGrayImg.getCvImage()); 194 | chosen_img = true; 195 | } 196 | 197 | } 198 | 199 | //-------------------------------------------------------------- 200 | void testApp::windowResized(int w, int h){ 201 | 202 | } -------------------------------------------------------------------------------- /src/testApp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Created by Parag K. Mital - http://pkmital.com 3 | * Contact: parag@pkmital.com 4 | * 5 | * Copyright 2011 Parag K. Mital. All rights reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person 8 | * obtaining a copy of this software and associated documentation 9 | * files (the "Software"), to deal in the Software without 10 | * restriction, including without limitation the rights to use, 11 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the 13 | * Software is furnished to do so, subject to the following 14 | * conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be 17 | * included in all copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 21 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 26 | * OTHER DEALINGS IN THE SOFTWARE. 27 | */ 28 | #ifndef _TEST_APP 29 | #define _TEST_APP 30 | 31 | #include "ofMain.h" 32 | 33 | #include "pkmDetector.h" 34 | 35 | #include "ofxOpenCv.h" 36 | #include "ofShader.h" 37 | 38 | #include 39 | #include 40 | 41 | const int CAM_WIDTH = 320; 42 | const int CAM_HEIGHT = 240; 43 | const int SCREEN_WIDTH = CAM_WIDTH*2; 44 | const int SCREEN_HEIGHT = CAM_HEIGHT + 75; 45 | 46 | 47 | 48 | 49 | class testApp : public ofBaseApp { 50 | 51 | public: 52 | 53 | ~testApp(); 54 | void setup(); 55 | 56 | void update(); 57 | void draw(); 58 | 59 | void keyPressed (int key); 60 | void mouseMoved(int x, int y ); 61 | void mouseDragged(int x, int y, int button); 62 | void mousePressed(int x, int y, int button); 63 | void mouseReleased(int x, int y, int button); 64 | void windowResized(int w, int h); 65 | 66 | ofVideoGrabber vidInput; 67 | 68 | ofxCvColorImage colorImg, testImg; 69 | ofxCvGrayscaleImage grayImg, testGrayImg; 70 | 71 | int x_start, x_end, y_start, y_end; 72 | bool choosing_img, chosen_img; 73 | pkmDetector detector; 74 | int detection; 75 | 76 | }; 77 | 78 | #endif 79 | --------------------------------------------------------------------------------