00001
00005 #include "tools.hpp"
00006
00007 bool comparator ( const mypair& l, const mypair& r) {
00008 return l.first < r.first;
00009 }
00010
00011 double perpDist(cv::Point2f& P1, cv::Point2f& P2, cv::Point2f& P3)
00012 {
00013
00014
00015
00016
00017 double u, x, y, d;
00018
00019 u = ((P3.x - P1.x)*(P2.x - P1.x) + (P3.y - P1.y)*(P2.y - P1.y)) / (pow(double(P2.x - P1.x), 2.0) + pow(double(P2.y - P1.y), 2.0));
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 x = P1.x + u*(P2.x - P1.x);
00030 y = P1.y + u*(P2.y - P1.y);
00031
00032 d = pow(pow(P3.x - x, 2.0) + pow(P3.y - y, 2.0),0.5);
00033
00034 return d;
00035 }
00036
00037 double distBetweenPts2f(cv::Point2f& P1, cv::Point2f& P2)
00038 {
00039
00040
00041
00042
00043
00044
00045 return pow((pow(double(P1.x - P2.x), 2.0) + pow(double(P1.y - P2.y),2)), 0.5);
00046 }
00047
00048 double distBetweenPts(cv::Point3d& P1, cv::Point3d& P2) {
00049 return pow(double(pow(double(P1.x - P2.x), 2.0) + pow(double(P1.y - P2.y), 2.0) + pow(double(P1.z - P2.z), 2.0)), 0.5);
00050 }
00051
00052 double distBetweenPts(cv::Point& P1, cv::Point& P2)
00053 {
00054
00055
00056
00057 double retVal;
00058 retVal = pow(double(pow(double(P1.x - P2.x), 2.0) + pow(double(P1.y - P2.y), 2.0)), 0.5);
00059 return retVal;
00060 }
00061
00062 double findMinimumSeparation(vector<cv::Point2f>& pts)
00063 {
00064 double minSep = 9e50;
00065 double val = 0.0;
00066
00067 for (unsigned int i = 0; i < pts.size(); i++)
00068 {
00069 for (unsigned int j = i+1; j < pts.size(); j++)
00070 {
00071 val = norm(pts.at(i)-pts.at(j));
00072 if (val < minSep)
00073 {
00074 minSep = val;
00075 }
00076 }
00077 }
00078
00079 return minSep;
00080 }
00081
00082 cv::Point2f meanPoint(cv::Point2f& P1, cv::Point2f& P2)
00083 {
00084 return cv::Point2f((P1.x+P2.x)/2, (P1.y+P2.y)/2);
00085 }
00086
00087 void findLinearModel(double* x, double* y, int termsToConsider, double &m, double &c) {
00088
00089 double mean_x = 0.0, mean_y = 0.0;
00090
00091 if (termsToConsider == 1) {
00092 m = 0.0;
00093 c = y[0];
00094
00095 return;
00096 }
00097
00098
00099
00100 for (int iii = 0; iii < termsToConsider; iii++) {
00101 mean_x += x[iii];
00102 mean_y += y[iii];
00103 }
00104
00105 mean_x /= double(termsToConsider);
00106 mean_y /= double(termsToConsider);
00107
00108
00109
00110 double s_x = 0.0, s_xy = 0.0;
00111
00112 for (int iii = 0; iii < termsToConsider; iii++) {
00113 s_x += pow(x[iii]-mean_x,2.0);
00114
00115 s_xy += (x[iii]-mean_x)*(y[iii]-mean_y);
00116 }
00117
00118
00119
00120 m = s_xy / s_x;
00121 c = mean_y - m*mean_x;
00122
00123
00124
00125 }
00126
00127 void writePoints(const char *filename, const vector<cv::Point2f>& pts) {
00128
00129 ofstream myfile;
00130 myfile.open(filename);
00131
00132 for (unsigned int jjj = 0; jjj < pts.size(); jjj++) {
00133 myfile << pts.at(jjj).x << "," << pts.at(jjj).y << endl;
00134 }
00135
00136 myfile.close();
00137
00138 }
00139
00140 void readPoints(const char *filename, vector<cv::Point2f>& pts) {
00141
00142 pts.clear();
00143 ifstream myfile;
00144 myfile.open(filename);
00145
00146 char buffer[512];
00147
00148 cv::Point2f latestPoint;
00149 char comma;
00150
00151 while (true) {
00152
00153 comma = ' ';
00154 myfile.getline(buffer, 512);
00155
00156 stringstream ss;
00157
00158 ss << buffer;
00159
00160 ss >> latestPoint.x >> comma >> latestPoint.y;
00161
00162 if (comma == ',') {
00163 pts.push_back(latestPoint);
00164 } else {
00165 break;
00166 }
00167
00168
00169 if (myfile.eof()) {
00170 break;
00171 }
00172 }
00173
00174
00175 myfile.close();
00176
00177 }
00178
00179 double lookupValue(double xi, double yi, double maxVal, const cv::Mat& lookupMat) {
00180
00181
00182 cv::Point2f coord(xi*((float) lookupMat.cols)/maxVal, yi*((float) lookupMat.rows)/maxVal);
00183
00184 double d = getInterpolatedVal(lookupMat, coord);
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 return d;
00199
00200 }
00201
00202 double getInterpolatedVal(const cv::Mat& img, cv::Point2f& coord) {
00203
00204 double retVal = 0.00;
00205
00206
00207
00208
00209 cv::Point dcoord[4];
00210 float val[4];
00211 float dist[4], total_dist = 0.0;
00212
00213 val[0] = 0.0;
00214 val[1] = 0.0;
00215 val[2] = 0.0;
00216 val[3] = 0.0;
00217
00218
00219
00220
00221 dcoord[0] = cv::Point(floor(coord.x), floor(coord.y));
00222
00223 if (img.type() == CV_8UC1) {
00224 val[0] = img.at<unsigned char>(dcoord[0].y, dcoord[0].x);
00225 } else if (img.type() == CV_64FC1) {
00226 val[0] = img.at<double>(dcoord[0].y, dcoord[0].x);
00227 }
00228
00229
00230 dist[0] = pow(pow(coord.x - ((float) dcoord[0].x), 2.0) + pow(coord.y - ((float) dcoord[0].y), 2.0), 0.5);
00231 total_dist += dist[0];
00232
00233
00234
00235 dcoord[1] = cv::Point(ceil(coord.x), floor(coord.y));
00236
00237 if (img.type() == CV_8UC1) {
00238 val[1] = img.at<unsigned char>(dcoord[1].y, dcoord[1].x);
00239 } else if (img.type() == CV_64FC1) {
00240 val[1] = img.at<double>(dcoord[1].y, dcoord[1].x);
00241 }
00242
00243
00244
00245
00246 dist[1] = pow(pow(coord.x - ((float) dcoord[1].x), 2.0) + pow(coord.y - ((float) dcoord[1].y), 2.0), 0.5);
00247 total_dist += dist[1];
00248
00249
00250
00251 dcoord[2] = cv::Point(ceil(coord.x), ceil(coord.y));
00252
00253 if (img.type() == CV_8UC1) {
00254 val[2] = img.at<unsigned char>(dcoord[2].y, dcoord[2].x);
00255 } else if (img.type() == CV_64FC1) {
00256 val[2] = img.at<double>(dcoord[2].y, dcoord[2].x);
00257 }
00258
00259
00260 dist[2] = pow(pow(coord.x - ((float) dcoord[2].x), 2.0) + pow(coord.y - ((float) dcoord[2].y), 2.0), 0.5);
00261 total_dist += dist[2];
00262
00263
00264
00265 dcoord[3] = cv::Point(floor(coord.x), ceil(coord.y));
00266
00267 if (img.type() == CV_8UC1) {
00268 val[3] = img.at<unsigned char>(dcoord[3].y, dcoord[3].x);
00269 } else if (img.type() == CV_64FC1) {
00270 val[3] = img.at<double>(dcoord[3].y, dcoord[3].x);
00271 }
00272
00273
00274 dist[3] = pow(pow(coord.x - ((float) dcoord[3].x), 2.0) + pow(coord.y - ((float) dcoord[3].y), 2.0), 0.5);
00275 total_dist += dist[3];
00276
00277
00278
00279
00280 cv::Point ref_coord = cv::Point(floor(coord.x), floor(coord.y));
00281
00282 if (total_dist == 0.0) {
00283 retVal = val[0];
00284
00285
00286 return retVal;
00287 }
00288
00289
00290
00291 cv::Mat x_mat(1, 2, CV_64FC1);
00292 x_mat.at<double>(0,0) = 1 - abs(coord.x - ((double) ref_coord.x));
00293 x_mat.at<double>(0,1) = abs(coord.x - ((double) ref_coord.x));
00294
00295 cv::Mat y_mat(2, 1, CV_64FC1);
00296 y_mat.at<double>(0,0) = 1 - abs(coord.y - ((double) ref_coord.y));
00297 y_mat.at<double>(1,0) = abs(coord.y - ((double) ref_coord.y));
00298
00299 cv::Mat f_vals(2, 2, CV_64FC1);
00300 f_vals.at<double>(0,0) = val[0];
00301 f_vals.at<double>(0,1) = val[3];
00302 f_vals.at<double>(1,0) = val[1];
00303 f_vals.at<double>(1,1) = val[2];
00304
00305
00306
00307 cv::Mat A = x_mat * f_vals * y_mat;
00308
00309 retVal = A.at<double>(0,0);
00310
00311 if (0) {
00312 cout << "x_mat = " << x_mat << endl;
00313 cout << "y_mat = " << y_mat << endl;
00314 cout << "f_vals = " << f_vals << endl;
00315 cout << "A = " << A << endl;
00316
00317 printf("%s << vals: (%f, %f, %f, %f) : dists: (%f, %f, %f, %f) : (%f, %f) vs (%d, %d) : (%f)\n", __FUNCTION__, val[0], val[1], val[2], val[3], dist[0], dist[1], dist[2], dist[3], coord.x, coord.y, ref_coord.x, ref_coord.y, retVal);
00318
00319 cin.get();
00320 }
00321
00322
00323
00324
00325
00326
00327
00328
00329 return retVal;
00330
00331
00332 }
00333
00334 void convertUcharToBinary(unsigned char val, int* binaryArray) {
00335 for (int iii = 0; iii < 8; iii++) {
00336 if ((int) val >= (int) pow(2, 7-iii)) {
00337 binaryArray[iii] = 1;
00338 val -= (int) pow(2, 7-iii);
00339 } else {
00340 binaryArray[iii] = 0;
00341 }
00342 }
00343 }
00344
00345 int countElementsInFolder(const char* folderName, vector<string>& elementNames, int elementType) {
00346 int elementCount = 0;
00347 DIR *dirp;
00348 struct dirent * entry;
00349
00350 int typeCode = 0;
00351
00352 if (elementType == 0) {
00353
00354 typeCode = DT_REG;
00355 } else if (elementType == 1) {
00356
00357 typeCode = DT_DIR;
00358 }
00359
00360 char *folder;
00361
00362 folder = (char*) malloc(strlen(folderName) + 32);
00363 sprintf(folder, "%s", folderName);
00364
00365
00366
00367 dirp = opendir(folder);
00368
00369
00370
00371 while ((entry = readdir(dirp)) != NULL) {
00372
00373 if ((entry->d_type == typeCode) && (entry->d_name[0] != '.')) {
00374
00375 elementNames.push_back(string(entry->d_name));
00376
00377
00378 printf("%s << elementName[%d] = %s\n", __FUNCTION__, elementCount, elementNames.at(elementCount).c_str());
00379
00380 elementCount++;
00381
00382 }
00383 }
00384
00385 closedir(dirp);
00386
00387 return elementCount;
00388
00389 }
00390
00391 void redistortPoints(const vector<cv::Point2f>& src, vector<cv::Point2f>& dst, const cv::Mat& cameraMatrix, const cv::Mat& distCoeffs, const cv::Mat& newCamMat) {
00392
00393 double fx, fy, ifx, ify, cx, cy;
00394 double fx0, fy0, ifx0, ify0, cx0, cy0;
00395 double k[8]={0,0,0,0,0,0,0,0};
00396 double r2, icdist, deltaX, deltaY;
00397 double x, y, x0, y0, x1, y1;
00398
00399 cv::Mat optimalMat(3, 3, CV_64FC1);
00400
00401
00402
00403
00404
00405
00406
00407 fx0 = cameraMatrix.at<double>(0, 0);
00408 fy0 = cameraMatrix.at<double>(1, 1);
00409 ifx0 = 1./fx0;
00410 ify0 = 1./fy0;
00411 cx0 = cameraMatrix.at<double>(0, 2);
00412 cy0 = cameraMatrix.at<double>(1, 2);
00413
00414 fx = newCamMat.at<double>(0, 0);
00415 fy = newCamMat.at<double>(1, 1);
00416 ifx = 1./fx;
00417 ify = 1./fy;
00418 cx = newCamMat.at<double>(0, 2);
00419 cy = newCamMat.at<double>(1, 2);
00420
00421 for (unsigned int i = 0; i < 8; i++){
00422 k[i] = distCoeffs.at<double>(0, i);
00423 }
00424
00425
00426
00427
00428
00429 dst.clear();
00430
00431 for (unsigned int i = 0; i < src.size(); i++) {
00432
00433 x = src.at(i).x;
00434 y = src.at(i).y;
00435
00436
00437
00438
00439 x0 = (x - cx)*ifx;
00440 y0 = (y - cy)*ify;
00441
00442 x = x0;
00443 y = y0;
00444
00445
00446 r2 = x*x + y*y;
00447 icdist = (1 + ((k[7]*r2 + k[6])*r2 + k[5])*r2)/(1 + ((k[4]*r2 + k[1])*r2 + k[0])*r2);
00448 deltaX = 2*k[2]*x*y + k[3]*(r2 + 2*x*x);
00449 deltaY = k[2]*(r2 + 2*y*y) + 2*k[3]*x*y;
00450
00451
00452
00453
00455
00456
00457
00459 x = (x0/icdist) + deltaX;
00460 y = (y0/icdist) + deltaY;
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474 x1 = x;
00475 y1 = y;
00476
00477
00478 x = (x1/ifx0) + cx0;
00479 y = (y1/ify0) + cy0;
00480
00481
00482
00483
00484
00485 dst.push_back(cv::Point2f(x, y));
00486 }
00487
00488
00489
00490 }
00491
00492 double timeElapsedMS(struct timeval& timer, bool reset) {
00493
00494 struct timeval new_time;
00495
00496 long seconds, useconds;
00497
00498 gettimeofday(&new_time, NULL);
00499
00500 seconds = new_time.tv_sec - timer.tv_sec;
00501 useconds = new_time.tv_usec - timer.tv_usec;
00502
00503 double retVal = ((double) seconds) * 1000.0 + ((double) useconds) * 0.001;
00504
00505 if (reset) {
00506 timer = new_time;
00507 }
00508
00509 return retVal;
00510
00511
00512 }
00513
00514 bool matricesAreEqual(cv::Mat& mat1, cv::Mat& mat2) {
00515
00516 if (mat1.rows != mat2.rows) {
00517 return false;
00518 }
00519
00520 if (mat1.cols != mat2.cols) {
00521 return false;
00522 }
00523
00524 if (mat1.type() != mat2.type()) {
00525 return false;
00526 }
00527
00528 if ((mat1.type() != CV_16UC1) && (mat1.type() != CV_16SC1) && (mat1.type() != CV_8UC1) && (mat1.type() != CV_8UC3) && (mat1.type() != CV_8SC1) && (mat1.type() != CV_16UC3) && (mat1.type() != CV_16SC3) && (mat1.type() != CV_64FC1) && (mat1.type() != CV_32FC1)) {
00529 printf("%s << ERROR! Equality check for this type (%d) has not been implemented!\n", __FUNCTION__, mat1.type());
00530 return false;
00531 }
00532
00533 bool isStillValid = true;
00534
00535 #pragma omp parallel for
00536 for (int iii = 0; iii < mat1.rows; iii++) {
00537 for (int jjj = 0; jjj < mat1.cols; jjj++) {
00538
00539 if (!isStillValid) {
00540 break;
00541 }
00542
00543 switch (mat1.type()) {
00544 case CV_64FC1:
00545
00546 if (mat1.at<double>(iii,jjj) != mat2.at<double>(iii,jjj)) {
00547
00548 isStillValid = false;
00549 }
00550 break;
00551 case CV_32FC1:
00552
00553 if (mat1.at<float>(iii,jjj) != mat2.at<float>(iii,jjj)) {
00554
00555 isStillValid = false;
00556 }
00557 break;
00558 case CV_16UC1:
00559
00560 if (mat1.at<unsigned short>(iii,jjj) != mat2.at<unsigned short>(iii,jjj)) {
00561
00562 isStillValid = false;
00563 }
00564 break;
00565 case CV_16SC1:
00566
00567 if (mat1.at<short>(iii,jjj) != mat2.at<short>(iii,jjj)) {
00568 isStillValid = false;
00569 }
00570 break;
00571 case CV_8UC1:
00572
00573 if (mat1.at<unsigned char>(iii,jjj) != mat2.at<unsigned char>(iii,jjj)) {
00574
00575 isStillValid = false;
00576 }
00577 break;
00578 case CV_8UC3:
00579
00580 if ((mat1.at<cv::Vec3b>(iii,jjj)[0] != mat2.at<cv::Vec3b>(iii,jjj)[0]) || (mat1.at<cv::Vec3b>(iii,jjj)[1] != mat2.at<cv::Vec3b>(iii,jjj)[1]) || (mat1.at<cv::Vec3b>(iii,jjj)[2] != mat2.at<cv::Vec3b>(iii,jjj)[2])) {
00581 isStillValid = false;
00582 }
00583 break;
00584 case CV_8SC1:
00585
00586 if (mat1.at<char>(iii,jjj) != mat2.at<char>(iii,jjj)) {
00587 isStillValid = false;
00588 }
00589 break;
00590 case CV_16UC3:
00591
00592 if ((mat1.at<cv::Vec3s>(iii,jjj)[0] != mat2.at<cv::Vec3s>(iii,jjj)[0]) || (mat1.at<cv::Vec3s>(iii,jjj)[1] != mat2.at<cv::Vec3s>(iii,jjj)[1]) || (mat1.at<cv::Vec3s>(iii,jjj)[2] != mat2.at<cv::Vec3s>(iii,jjj)[2])) {
00593 isStillValid = false;
00594 }
00595 break;
00596 case CV_16SC3:
00597
00598 if ((mat1.at<cv::Vec3s>(iii,jjj)[0] != mat2.at<cv::Vec3s>(iii,jjj)[0]) || (mat1.at<cv::Vec3s>(iii,jjj)[1] != mat2.at<cv::Vec3s>(iii,jjj)[1]) || (mat1.at<cv::Vec3s>(iii,jjj)[2] != mat2.at<cv::Vec3s>(iii,jjj)[2])) {
00599 isStillValid = false;
00600 }
00601 break;
00602 default:
00603 break;
00604 }
00605 }
00606 }
00607
00608 if (!isStillValid) {
00609 return false;
00610 }
00611 return true;
00612
00613 }
00614
00615 void randomSelection(vector<unsigned int>& src, vector<unsigned int>& dst, unsigned int max) {
00616
00617 dst.clear();
00618 dst.insert(dst.end(), src.begin(), src.end());
00619
00620 if (dst.size() <= max) {
00621 return;
00622 }
00623
00624 while (dst.size() > max) {
00625 dst.erase(dst.begin() + (rand() % dst.size()));
00626 }
00627
00628 }
00629
00630 double asymmetricGaussianValue(double score, double mean, double loVar, double hiVar) {
00631
00632 double zScore, sigma = 1.0, retVal;
00633
00634 if (score == mean) {
00635 return 1.00;
00636 } else if (score > mean+3*hiVar) {
00637 return 0.00;
00638 } else if (score < mean-3*loVar) {
00639 return 0.00;
00640 } else if (score > mean) {
00641 sigma = abs(hiVar - mean);
00642 } else if (score < mean) {
00643 sigma = abs(loVar - mean);
00644 }
00645
00646 zScore = (score - mean) / sigma;
00647 retVal = exp(-pow(zScore, 2.0)/2.0);
00648
00649 return retVal;
00650
00651 }
00652
00653 void addUniqueToVector(vector<unsigned int>& dst, vector<unsigned int>& src) {
00654
00655 for (unsigned int iii = 0; iii < src.size(); iii++) {
00656
00657 bool alreadyAdded = false;
00658
00659 for (unsigned int jjj = 0; jjj < dst.size(); jjj++) {
00660 if (dst.at(jjj) == src.at(iii)) {
00661 alreadyAdded = true;
00662 }
00663
00664
00665 }
00666
00667 if (!alreadyAdded) {
00668 dst.push_back(src.at(iii));
00669 }
00670
00671 }
00672
00673 }
00674
00675 double calcLinePerpDistance(double *line1, double *line2) {
00676 double retVal = 0.0;
00677
00678 retVal = abs(line2[2] - line1[2]) / sqrt(pow(line1[0], 2) + pow(line1[1], 2));
00679
00680 return retVal;
00681 }
00682
00683 cv::Scalar getRandomColour() {
00684 cv::Scalar color( rand()&255, rand()&255, rand()&255 );
00685
00686 return color;
00687 }
00688
00689 long long int factorial(int num)
00690 {
00691
00692 long long int result=1;
00693 for (int i=1; i<=num; ++i) {
00694
00695 result *= 1;
00696 }
00697 return result;
00698
00699 }
00700
00701 void getNextCombo(vector<unsigned int>& currentIndices, int r, int n) {
00702
00703
00704 bool valid = true;
00705
00706
00707
00708
00709 if (currentIndices.size() == 0)
00710 {
00711 for (int i = 0; i < r; i++)
00712 {
00713 currentIndices.push_back(i);
00714 }
00715 }
00716 else
00717 {
00718
00719
00720 int i = 0;
00721
00722 while (valid && (i < r))
00723 {
00724
00725
00726 if (currentIndices.at(currentIndices.size()-i-1) > (n-2-i))
00727 {
00728
00729 i++;
00730 }
00731 else
00732 {
00733 currentIndices.at(currentIndices.size()-i-1) = currentIndices.at(currentIndices.size()-i-1) + 1;
00734 for (int j = 0; j < i; j++)
00735 {
00736 currentIndices.at(currentIndices.size()-i+j) = currentIndices.at(currentIndices.size()-i+j-1) + 1;
00737 }
00738 valid = false;
00739 }
00740 }
00741
00742
00743 }
00744 }
00745
00746 void calcParameters(const vector<double>& v, double& mean, double& stdev) {
00747
00748 double sum = 0.0;
00749
00750 for (unsigned int iii = 0; iii < v.size(); iii++) {
00751 sum += v.at(iii);
00752 }
00753
00754 mean = sum / v.size();
00755
00756 double sq_sum = 0.0;
00757
00758 for (unsigned int iii = 0; iii < v.size(); iii++) {
00759 sq_sum += pow(v.at(iii)-mean,2.0);
00760 }
00761
00762 stdev = std::sqrt(sq_sum / v.size());
00763
00764 }
00765
00766 double findEquivalentProbabilityScore(double* values, int quantity, double prob)
00767 {
00768
00769
00770 vector<double> listVector;
00771 double min = 1.00;
00772 int minIndex;
00773
00774
00775 for (int j = 0; j < quantity; j++)
00776 {
00777 listVector.push_back(values[j]);
00778 }
00779
00780
00781 while (listVector.size() >= (unsigned int)(std::max(int(prob*quantity), 1)))
00782 {
00783
00784
00785 min = 9e99;
00786
00787 for (unsigned int j = 0; j < listVector.size(); j++)
00788 {
00789 if (listVector.at(j) < min)
00790 {
00791 min = listVector.at(j);
00792 minIndex = j;
00793 }
00794 }
00795
00796 listVector.erase(listVector.begin() + minIndex);
00797
00798 }
00799
00800 return min;
00801
00802 }
00803
00804 void convert_byte_to_binary_string(void* src, char* dst) {
00805
00806 uint8_t* num;
00807
00808 num = (uint8_t*) src;
00809
00810 unsigned int factor = 128;
00811
00812 for (unsigned int iii = 0; iii < 8; iii++) {
00813 if (*num > factor) {
00814 dst[iii] = '1';
00815 } else {
00816 dst[iii] = '0';
00817 }
00818 factor /= 2;
00819 }
00820 dst[8] = '\0';
00821 }