00001 #include "NormalDetector.h"
00002
00003 #include <iostream>
00004
00005
00006 NormalDetector::NormalDetector(const PeakFinder* peak, unsigned int scales, double sigma, double step, unsigned int window, SmoothingFilterFamily filterType):
00007 MultiScaleDetector(peak, scales, sigma, step, filterType),
00008 m_windowSize(window)
00009 {
00010
00011 }
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 void NormalDetector::computeSignal(const LaserReading& reading, std::vector<double>& signal, std::vector<unsigned int>& maxRangeMapping) const{
00023
00024 std::vector<double> ranges;
00025 ranges.reserve(reading.getRho().size());
00026 maxRangeMapping.reserve(reading.getRho().size());
00027 for(unsigned int i = 0; i < reading.getRho().size(); i++){
00028 if(reading.getRho()[i] < reading.getMaxRange()){
00029 ranges.push_back(reading.getRho()[i]);
00030 maxRangeMapping.push_back(i);
00031 } else if (m_useMaxRange){
00032 ranges.push_back(reading.getMaxRange());
00033 maxRangeMapping.push_back(i);
00034 }
00035 }
00036
00037
00038 int offsetRange = floor((int)m_filterBank[0].size()/2.0);
00039 const std::vector<double>& rangeData = convolve1D(ranges, m_filterBank[0], -offsetRange);
00040 const std::vector<double>& phiData = reading.getPhi();
00041 std::vector<Point2D> points(rangeData.size());
00042
00043 for(unsigned int i = 0; i < rangeData.size(); i++){
00044 if(rangeData[i]<reading.getMaxRange()){
00045 points[i].x = cos(phiData[maxRangeMapping[i]])*rangeData[i];
00046 points[i].y = sin(phiData[maxRangeMapping[i]])*rangeData[i];
00047 } else {
00048 points[i].x = cos(phiData[maxRangeMapping[i]])*reading.getMaxRange();
00049 points[i].y = sin(phiData[maxRangeMapping[i]])*reading.getMaxRange();
00050 }
00051 }
00052
00053 signal.resize(points.size());
00054 unsigned int offset = floor((double)m_windowSize * 0.5);
00055 std::vector<Point2D>::const_iterator first = points.begin();
00056 std::vector<Point2D>::const_iterator last = first + m_windowSize;
00057 double oldangle = 0;
00058 for(unsigned int i = offset; i < signal.size() - offset; i++){
00059 LineParameters param = computeNormals(std::vector<Point2D>(first,last));
00060 signal[i] = normAngle(param.alpha, oldangle - M_PI);
00061 oldangle = signal[i];
00062 first++; last++;
00063 }
00064 for(unsigned int i = 0; i < offset; i++){
00065 signal[i] = signal[offset];
00066 }
00067 for(unsigned int i = signal.size() - offset; i < signal.size(); i++){
00068 signal[i] = signal[signal.size() - offset - 1];
00069 }
00070 }
00071
00072 unsigned int NormalDetector::computeInterestPoints(const LaserReading& reading, const std::vector<double>& signal, std::vector<InterestPoint*>& point,
00073 std::vector< std::vector<unsigned int> >& indexes, std::vector<unsigned int>& maxRangeMapping) const
00074 {
00075 point.clear();
00076 point.reserve(reading.getRho().size());
00077 const std::vector<Point2D>& worldPoints = reading.getWorldCartesian();
00078 for(unsigned int i = 0; i < indexes.size(); i++){
00079 for(unsigned int j = 0; j < indexes[i].size(); j++){
00080 OrientedPoint2D pose;
00081 unsigned int pointIndex = maxRangeMapping[indexes[i][j]];
00082
00083
00084 double rangeBefore = (pointIndex > 1)? reading.getRho()[pointIndex - 1] : reading.getMaxRange();
00085 double rangeAfter = (pointIndex < worldPoints.size() - 1)? reading.getRho()[pointIndex + 1] : reading.getMaxRange();
00086 double rangeCurrent = reading.getRho()[pointIndex];
00087 if(rangeBefore < rangeAfter){
00088 if(rangeBefore < rangeCurrent){
00089 pointIndex = pointIndex - 1;
00090 }
00091 } else if(rangeAfter < rangeCurrent){
00092 pointIndex = pointIndex + 1;
00093 }
00094
00095
00096 if(reading.getRho()[pointIndex] >= reading.getMaxRange()){
00097 continue;
00098 }
00099
00100 pose.x = (reading.getWorldCartesian()[pointIndex]).x;
00101 pose.y = (reading.getWorldCartesian()[pointIndex]).y;
00102 pose.theta = normAngle(signal[indexes[i][j]], -M_PI);
00103
00104 bool exists = false;
00105 for(unsigned int k = 0; !exists && k < point.size(); k++){
00106 exists = exists || (fabs(pose.x - point[k]->getPosition().x) <= 0.2 && fabs(pose.y - point[k]->getPosition().y) <= 0.2);
00107 }
00108 if(exists) continue;
00109
00110 unsigned int first = pointIndex - floor((int)m_filterBank[i].size()/2.0);
00111 unsigned int last = pointIndex + floor((int)m_filterBank[i].size()/2.0);
00112 std::vector<Point2D> support(reading.getWorldCartesian().begin() + first, reading.getWorldCartesian().begin() + last + 1);
00113 double maxDistance = -1e20;
00114 for(unsigned int k = 0; k < support.size(); k++){
00115 double distance = sqrt((pose.x - support[k].x)*(pose.x - support[k].x) + (pose.y - support[k].y)*(pose.y - support[k].y));
00116 maxDistance = maxDistance < distance ? distance : maxDistance;
00117 }
00118 InterestPoint *interest = new InterestPoint(pose, maxDistance);
00119
00120 interest->setSupport(support);
00121 interest->setScaleLevel(i);
00122 point.push_back(interest);
00123 }
00124 }
00125 return point.size();
00126 }
00127