featureDetection.cpp
Go to the documentation of this file.
00001 #include <iostream>
00002 #include <string.h>
00003 #include "kf_tracker/featureDetection.h"
00004 #include "kf_tracker/CKalmanFilter.h"
00005 
00006 using namespace cv;
00007 
00008 featureDetection::featureDetection(){
00009 
00010         _detectedEdges = Mat();
00011         _width = 800;
00012         _height = 600;
00013         _LMWidth = 10;
00014         _thres = 40;
00015         _rho = 1;
00016         _theta = CV_PI/180.0;
00017         _houghThres =100;
00018         _ransacThres = 0.01;
00019 }
00020 
00021 featureDetection::~featureDetection(){
00022 
00023 }
00024 
00026 
00027 // This is just one approach. Other approaches can be Edge detection, Connected Components, etc.
00028 void featureDetection::filteringPipeLine(Mat src){
00029         Mat img;
00030         
00032         Mat mask = Mat(src.size(), CV_8UC1, Scalar(1));
00033         for(int i = 0;i < mask.rows/2; i++){
00034                 for(int j = 0;j < mask.cols;j++){
00035                         mask.at<uchar>(Point(j,i)) = 0;
00036                 }
00037         }
00038         src.copyTo(img,mask);
00040         
00041         _detectedEdges = Mat(img.size(),CV_8UC1); // detectedEdges
00042         _detectedEdges.setTo(0);
00043 
00044         int val = 0;
00045         // iterating through each row
00046         for (int j = img.rows/2;j<img.rows;j++){
00047                 unsigned char *imgptr = img.ptr<uchar>(j);
00048                 unsigned char *detEdgesptr = _detectedEdges.ptr<uchar>(j);
00049 
00050                 // iterating through each column seeing the difference among columns which are "width" apart
00051                 for (int i = _LMWidth;i < img.cols - _LMWidth; ++i){
00052                         if(imgptr[i]!= 0){
00053                                 val = 2*imgptr[i];
00054                                 val += -imgptr[i - _LMWidth];
00055                                 val += -imgptr[i + _LMWidth];
00056                                 val += -abs((int)(imgptr[i - _LMWidth] - imgptr[i + _LMWidth]));
00057 
00058                                 val = (val<0)?0:val;
00059                                 val = (val>255)?255:val;
00060 
00061                                 detEdgesptr[i] = (unsigned char) val;
00062                         }
00063                 }
00064         }
00065 
00066         // Thresholding
00067         threshold(_detectedEdges,_detectedEdges,_thres,255,0);
00068 
00069 }
00071 
00072 // Performing Hough Transform
00073 vector<Vec2f> featureDetection::houghTransform(){
00074 
00075         Mat _detectedEdgesRGB;
00076         cvtColor(_detectedEdges,_detectedEdgesRGB, CV_GRAY2BGR); // converting to RGB
00077         HoughLines(_detectedEdges,_lines,_rho,_theta,_houghThres); // Finding the hough lines
00078         vector<Vec2f> retVar;
00079         
00080         if (_lines.size() > 1){
00081                 Mat labels,centers;
00082                 Mat samples = Mat(_lines.size(),2,CV_32F);
00083 
00084                 for (int i = 0;i < _lines.size();i++){
00085                         samples.at<float>(i,0) = _lines[i][0];
00086                         samples.at<float>(i,1) = _lines[i][1];
00087                 }
00088                 // K means clustering to get two lines
00089                 kmeans(samples, 2, labels, TermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, 1000, 0.001), 5, KMEANS_PP_CENTERS, centers );
00090 
00092                 _lines.clear();
00093                 
00094                 vector<Point2f> left;
00095                 vector<Point2f> right;
00096                 for(int i = 0;i < labels.rows; i++){
00097                         if (labels.at<int>(i) == 0) left.push_back(Point2f(samples.at<float>(i,0), samples.at<float>(i,1)));
00098                         else right.push_back(Point2f(samples.at<float>(i,0), samples.at<float>(i,1)));
00099                 }
00100                 // Performing Ransac
00101                 vector<Point2f> leftR = ransac(left); 
00102                 vector<Point2f> rightR = ransac(right);
00104 
00105                 if (leftR.size() < 1 || rightR.size() < 1 || 
00106                    (float)(cos((leftR[0].y + leftR[1].y)/2) * cos((rightR[0].y + rightR[1].y)/2)) >= 0) return retVar;
00107 
00108                 // pushing the end points of the line to _lines
00109                 _lines.push_back(Vec2f((leftR[0].x + leftR[1].x)/2, (leftR[0].y + leftR[1].y)/2));
00110                 _lines.push_back(Vec2f((rightR[0].x + rightR[1].x)/2, (rightR[0].y + rightR[1].y)/2));
00111 
00112         }
00113 
00114 
00115         return _lines;
00116 }
00117 
00118 // Implementing RANSAC to remove outlier lines
00119 // Picking the best estimate having maximum number of inliers
00120 // TO DO: Better implementation 
00121 vector<Point2f> featureDetection::ransac(vector<Point2f> data){
00122 
00123         vector<Point2f> res;
00124         int maxInliers = 0;
00125 
00126         // Picking up the first sample
00127         for(int i = 0;i < data.size();i++){
00128                 Point2f p1 = data[i];
00129         
00130                 // Picking up the second sample
00131                 for(int j = i + 1;j < data.size();j++){
00132                         Point2f p2 = data[j];
00133                         int n = 0;
00134                         
00135                         // Finding the total number of inliers
00136                         for (int k = 0;k < data.size();k++){
00137                                 Point2f p3 = data[k];
00138                                 float normalLength = norm(p2 - p1);
00139                                 float distance = abs((float)((p3.x - p1.x) * (p2.y - p1.y) - (p3.y - p1.y) * (p2.x - p1.x)) / normalLength);
00140                                 if (distance < _ransacThres) n++;
00141                         }
00142                         
00143                         // if the current selection has more inliers, update the result and maxInliers
00144                         if (n > maxInliers) {
00145                                 res.clear();
00146                                 maxInliers = n;                 
00147                                 res.push_back(p1);
00148                                 res.push_back(p2);
00149                         }
00150                 
00151                 }
00152                 
00153         }
00154 
00155         return res;
00156 }
00157 
00158 
00159 Mat featureDetection::lineItr(Mat img, vector<Vec2f> lines, string name){
00160 
00161         Mat imgRGB;
00162         cvtColor(img,imgRGB,CV_GRAY2RGB); // converting the image to RGB for display
00163         vector<Point> endPoints;
00164 
00165         // Here, I convert the polar coordinates to Cartesian coordinates.
00166         // Then, I extend the line to meet the boundary of the image.
00167         for (int i = 0;i < lines.size();i++){
00168                 float r = lines[i][0];
00169                 float t = lines[i][1];
00170                 
00171                 float x = r*cos(t);
00172                 float y = r*sin(t);
00173 
00174                 Point p1(cvRound(x - 1.0*sin(t)*1000), cvRound(y + cos(t)*1000));
00175                 Point p2(cvRound(x + 1.0*sin(t)*1000), cvRound(y - cos(t)*1000));
00176 
00177                 clipLine(img.size(),p1,p2);
00178                 if (p1.y > p2.y){
00179                         endPoints.push_back(p1);
00180                         endPoints.push_back(p2);
00181                 }
00182                 else{
00183                         endPoints.push_back(p2);
00184                         endPoints.push_back(p1);
00185                 }
00186 
00187         }
00188 
00189         
00190         Point pint;
00191         bool check = findIntersection(endPoints,pint);
00192 
00193         if (check){
00194                 line(imgRGB,endPoints[0],pint,Scalar(0,0,255),5);
00195                 line(imgRGB,endPoints[2],pint,Scalar(0,0,255),5);
00196         }       
00198 
00199         
00200         float xIntercept = min(endPoints[0].x,endPoints[2].x);
00201         myfile << name << "," << xIntercept * 2 << "," << pint.x * 2 << endl;
00202 
00203         visualize(imgRGB); // Visualize the final result
00204 
00205         return imgRGB;
00206 }
00207 
00208 // Finding the Vanishing Point
00209 bool featureDetection::findIntersection(vector<Point> endP, Point& pi){
00210 
00211         Point x = endP[2] - endP[0];
00212         Point d1 = endP[1] - endP[0];
00213         Point d2 = endP[3] - endP[2];
00214         
00215         float cross = d1.x*d2.y - d1.y*d2.x;
00216         if (abs(cross) < 1e-8) // No intersection
00217         return false;
00218 
00219     double t1 = (x.x * d2.y - x.y * d2.x)/cross;
00220     pi = endP[0] + d1 * t1;
00221     return true;
00222 
00223 
00224 }
00225 
00226 // Visualize
00227 void featureDetection::visualize(Mat imgRGB){
00228         
00229         namedWindow("detectedFeatures");
00230         imshow("detectedFeatures",imgRGB);
00231         waitKey(100);
00232 
00233 }
00234 
00235 #ifdef testT
00236 int main()
00237 {
00238         featureDetection detect; // object of featureDetection class
00239 
00240 
00241         ippath += imname;
00242         Mat img1 = imread(ippath,0); // Read the image
00243         resize(img1,img1,Size(detect._width,detect._height));
00244         
00245         detect.filteringPipeLine(img1); 
00246         vector<Vec2f> lines = detect.houghTransform(); // Hough Transform
00247         Mat imgFinal = detect.lineItr(img1, lines, imname); 
00248         
00249         oppath += imname;
00250         imwrite(oppath,imgFinal); 
00251 
00252         while ( getline (imageNames,imname) ){
00253                 ippath = "./images/";
00254                 oppath = "./output/";
00255                 ippath += imname;
00256 
00257                 Mat img2 = imread(ippath,0); // Read the image
00258                 resize(img2,img2,Size(detect._width,detect._height));
00259                 
00260                 detect.filteringPipeLine(img2); 
00261                 vector<Vec2f> lines2 = detect.houghTransform(); // Hough Transform
00262                 
00263                 
00264                 
00265                 if (lines2.size() < 2) {
00266                         imgFinal = detect.lineItr(img2,lines, imname);
00267                         oppath += imname;
00268                         imwrite(oppath,imgFinal); 
00269                         continue;
00270                 }
00271                 
00273                 CKalmanFilter KF2(lines);
00274                 vector<Vec2f> pp = KF2.predict();
00275 
00276                 vector<Vec2f> lines2Final = KF2.update(lines2);
00277                 lines = lines2Final;
00278                 imgFinal = detect.lineItr(img2,lines2, imname); 
00280                 
00281                 oppath += imname;
00282                 imwrite(oppath,imgFinal);
00283         }
00284         
00285 
00286 }
00287 #endif


multi_object_tracking_lidar
Author(s): Praveen Palanisamy
autogenerated on Thu Apr 18 2019 02:40:55