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
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);
00042 _detectedEdges.setTo(0);
00043
00044 int val = 0;
00045
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
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
00067 threshold(_detectedEdges,_detectedEdges,_thres,255,0);
00068
00069 }
00071
00072
00073 vector<Vec2f> featureDetection::houghTransform(){
00074
00075 Mat _detectedEdgesRGB;
00076 cvtColor(_detectedEdges,_detectedEdgesRGB, CV_GRAY2BGR);
00077 HoughLines(_detectedEdges,_lines,_rho,_theta,_houghThres);
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
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
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
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
00119
00120
00121 vector<Point2f> featureDetection::ransac(vector<Point2f> data){
00122
00123 vector<Point2f> res;
00124 int maxInliers = 0;
00125
00126
00127 for(int i = 0;i < data.size();i++){
00128 Point2f p1 = data[i];
00129
00130
00131 for(int j = i + 1;j < data.size();j++){
00132 Point2f p2 = data[j];
00133 int n = 0;
00134
00135
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
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);
00163 vector<Point> endPoints;
00164
00165
00166
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);
00204
00205 return imgRGB;
00206 }
00207
00208
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)
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
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;
00239
00240
00241 ippath += imname;
00242 Mat img1 = imread(ippath,0);
00243 resize(img1,img1,Size(detect._width,detect._height));
00244
00245 detect.filteringPipeLine(img1);
00246 vector<Vec2f> lines = detect.houghTransform();
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);
00258 resize(img2,img2,Size(detect._width,detect._height));
00259
00260 detect.filteringPipeLine(img2);
00261 vector<Vec2f> lines2 = detect.houghTransform();
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