ChessBoardFinder.cpp
1 |
#include <iostream> |
---|---|
2 |
#include <cstdlib> |
3 |
#include <math.h> |
4 |
#include <time.h> |
5 |
#include <rsb/Factory.h> |
6 |
#include <boost/program_options.hpp> |
7 |
|
8 |
#include <opencv/cv.h> |
9 |
#include <opencv/highgui.h> |
10 |
|
11 |
#include <rsb/converter/Repository.h> |
12 |
|
13 |
#include "HandDetectionHSV.h" |
14 |
|
15 |
#include "HoughLines2.h" |
16 |
#include "Util.h" |
17 |
#include "ChessDetection.h" |
18 |
#include "BoardLocalizationLines.h" |
19 |
#include "StrongFeaturesToTrackKeyPoints.h" |
20 |
#include "FieldOccCanny.h" |
21 |
#include "FieldOccHoughCircles.h" |
22 |
#include "IFieldOccDetection.h" |
23 |
#include "DataReader.h" |
24 |
#include "ResultPublisher.h" |
25 |
|
26 |
#ifdef USE_IMAGES_INSTEAD_OF_IMAGEFIXATIONS
|
27 |
#include <rst/converters/opencv/IplImageConverter.h> |
28 |
#else
|
29 |
#include <rst/converters/opencv/IplImageConverter.h> // We need both here!! |
30 |
#include <ChessBase\ImageFixationConverter.h> |
31 |
#endif
|
32 |
|
33 |
using namespace std; |
34 |
using namespace cv; |
35 |
|
36 |
namespace po = boost::program_options;
|
37 |
void handleCommandline(int argc, char *argv[]); |
38 |
|
39 |
string videoPath = "../../data/thomas-1-recording-fixed.avi"; |
40 |
|
41 |
|
42 |
#ifdef USE_IMAGES_INSTEAD_OF_IMAGEFIXATIONS
|
43 |
string inScope = "/video"; |
44 |
#else
|
45 |
string inScope = "/imagefixations"; |
46 |
#endif
|
47 |
|
48 |
string outScopeOccFields = "/occupiedFields"; |
49 |
string outScopeFixatedField = "/fixatedField"; |
50 |
int skipframe = 3*60*30;//skip 3 minutes |
51 |
int debugMode = 0; |
52 |
int recordMode = 0; |
53 |
int videoMode = 0; |
54 |
int main(int argc, char *argv[]) { |
55 |
cout << "chessboardfinder" << endl;
|
56 |
handleCommandline(argc, argv); |
57 |
ostringstream resultdat; |
58 |
DataReader dataReader = DataReader(); |
59 |
//boost::shared_ptr< rsb::converter::ProtocolBufferConverter<rst::generic::ListFloat> >
|
60 |
// converter(new rsb::converter::ProtocolBufferConverter<rst::generic::ListFloat>());
|
61 |
// rsb::converter::converterRepository<std::string>()->registerConverter(converter);
|
62 |
|
63 |
ResultPublisher resultPublisher(outScopeOccFields,outScopeFixatedField); |
64 |
resultPublisher.setupRSB(); |
65 |
VideoWriter record; |
66 |
|
67 |
if(videoMode){
|
68 |
dataReader.initVidCap(videoPath,skipframe); |
69 |
}else{
|
70 |
dataReader.initRSB(inScope); |
71 |
} |
72 |
|
73 |
if(recordMode){
|
74 |
resultdat << "../../data/result-" << time(NULL) << ".avi"; |
75 |
std::string resfile = resultdat.str();
|
76 |
record = VideoWriter(resfile, CV_FOURCC('D','I','V','X'), 15,Size(400,400), true); |
77 |
} |
78 |
cv::Mat frame; |
79 |
#ifndef USE_IMAGES_INSTEAD_OF_IMAGEFIXATIONS
|
80 |
Fixation fixation; |
81 |
#endif
|
82 |
clock_t start, end; |
83 |
cout << "Finished preparation" << endl;
|
84 |
ChessDetection chessDetect = ChessDetection(); |
85 |
HandDetectionHSV handDetect = HandDetectionHSV(); |
86 |
handDetect.setSkinPercentage(0.000000000001); |
87 |
BoardLocalizationLines boardDetect = BoardLocalizationLines(); |
88 |
StrongFeaturesToTrackKeyPoints keyPointDetect = StrongFeaturesToTrackKeyPoints(); |
89 |
vector<pair<IFieldOccDetection*,double>> fieldOccAlgos;
|
90 |
|
91 |
FieldOccCanny fieldOccCanny = FieldOccCanny(); |
92 |
fieldOccAlgos.push_back(pair<IFieldOccDetection*,double>(&fieldOccCanny,1.0)); |
93 |
FieldOccHoughCircles fieldOccHoughCircles = FieldOccHoughCircles(); |
94 |
fieldOccAlgos.push_back(pair<IFieldOccDetection*,double>(&fieldOccHoughCircles,3.0)); |
95 |
|
96 |
ImageManager imageManagerInput; |
97 |
ImageManager imageManagerUndistorted; |
98 |
|
99 |
for(;;){
|
100 |
|
101 |
if(videoMode){
|
102 |
if(!dataReader.readImageFile(&frame))
|
103 |
break;
|
104 |
}else{
|
105 |
cout << "PREPOP" << endl;
|
106 |
|
107 |
#ifdef USE_IMAGES_INSTEAD_OF_IMAGEFIXATIONS
|
108 |
if(!dataReader.readImageRSB(&frame))
|
109 |
break;
|
110 |
#else
|
111 |
if(!dataReader.readImageFixationRSB(&frame, &fixation))
|
112 |
break;
|
113 |
cout << "Yippie, got frame and fixation (Start " << fixation.start << ")" << endl; |
114 |
#endif
|
115 |
|
116 |
cout << "POPPED" << endl;
|
117 |
} |
118 |
|
119 |
//-----------------------------
|
120 |
//preprocessing
|
121 |
cout << "//////////////////////////////////////////////////////" << endl;
|
122 |
//cout << "frame: " << vidCap.get(CV_CAP_PROP_POS_FRAMES) << endl;
|
123 |
clock_t time_full; |
124 |
clock_t start_full = clock(); |
125 |
//do processingsteps
|
126 |
imageManagerInput.setRgbImage(frame); |
127 |
//start processing
|
128 |
bool handinside = chessDetect.detectHands(handDetect,imageManagerInput);
|
129 |
if(handinside){
|
130 |
cout << "skip processing because of hand" << endl;
|
131 |
imshow("video", frame); if(cv::waitKey(30) >= 0) break; |
132 |
continue;
|
133 |
} |
134 |
vector<Point2f> keyPointsSFTT = chessDetect.detectKeyPoints(keyPointDetect,imageManagerInput); |
135 |
vector<Point2f> chessBoardCornersSrc = chessDetect.detectChessboardPos(boardDetect,imageManagerInput); |
136 |
Mat transformationMat = chessDetect.warpPerspectiveMat(imageManagerInput,&imageManagerUndistorted,chessBoardCornersSrc,Size(400,400),0); |
137 |
//cout << "transformationMat " << transformationMat << endl;
|
138 |
cout << "corners " << Mat(chessBoardCornersSrc) << endl;
|
139 |
Mat undistorted = imageManagerUndistorted.getRgbImage(); |
140 |
vector<Point2f> newSFTTUndistorted(keyPointsSFTT.size()); |
141 |
perspectiveTransform(boardDetect.getLineIntersectionsPoints(),newSFTTUndistorted,transformationMat); |
142 |
|
143 |
cv::flann::KDTreeIndexParams indexParams(5);
|
144 |
Mat query(1,2,CV_32FC1); |
145 |
Mat pointMat = Mat(newSFTTUndistorted).reshape(1);
|
146 |
flann::Index kdtree(pointMat, indexParams); |
147 |
vector<Point2f> singleQuery; |
148 |
Mat index(1, 4, CV_32S); |
149 |
Mat dist(1, 4, CV_32F); |
150 |
RNG rng(12345);
|
151 |
Mat undistBW(400,400,CV_32FC1); |
152 |
Mat thMatB(undistorted.size(),(undistorted.depth(), 1));
|
153 |
Mat undistGray; |
154 |
Mat undistorted2 = undistorted.clone(); |
155 |
cvtColor( undistorted2, undistGray, CV_RGB2GRAY ); |
156 |
Mat undistGrayC = undistGray.clone(); |
157 |
threshold(undistGray,thMatB,255,255,THRESH_BINARY); |
158 |
Mat undistGrayE; |
159 |
|
160 |
imageManagerUndistorted.setRgbImage(undistorted); |
161 |
|
162 |
//combine multiple fieldOccupiedVariants
|
163 |
vector<double> tmp(64); |
164 |
fill(tmp.begin(),tmp.end(),0);
|
165 |
Mat combined(tmp); |
166 |
double sumWeights=0; |
167 |
for(vector<pair<IFieldOccDetection*,double> >::iterator fieldOccDect = fieldOccAlgos.begin(); fieldOccDect != fieldOccAlgos.end(); ++fieldOccDect) |
168 |
{ |
169 |
vector<double> occupiedFields = chessDetect.occupiedFields(*(fieldOccDect->first),imageManagerUndistorted);
|
170 |
add(Mat(combined),Mat(occupiedFields)*fieldOccDect->second,combined); |
171 |
sumWeights += fieldOccDect->second; |
172 |
} |
173 |
combined = combined / sumWeights; |
174 |
cout << "combined" << combined << endl;
|
175 |
|
176 |
vector<float> resultOccFields;
|
177 |
combined.col(0).copyTo(resultOccFields);
|
178 |
cout << "resultOccFields.size() " << resultOccFields.size() << endl;
|
179 |
if(resultOccFields.size()==64) |
180 |
resultPublisher.sendResultOccFields(resultOccFields);//TODO buggy - runtimeError
|
181 |
|
182 |
Point2f fixatedPoint(fixation.locationX,fixation.locationY); |
183 |
vector<Point2f> tmp1,tmp2; |
184 |
tmp1.push_back(fixatedPoint); |
185 |
perspectiveTransform(tmp1,tmp2,transformationMat); |
186 |
fixatedPoint = tmp2[0];
|
187 |
int fixationFieldX = fixatedPoint.x / 400 *8; |
188 |
int fixationFieldY = fixatedPoint.y / 400 *8; |
189 |
int fixatedFieldID = fixationFieldX + 8 * fixationFieldY; |
190 |
resultPublisher.sendResultFixatedField(fixatedFieldID); |
191 |
circle(undistorted, fixatedPoint,5,Scalar(255,0,0),-1); |
192 |
|
193 |
|
194 |
//undistGrayC.convertTo(undistGrayC, -1, 2.0f, 10);
|
195 |
/*int histSize = 60;
|
196 |
|
197 |
/// Set the ranges ( for B,G,R) )
|
198 |
float range[] = { 0, 255 } ;
|
199 |
const float* histRange = { range };
|
200 |
|
201 |
bool uniform = true; bool accumulate = false;
|
202 |
|
203 |
Mat hist;
|
204 |
|
205 |
/// Compute the histograms:
|
206 |
calcHist( &undistGray, 1, 0, Mat(), hist, 1, &histSize, &histRange, uniform, accumulate );
|
207 |
int hist_w = 512; int hist_h = 400;
|
208 |
int bin_w = cvRound( (double) hist_w/histSize );
|
209 |
Mat histImage( hist_h, hist_w, CV_8UC3, Scalar( 0,0,0) );
|
210 |
|
211 |
/// Normalize the result to [ 0, histImage.rows ]
|
212 |
normalize(hist, hist, 0, histImage.rows, NORM_MINMAX, -1, Mat() );
|
213 |
|
214 |
/// Draw for each channel
|
215 |
for( int i = 1; i < histSize; i++ )
|
216 |
{
|
217 |
cout << "hist.at<float>(i) = " << hist.at<float>(i) << endl;
|
218 |
if(hist.at<float>(i) > 0.25 * hist_h){
|
219 |
line( histImage, Point( bin_w*(i), hist_h - cvRound(hist.at<float>(i)) ),Point( bin_w*(i),hist_h ) ,
|
220 |
|
221 |
Scalar( 255, 0, 0), 3, 8, 0 );
|
222 |
}
|
223 |
|
224 |
}
|
225 |
|
226 |
for( int i = 1; i < histSize; i++ )
|
227 |
{
|
228 |
line( histImage, Point( bin_w*(i-1),hist_h - cvRound(hist.at<float>(i-1)) ) ,
|
229 |
Point( bin_w*(i), hist_h - cvRound(hist.at<float>(i)) ),
|
230 |
Scalar( 255, 0, 0), 3, 8, 0 );
|
231 |
}
|
232 |
|
233 |
/// Display
|
234 |
namedWindow("calcHist Demo", CV_WINDOW_AUTOSIZE );
|
235 |
imshow("calcHist Demo", histImage );*/
|
236 |
/*cout << "newPointsUndistorted = " << newSFTTUndistorted.size() << endl;
|
237 |
equalizeHist(undistGray,undistGrayE);
|
238 |
if(newSFTTUndistorted.size() == 81){
|
239 |
|
240 |
|
241 |
//single field processing
|
242 |
for(int i = 0; i < 8; i++){
|
243 |
Rect roiLine(i*50,0,50,400);
|
244 |
//equalizeHist(undistGray(roiLine),undistGray(roiLine));
|
245 |
for(int j = 0; j < 8; j++){
|
246 |
bool whiteField = i%2 ==j%2;
|
247 |
//cout << "field (" << i << "|"<<j<<") processed" << endl;
|
248 |
Point2f center = Point2f(400 / 8 * i + 400/8/2,400 / 8 * j + 400/8/2);
|
249 |
singleQuery.clear();
|
250 |
singleQuery.push_back(center);
|
251 |
Mat singleQuerMat = Mat(singleQuery).reshape(1);
|
252 |
kdtree.knnSearch(singleQuerMat, index, dist, 4, cv::flann::SearchParams(64));
|
253 |
Point2f max(0,0),min(400,400);
|
254 |
Scalar color( rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255) );
|
255 |
for(int k = 0; k < 4; k++)
|
256 |
{
|
257 |
Point2f startP = newSFTTUndistorted[index.at<int>(0,k)];
|
258 |
if(startP.x+startP.y > max.x+max.y )max = startP;
|
259 |
if(startP.x+startP.y < min.x+min.y )min = startP;
|
260 |
}
|
261 |
|
262 |
Rect roi(min+Point2f(7,9),max-Point2f(7,3)) ;
|
263 |
|
264 |
Mat imgRoi = undistorted(roi);
|
265 |
|
266 |
Mat grayRoi = undistGray(roi);
|
267 |
|
268 |
Rect roi2(roi);
|
269 |
roi2.height /= 2;
|
270 |
Mat imgRoi2 = undistorted(roi2);
|
271 |
Mat grayRoi2 = undistGray(roi2);
|
272 |
|
273 |
//not working cause of ilumination?
|
274 |
Mat grayRoiE = undistGrayE(roi2);
|
275 |
Mat thMat = thMatB(roi2);
|
276 |
int th = 30;
|
277 |
if(whiteField){
|
278 |
th = 150;
|
279 |
//cout << "white field" << endl;
|
280 |
threshold(grayRoiE,thMat,th,255,THRESH_BINARY_INV);
|
281 |
}
|
282 |
else{
|
283 |
th = 140;
|
284 |
//cout << "black field" << endl;
|
285 |
threshold(grayRoiE,thMat,th,255,THRESH_BINARY);
|
286 |
}
|
287 |
|
288 |
int diffPixel = countNonZero(thMat);
|
289 |
std::stringstream stst3 ;
|
290 |
stst3 << diffPixel;
|
291 |
|
292 |
Scalar m2;
|
293 |
Scalar stddev;
|
294 |
|
295 |
meanStdDev(grayRoi2,m2,stddev);
|
296 |
//cout << "stddev= " << stddev[0] << endl;
|
297 |
|
298 |
// if(stddev[0] > 10)
|
299 |
// equalizeHist(grayRoi2,grayRoi2);
|
300 |
//cvtColor( imgRoi, grayRoi, CV_RGB2GRAY );
|
301 |
|
302 |
Scalar m = mean(grayRoi);
|
303 |
|
304 |
//TODO doing anything?
|
305 |
|
306 |
std::stringstream stst2 ;
|
307 |
stst2 << (int)m[0];
|
308 |
int th_canny =50;
|
309 |
|
310 |
if(m[0]<70 || !whiteField){
|
311 |
//grayRoi.convertTo(grayRoi, -1, 2.0f, 10);
|
312 |
//imgRoi.convertTo(imgRoi, -1, 2.0f, 10);
|
313 |
//circle( undistorted, center, 6, Scalar(255,255,0), 3, 8, 0 );
|
314 |
th_canny = 40;
|
315 |
}
|
316 |
|
317 |
|
318 |
//Mat abc = undistGray(roi);
|
319 |
//Mat abc2 = undistBW(roi);
|
320 |
// threshold( abc,abc2 ,128,255,CV_THRESH_BINARY | CV_THRESH_OTSU);
|
321 |
// cout << "th succes" << endl;
|
322 |
//vector<vector<Point> > contours;
|
323 |
// vector<Vec4i> hierarchy;
|
324 |
// contours.clear();
|
325 |
// Mat testRoi = undistBW(roi);
|
326 |
// findContours(testRoi , contours, hierarchy,
|
327 |
// CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
|
328 |
|
329 |
// // iterate through all the top-level contours,
|
330 |
// // draw each connected component with its own random color
|
331 |
// cout << "calc success" << endl;
|
332 |
// int idx = 0;
|
333 |
// for( ; idx >= 0; idx = hierarchy[idx][0] )
|
334 |
// {
|
335 |
// Scalar color( rand()&255, rand()&255, rand()&255 );
|
336 |
// drawContours( undistorted2(roi), contours, idx, color, CV_FILLED, 8, hierarchy );
|
337 |
// }
|
338 |
|
339 |
Mat cannyRoi;
|
340 |
|
341 |
//cvtColor( imgRoi2, grayRoi2, CV_RGB2GRAY );
|
342 |
|
343 |
Canny(grayRoi2,cannyRoi,40,80);
|
344 |
|
345 |
int canny_nz = countNonZero(cannyRoi);
|
346 |
std::stringstream stst ;
|
347 |
|
348 |
stst << canny_nz ;
|
349 |
vector<Vec3f> circles;
|
350 |
|
351 |
HoughCircles(grayRoi,circles,CV_HOUGH_GRADIENT, 1, grayRoi.rows/8, 25, 18, 10, 0 );
|
352 |
if(stddev[0]>10 || canny_nz > th_canny){ //circles.size() > 0 ||
|
353 |
for( size_t i = 0; i < circles.size(); i++ )
|
354 |
{
|
355 |
Point centerP(cvRound(circles[i][0]), cvRound(circles[i][1]));
|
356 |
int radius = cvRound(circles[i][2]);
|
357 |
//circle( imgRoi, centerP, 3, Scalar(0,255,0), -1, 8, 0 );
|
358 |
//circle( imgRoi, centerP, radius, Scalar(0,255,0), 3, 8, 0 );
|
359 |
|
360 |
}
|
361 |
if(circles.size() > 0 )
|
362 |
circle( undistorted, center, 3, Scalar(0,255,0), -1, 8, 0 );
|
363 |
else
|
364 |
circle( undistorted, center, 3, Scalar(255,255,0), -1, 8, 0 );
|
365 |
|
366 |
putText( undistorted, stst.str(),center-Point2f(0,10),0,0.4f, Scalar(0,255,0));
|
367 |
putText( undistorted, stst2.str(),center+Point2f(0,20),0,0.4f, Scalar(0,255,0));
|
368 |
putText( undistorted, stst3.str(),center+Point2f(5,5),0,0.4f, Scalar(0,255,0));
|
369 |
} else {
|
370 |
//cout << "no circles found" << endl;
|
371 |
circle( undistorted, center, 3, Scalar(0,0,255), -1, 8, 0 );
|
372 |
putText( undistorted, stst.str(),center-Point2f(0,10),0,0.4f, Scalar(0,0,255));
|
373 |
putText( undistorted, stst2.str(),center+Point2f(0,20),0,0.4f, Scalar(0,0,255));
|
374 |
putText( undistorted, stst3.str(),center+Point2f(5,5),0,0.4f, Scalar(0,0,255));
|
375 |
}
|
376 |
|
377 |
rectangle(undistorted,roi,Scalar(255,0,0));
|
378 |
rectangle(undistorted,roi2,Scalar(255,255,0));
|
379 |
}
|
380 |
}
|
381 |
}else{
|
382 |
cout << "something went wrong - no full chessboard detected" << endl;
|
383 |
}
|
384 |
*/
|
385 |
clock_t end_full = clock(); |
386 |
time_full = (end_full-start_full); |
387 |
|
388 |
//save result
|
389 |
if(recordMode)
|
390 |
record << undistorted; |
391 |
//Mat highContrast = undistorted;
|
392 |
//undistorted.convertTo(highContrast, -1, 1.5f, 20);
|
393 |
|
394 |
//imshow("videoBW", undistGray);
|
395 |
//imshow("videoBW2", thMatB);
|
396 |
//equalizeHist(undistGrayC,undistGrayC);
|
397 |
//imshow("videoBW2", undistBW);
|
398 |
//Mat diff = undistGrayC-undistGray;
|
399 |
//threshold(diff,diff,0,255,CV_THRESH_BINARY | CV_THRESH_OTSU);
|
400 |
//imshow("videoBW2",diff);
|
401 |
imshow("video", imageManagerInput.getRgbImage()); imshow("video2", imageManagerUndistorted.getRgbImage());if(cv::waitKey(30) >= 0) break; |
402 |
|
403 |
cout << ((double)(time_full)/(double)CLOCKS_PER_SEC)*1000 << " milliseconds for all" << endl; |
404 |
//boost::this_thread::sleep(boost::posix_time::milliseconds(10000));
|
405 |
continue;
|
406 |
|
407 |
|
408 |
//NOT USED
|
409 |
//ORB-KEYPOINTS ON CORNERS
|
410 |
/*cv::Rect chess(frame.rows/2,frame.cols/2,20,20);
|
411 |
//cout << corners.size() << " corners found! " <<endl;
|
412 |
if(corners.size()>0){
|
413 |
cornerSubPix(gray, corners, cv::Size(11, 11), cv::Size(-1, -1),
|
414 |
cv::TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
|
415 |
cout << corners.size() << " corners after refinement! " <<endl;
|
416 |
vector<cv::KeyPoint> keypoints;
|
417 |
for(int i=0; i < corners.size(); i++)
|
418 |
{
|
419 |
keypoints.push_back(KeyPoint(corners[i],15));
|
420 |
}
|
421 |
cv::Scalar keypointColor = cv::Scalar(255, 0, 0);
|
422 |
//drawKeypoints(frame, keypoints, frame, keypointColor, cv::DrawMatchesFlags::DEFAULT);
|
423 |
imshow( "corners", frame ); if(cv::waitKey(30) >= 0) break;
|
424 |
continue;
|
425 |
//cv::Ptr<cv::FeatureDetector> featureDetector = cv::FeatureDetector::create("FAST");
|
426 |
//cout << "creation complete" << endl;
|
427 |
//featureDetector->detect(frame, keypoints);
|
428 |
cout << "keypoints detected" << endl;
|
429 |
cv::Mat descriptors;
|
430 |
cv::Ptr<cv::DescriptorExtractor> featureExtractor = cv::DescriptorExtractor::create("ORB");
|
431 |
cout << "creation complete" << endl;
|
432 |
featureExtractor->compute(gray,keypoints,descriptors);
|
433 |
cout << "descriptors calculated" << endl;
|
434 |
// cv::Scalar keypointColor = cv::Scalar(255, 0, 0); // Blue keypoints.
|
435 |
// drawKeypoints(frame, keypoints, frame, keypointColor, cv::DrawMatchesFlags::DEFAULT);
|
436 |
// imshow("video", frame); if(cv::waitKey(30) >= 0) break;
|
437 |
cout << "before matchercreation " << endl;
|
438 |
cv::BruteForceMatcher< cv::L2<float> > matcher2 = cv::BruteForceMatcher< cv::L2<float> >();
|
439 |
cout << "after matchercreation " << endl;
|
440 |
//cv::Ptr<cv::DescriptorMatcher> matcher = cv::DescriptorMatcher::create("BruteForce");
|
441 |
vector< cv::DMatch > matches;
|
442 |
cout << "before matching " << endl;
|
443 |
matcher2.match(descriptors,descriptors.row(0),matches);
|
444 |
cout << "before adding trainingsset " << endl;
|
445 |
// matcher2.add(descriptors);
|
446 |
// cout << "before matching " << endl;
|
447 |
// matcher2.match(descriptors.row(1),matches);
|
448 |
cout << "matches found" << endl;
|
449 |
double max_dist = 0; double min_dist = 100;
|
450 |
//-- Quick calculation of max and min distances between keypoints
|
451 |
for( int i = 0; i < descriptors.rows; i++ )
|
452 |
{ double dist = matches[i].distance;
|
453 |
if( dist < min_dist ) min_dist = dist;
|
454 |
if( dist > max_dist ) max_dist = dist;
|
455 |
}
|
456 |
printf("-- Max dist : %f \n", max_dist );
|
457 |
printf("-- Min dist : %f \n", min_dist );
|
458 |
//-- Draw only "good" matches (i.e. whose distance is less than 2*min_dist )
|
459 |
//-- PS.- radiusMatch can also be used here.
|
460 |
std::vector< cv::DMatch > good_matches;
|
461 |
int maxMatches = 1000;
|
462 |
int actMatches = 0;
|
463 |
for( int i = 0; i < matches.size(); i++ )
|
464 |
{ if(actMatches < maxMatches && true)//matches[i].distance < (2*min_dist + max_dist/(double)2)
|
465 |
{ good_matches.push_back( matches[i]);
|
466 |
actMatches++;
|
467 |
}
|
468 |
}
|
469 |
cout << good_matches.size() << " good matches found" << endl;
|
470 |
//-- Draw only "good" matches
|
471 |
vector<cv::KeyPoint> keypoints2;
|
472 |
keypoints2.push_back(keypoints[1]);
|
473 |
cv::Mat img_matches;
|
474 |
drawMatches( frame, keypoints, frame, keypoints2,
|
475 |
good_matches, img_matches, cv::Scalar::all(-1), cv::Scalar::all(-1),
|
476 |
vector<char>(), cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
|
477 |
//-- Show detected matches
|
478 |
cv::Mat img_matches_small = cv::Mat(1400,700,img_matches.type());
|
479 |
cv::resize(img_matches,img_matches_small,cv::Size(1400,700));
|
480 |
imshow( "Good Matches", img_matches_small ); if(cv::waitKey(30) >= 0) break;
|
481 |
|
482 |
for( int i = 0; i < good_matches.size(); i++ )
|
483 |
{ printf( "-- Good Match [%d] Keypoint 1: %d -- Keypoint 2: %d with dist: %f \n", i, good_matches[i].queryIdx, good_matches[i].trainIdx,matches[i].distance); }
|
484 |
boost::this_thread::sleep(boost::posix_time::milliseconds(100));
|
485 |
clock_t time_all = time_handdetection + time_houghlines + time_corners;
|
486 |
cout << "full time: " << ((double)(time_houghlines)/(double)CLOCKS_PER_SEC)*1000 <<endl;
|
487 |
}
|
488 |
}*/
|
489 |
} |
490 |
cout << "Finished. Press Button to exit" << endl;
|
491 |
char waitForExit1 = getchar();
|
492 |
|
493 |
return EXIT_SUCCESS;
|
494 |
|
495 |
} |
496 |
|
497 |
void handleCommandline(int argc, char *argv[]) { |
498 |
po::options_description options("Allowed options");
|
499 |
|
500 |
options.add_options() |
501 |
("help,h", "Display a help message.") |
502 |
("videopath,v", po::value < string > (&videoPath), "Path to video (from eyetracker) to be processed.") |
503 |
("debugMode,d", po::value < int > (&debugMode), "Trigger for Debugmode."); |
504 |
|
505 |
po::variables_map vm; |
506 |
|
507 |
po::store( po::command_line_parser(argc, argv).options(options).run(), vm); |
508 |
|
509 |
// first, process the help option
|
510 |
if (vm.count("help")) { |
511 |
cout << options << "\n";
|
512 |
exit(1);
|
513 |
} |
514 |
if (vm.count("videopath")) { |
515 |
cout << "videopath:::" << videoPath << "\n"; |
516 |
} |
517 |
if (vm.count("debugMode")) { |
518 |
cout << "debugMode:::" << debugMode << "\n"; |
519 |
} |
520 |
|
521 |
// afterwards, let program options handle argument errors
|
522 |
po::notify(vm); |
523 |
|
524 |
cout << "Program started with:" << endl;
|
525 |
cout << " videopath=" << videoPath << endl;
|
526 |
} |