Commit f4c74eb5 authored by Maria Dimashova's avatar Maria Dimashova

changed the dot

parent d0a91f8f
...@@ -596,7 +596,7 @@ public: ...@@ -596,7 +596,7 @@ public:
void read( FileNode& fn ); void read( FileNode& fn );
void write( FileStorage& fs ) const; void write( FileStorage& fs ) const;
void asserts() const; void isConsistent() const;
Size winSize; Size winSize;
int regionSize; int regionSize;
...@@ -612,9 +612,9 @@ public: ...@@ -612,9 +612,9 @@ public:
{ {
DetectParams(); DetectParams();
DetectParams( float minRatio, int minRegionSize, int maxRegionSize, int regionSizeStep, DetectParams( float minRatio, int minRegionSize, int maxRegionSize, int regionSizeStep,
bool isGroup, int groupThreshold, double groupEps ); bool isGroup, int groupThreshold=3, double groupEps=0.2f );
void asserts( float minTrainRatio=1.f) const; void isConsistent( float minTrainRatio=1.f ) const;
float minRatio; float minRatio;
...@@ -623,17 +623,27 @@ public: ...@@ -623,17 +623,27 @@ public:
int regionSizeStep; int regionSizeStep;
bool isGroup; bool isGroup;
int groupThreshold; int groupThreshold;
double groupEps; double groupEps;
}; };
struct CV_EXPORTS DOTTemplate struct CV_EXPORTS DOTTemplate
{ {
struct CV_EXPORTS TrainData
{
TrainData();
TrainData( const Mat& maskedImage, const cv::Mat& strongestGradientsMask );
cv::Mat maskedImage;
cv::Mat strongestGradientsMask;
};
DOTTemplate(); DOTTemplate();
DOTTemplate( const cv::Mat& quantizedImage, int classID, DOTTemplate( const cv::Mat& quantizedImage, int objectClassID,
const cv::Mat& maskedImage=cv::Mat(), const cv::Mat& gradientMask=cv::Mat() ); const cv::Mat& maskedImage=cv::Mat(), const cv::Mat& strongestGradientsMask=cv::Mat() );
void addClassID( int classID, const cv::Mat& maskedImage=cv::Mat(), const cv::Mat& gradientMask=cv::Mat() );
void addObjectClassID( int objectClassID, const cv::Mat& maskedImage=cv::Mat(), const cv::Mat& strongestGradientsMask=cv::Mat() );
const TrainData* getTrainData( int objectClassID ) const;
static float computeTexturelessRatio( const cv::Mat& quantizedImage ); static float computeTexturelessRatio( const cv::Mat& quantizedImage );
...@@ -641,11 +651,9 @@ public: ...@@ -641,11 +651,9 @@ public:
void write( FileStorage& fs ) const; void write( FileStorage& fs ) const;
cv::Mat quantizedImage; cv::Mat quantizedImage;
std::vector<int> classIDs;
float texturelessRatio; float texturelessRatio;
std::vector<int> objectClassIDs;
std::vector<cv::Mat> maskedImages; std::vector<TrainData> trainData;
std::vector<cv::Mat> gradientMasks;
}; };
DOTDetector(); DOTDetector();
...@@ -661,22 +669,24 @@ public: ...@@ -661,22 +669,24 @@ public:
void save( const std::string& filename ) const; void save( const std::string& filename ) const;
void train( const string& baseDirName, const TrainParams& trainParams=TrainParams(), bool isAddImageAndGradientMask=false ); void train( const string& baseDirName, const TrainParams& trainParams=TrainParams(), bool isAddImageAndGradientMask=false );
void detectMultiScale( const Mat& image, vector<vector<Rect> >& rects, void detectMultiScale( const Mat& image, vector<vector<Rect> >& rects, const DetectParams& detectParams=DetectParams(),
const DetectParams& detectParams=DetectParams(), vector<vector<float> >* ratios=0, vector<vector<int> >* dotTemplateIndices=0 ) const;
vector<vector<float> >*ratios=0, vector<vector<int> >* trainTemplateIndices=0 ) const;
const vector<DOTTemplate>& getDOTTemplates() const; const vector<DOTTemplate>& getDOTTemplates() const;
const vector<string>& getClassNames() const; const vector<string>& getObjectClassNames() const;
static void groupRectanglesList( std::vector<std::vector<cv::Rect> >& rectList, int groupThreshold, double eps ); static void groupRectanglesList( std::vector<std::vector<cv::Rect> >& rectList, int groupThreshold, double eps );
protected: protected:
void detectQuantized( const Mat& queryQuantizedImage, float minRatio, void detectQuantized( const Mat& queryQuantizedImage, float minRatio,
vector<vector<Rect> >& rects, vector<vector<float> >& ratios, vector<vector<int> >& trainTemlateIdxs ) const; vector<vector<Rect> >& rects,
vector<vector<float> >& ratios,
vector<vector<int> >& dotTemplateIndices ) const;
TrainParams trainParams; TrainParams trainParams;
bool isAddImageAndGradientMask; //bool isAddImageAndGradientMask;
std::vector<std::string> classNames; std::vector<std::string> objectClassNames;
std::vector<DOTTemplate> dotTemplates; std::vector<DOTTemplate> dotTemplates;
}; };
......
...@@ -56,7 +56,7 @@ static void readDirContent( const string& descrFilename, vector<string>& names ) ...@@ -56,7 +56,7 @@ static void readDirContent( const string& descrFilename, vector<string>& names )
{ {
names.clear(); names.clear();
ifstream file( descrFilename.c_str() ); ifstream file( descrFilename.c_str(), ifstream::in );
if ( !file.is_open() ) if ( !file.is_open() )
return; return;
...@@ -233,7 +233,7 @@ static void quantizeToTrain( const Mat& _magnitudesExt, const Mat& _anglesExt, c ...@@ -233,7 +233,7 @@ static void quantizeToTrain( const Mat& _magnitudesExt, const Mat& _anglesExt, c
subMagnitudes.copyTo( subMagnitudesCopy ); subMagnitudes.copyTo( subMagnitudesCopy );
Mat subAngles( anglesExt, shiftedRect ); Mat subAngles( anglesExt, shiftedRect );
double maxMagnitude; double maxMagnitude = 0;
int strongestCount = 0; int strongestCount = 0;
for( ; strongestCount < params.maxStrongestCount; strongestCount++ ) for( ; strongestCount < params.maxStrongestCount; strongestCount++ )
{ {
...@@ -268,16 +268,17 @@ static void quantizeToTrain( const Mat& _magnitudesExt, const Mat& _anglesExt, c ...@@ -268,16 +268,17 @@ static void quantizeToTrain( const Mat& _magnitudesExt, const Mat& _anglesExt, c
} }
} }
static void quantizeToDetect( const Mat& _magnitudes, const Mat& angles, Mat& quantizedImage, const DOTDetector::TrainParams& params ) static void quantizeToDetect( const Mat& _magnitudes, const Mat& angles,
Mat& quantizedImage, int regionSize, const DOTDetector::TrainParams& params )
{ {
Mat magnitudes; _magnitudes.copyTo( magnitudes ); Mat magnitudes; _magnitudes.copyTo( magnitudes );
const int verticalRegionCount = magnitudes.rows / params.regionSize; const int verticalRegionCount = magnitudes.rows / regionSize;
const int horizontalRegionCount = magnitudes.cols / params.regionSize; const int horizontalRegionCount = magnitudes.cols / regionSize;
quantizedImage = Mat( verticalRegionCount, horizontalRegionCount, CV_8UC1, Scalar::all(0) ); quantizedImage = Mat( verticalRegionCount, horizontalRegionCount, CV_8UC1, Scalar::all(0) );
Rect curRect(0, 0, params.regionSize, params.regionSize); Rect curRect(0, 0, regionSize, regionSize);
const int maxStrongestCount = 1; const int maxStrongestCount = 1;
for( int vRegIdx = 0; vRegIdx < verticalRegionCount; vRegIdx++ ) for( int vRegIdx = 0; vRegIdx < verticalRegionCount; vRegIdx++ )
{ {
...@@ -311,10 +312,10 @@ static void quantizeToDetect( const Mat& _magnitudes, const Mat& angles, Mat& qu ...@@ -311,10 +312,10 @@ static void quantizeToDetect( const Mat& _magnitudes, const Mat& angles, Mat& qu
curRectBits |= 1 << DOTDetector::TrainParams::BIN_COUNT; curRectBits |= 1 << DOTDetector::TrainParams::BIN_COUNT;
quantizedImage.at<uchar>(vRegIdx, hRegIdx) = curRectBits; quantizedImage.at<uchar>(vRegIdx, hRegIdx) = curRectBits;
curRect.x += params.regionSize; curRect.x += regionSize;
} }
curRect.x = 0; curRect.x = 0;
curRect.y += params.regionSize; curRect.y += regionSize;
} }
} }
...@@ -327,7 +328,7 @@ inline void andQuantizedImages( const Mat& queryQuantizedImage, const Mat& train ...@@ -327,7 +328,7 @@ inline void andQuantizedImages( const Mat& queryQuantizedImage, const Mat& train
int area = cv::countNonZero( trainQuantizedImage ); int area = cv::countNonZero( trainQuantizedImage );
ratio = (float)nonZeroCount / area; ratio = (float)nonZeroCount / area;
texturelessRatio = texturelessCount / nonZeroCount; texturelessRatio = (float)texturelessCount / nonZeroCount;
} }
static void computeTrainUsedStrongestMask( const Mat& _magnitudesExt, const Mat& _anglesExt, const Mat& maskExt, const Mat& quantizedImage, static void computeTrainUsedStrongestMask( const Mat& _magnitudesExt, const Mat& _anglesExt, const Mat& maskExt, const Mat& quantizedImage,
...@@ -402,10 +403,10 @@ DOTDetector::TrainParams::TrainParams( const Size& _winSize, int _regionSize, in ...@@ -402,10 +403,10 @@ DOTDetector::TrainParams::TrainParams( const Size& _winSize, int _regionSize, in
maxStrongestCount(_maxStrongestCount), maxNonzeroBits(_maxNonzeroBits), maxStrongestCount(_maxStrongestCount), maxNonzeroBits(_maxNonzeroBits),
minRatio(_minRatio) minRatio(_minRatio)
{ {
asserts(); isConsistent();
} }
void DOTDetector::TrainParams::asserts() const void DOTDetector::TrainParams::isConsistent() const
{ {
CV_Assert( winSize.width > 0 && winSize.height > 0 ); CV_Assert( winSize.width > 0 && winSize.height > 0 );
CV_Assert( regionSize > 0 && regionSize % 2 == 1); CV_Assert( regionSize > 0 && regionSize % 2 == 1);
...@@ -433,7 +434,7 @@ void DOTDetector::TrainParams::read( FileNode& fn ) ...@@ -433,7 +434,7 @@ void DOTDetector::TrainParams::read( FileNode& fn )
minRatio = fn["minRatio"]; minRatio = fn["minRatio"];
asserts(); isConsistent();
} }
void DOTDetector::TrainParams::write( FileStorage& fs ) const void DOTDetector::TrainParams::write( FileStorage& fs ) const
...@@ -459,10 +460,10 @@ DOTDetector::DetectParams::DetectParams( float _minRatio, int _minRegionSize, in ...@@ -459,10 +460,10 @@ DOTDetector::DetectParams::DetectParams( float _minRatio, int _minRegionSize, in
minRatio(_minRatio), minRegionSize(_minRegionSize), maxRegionSize(_maxRegionSize), regionSizeStep(_regionSizeStep), minRatio(_minRatio), minRegionSize(_minRegionSize), maxRegionSize(_maxRegionSize), regionSizeStep(_regionSizeStep),
isGroup(_isGroup), groupThreshold(_groupThreshold), groupEps(_groupEps) isGroup(_isGroup), groupThreshold(_groupThreshold), groupEps(_groupEps)
{ {
asserts(); isConsistent();
} }
void DOTDetector::DetectParams::asserts( float minTrainRatio ) const void DOTDetector::DetectParams::isConsistent( float minTrainRatio ) const
{ {
CV_Assert( minRatio > 0 && minRatio < 1 ); CV_Assert( minRatio > 0 && minRatio < 1 );
CV_Assert( minRatio <= minTrainRatio ); CV_Assert( minRatio <= minTrainRatio );
...@@ -484,22 +485,30 @@ void DOTDetector::DetectParams::asserts( float minTrainRatio ) const ...@@ -484,22 +485,30 @@ void DOTDetector::DetectParams::asserts( float minTrainRatio ) const
* DOTDetector::DOTTemplate * DOTDetector::DOTTemplate
*/ */
DOTDetector::DOTTemplate::TrainData::TrainData()
{
}
DOTDetector::DOTTemplate::TrainData::TrainData( const Mat& _maskedImage, const cv::Mat& _strongestGradientsMask )
: maskedImage( _maskedImage ), strongestGradientsMask( _strongestGradientsMask )
{
}
DOTDetector::DOTTemplate::DOTTemplate() : texturelessRatio(-1.f) {} DOTDetector::DOTTemplate::DOTTemplate() : texturelessRatio(-1.f) {}
DOTDetector::DOTTemplate::DOTTemplate( const cv::Mat& _quantizedImage, int _classID, const cv::Mat& _maskedImage, const cv::Mat& _gradientMask ) : DOTDetector::DOTTemplate::DOTTemplate( const cv::Mat& _quantizedImage, int _objectClassID, const cv::Mat& _maskedImage, const cv::Mat& _strongestGradientsMask ) :
quantizedImage(_quantizedImage), texturelessRatio(computeTexturelessRatio(_quantizedImage)) quantizedImage(_quantizedImage), texturelessRatio(computeTexturelessRatio(_quantizedImage))
{ {
addClassID( _classID, _maskedImage, _gradientMask ); addObjectClassID( _objectClassID, _maskedImage, _strongestGradientsMask );
} }
void DOTDetector::DOTTemplate::addClassID( int _classID, const cv::Mat& _maskedImage, const cv::Mat& _gradientMask ) void DOTDetector::DOTTemplate::addObjectClassID( int _objectClassID, const cv::Mat& _maskedImage, const cv::Mat& _strongestGradientsMask )
{ {
CV_Assert( _classID >= 0 ); CV_Assert( _objectClassID >= 0 );
bool isFound = false; bool isFound = false;
for( size_t i = 0; i < classIDs.size(); i++ ) for( size_t i = 0; i < objectClassIDs.size(); i++ )
{ {
if( classIDs[i] == _classID ) if( objectClassIDs[i] == _objectClassID )
{ {
isFound = true; isFound = true;
break; break;
...@@ -508,16 +517,28 @@ void DOTDetector::DOTTemplate::addClassID( int _classID, const cv::Mat& _maskedI ...@@ -508,16 +517,28 @@ void DOTDetector::DOTTemplate::addClassID( int _classID, const cv::Mat& _maskedI
if( !isFound ) if( !isFound )
{ {
classIDs.push_back( _classID ); objectClassIDs.push_back( _objectClassID );
if( !_maskedImage.empty() ) if( !_maskedImage.empty() )
{ {
CV_Assert( !_gradientMask.empty() ); CV_Assert( !_strongestGradientsMask.empty() );
maskedImages.push_back( _maskedImage ); trainData.push_back( TrainData(_maskedImage, _strongestGradientsMask) );
gradientMasks.push_back( _gradientMask );
} }
} }
} }
const DOTDetector::DOTTemplate::TrainData* DOTDetector::DOTTemplate::getTrainData( int objectClassID ) const
{
if( objectClassID >= 0 )
{
for( size_t i = 0; i < objectClassIDs.size(); i++ )
{
if( objectClassID == objectClassIDs[i] )
return &trainData[i];
}
}
return 0;
}
float DOTDetector::DOTTemplate::computeTexturelessRatio( const cv::Mat& quantizedImage ) float DOTDetector::DOTTemplate::computeTexturelessRatio( const cv::Mat& quantizedImage )
{ {
const uchar TEXTURELESS_VAL = 1 << DOTDetector::TrainParams::BIN_COUNT; const uchar TEXTURELESS_VAL = 1 << DOTDetector::TrainParams::BIN_COUNT;
...@@ -536,14 +557,14 @@ float DOTDetector::DOTTemplate::computeTexturelessRatio( const cv::Mat& quantize ...@@ -536,14 +557,14 @@ float DOTDetector::DOTTemplate::computeTexturelessRatio( const cv::Mat& quantize
void DOTDetector::DOTTemplate::read( FileNode& fn ) void DOTDetector::DOTTemplate::read( FileNode& fn )
{ {
fn["template"] >> quantizedImage; fn["template"] >> quantizedImage;
fn["classIDs"] >> classIDs; fn["objectClassIDs"] >> objectClassIDs;
texturelessRatio = fn["texturelessRatio"]; texturelessRatio = fn["texturelessRatio"];
} }
void DOTDetector::DOTTemplate::write( FileStorage& fs ) const void DOTDetector::DOTTemplate::write( FileStorage& fs ) const
{ {
fs << "template" << quantizedImage; fs << "template" << quantizedImage;
fs << "classIDs" << classIDs; fs << "objectClassIDs" << objectClassIDs;
fs << "texturelessRatio" << texturelessRatio; fs << "texturelessRatio" << texturelessRatio;
} }
...@@ -551,11 +572,11 @@ void DOTDetector::DOTTemplate::write( FileStorage& fs ) const ...@@ -551,11 +572,11 @@ void DOTDetector::DOTTemplate::write( FileStorage& fs ) const
* DOTDetector * DOTDetector
*/ */
DOTDetector::DOTDetector() : isAddImageAndGradientMask( false ) DOTDetector::DOTDetector()
{ {
} }
DOTDetector::DOTDetector( const std::string& filename ) : isAddImageAndGradientMask( false ) DOTDetector::DOTDetector( const std::string& filename )
{ {
load( filename ); load( filename );
} }
...@@ -567,7 +588,7 @@ DOTDetector::~DOTDetector() ...@@ -567,7 +588,7 @@ DOTDetector::~DOTDetector()
void DOTDetector::clear() void DOTDetector::clear()
{ {
classNames.clear(); objectClassNames.clear();
dotTemplates.clear(); dotTemplates.clear();
} }
...@@ -586,7 +607,7 @@ void DOTDetector::read( FileNode& fn ) ...@@ -586,7 +607,7 @@ void DOTDetector::read( FileNode& fn )
{ {
string name; string name;
fni >> name; fni >> name;
classNames.push_back( name ); objectClassNames.push_back( name );
} }
// read DOT templates // read DOT templates
...@@ -608,11 +629,11 @@ void DOTDetector::write( FileStorage& fs ) const ...@@ -608,11 +629,11 @@ void DOTDetector::write( FileStorage& fs ) const
fs << "}"; //params fs << "}"; //params
// write class names // write class names
fs << "class_count" << (int)classNames.size(); fs << "class_count" << (int)objectClassNames.size();
fs << "class_names" << "["; fs << "class_names" << "[";
for( size_t i = 0; i < classNames.size(); i++ ) for( size_t i = 0; i < objectClassNames.size(); i++ )
{ {
fs << classNames[i]; fs << objectClassNames[i];
} }
fs << "]"; fs << "]";
...@@ -647,29 +668,31 @@ void DOTDetector::save( const std::string& filename ) const ...@@ -647,29 +668,31 @@ void DOTDetector::save( const std::string& filename ) const
} }
} }
void DOTDetector::train( const string& _baseDirName, const TrainParams& _trainParams, bool /*_isAddImageAndGradientMask*/ ) void DOTDetector::train( const string& _baseDirName, const TrainParams& _trainParams, bool isAddImageAndGradientMask )
{ {
clear(); clear();
trainParams = _trainParams; trainParams = _trainParams;
trainParams.asserts(); trainParams.isConsistent();
string baseDirName = _baseDirName + (*(_baseDirName.end()-1) == '/' ? "" : "/"); string baseDirName = _baseDirName + (*(_baseDirName.end()-1) == '/' ? "" : "/");
const int regionSize_2 = trainParams.regionSize / 2; const int regionSize_2 = trainParams.regionSize / 2;
readDirContent( baseDirName+"objects.txt", classNames ); vector<string> allObjectClassNames;
readDirContent( baseDirName + "objects.txt", allObjectClassNames );
for( size_t objIdx = 0; objIdx < classNames.size(); objIdx++ ) for( size_t objIdx = 0; objIdx < allObjectClassNames.size(); objIdx++ )
{ {
string curObjDirName = baseDirName + classNames[objIdx] + "/"; string curObjDirName = baseDirName + allObjectClassNames[objIdx] + "/";
cout << "===============" << classNames[objIdx] << "===============" << endl; cout << "===============" << allObjectClassNames[objIdx] << "===============" << endl;
vector<string> imagesFilenames; vector<string> imagesFilenames;
readDirContent( curObjDirName + "images.txt", imagesFilenames ); readDirContent( curObjDirName + "images.txt", imagesFilenames );
if( imagesFilenames.empty() ) if( imagesFilenames.empty() )
continue; continue;
objectClassNames.push_back( allObjectClassNames[objIdx] );
int countSamples = 0; int countSamples = 0;
for( size_t imgIdx = 0; imgIdx < imagesFilenames.size(); imgIdx++ ) for( size_t imgIdx = 0; imgIdx < imagesFilenames.size(); imgIdx++ )
{ {
...@@ -692,47 +715,62 @@ void DOTDetector::train( const string& _baseDirName, const TrainParams& _trainPa ...@@ -692,47 +715,62 @@ void DOTDetector::train( const string& _baseDirName, const TrainParams& _trainPa
countSamples++; countSamples++;
Mat trainImageExt, trainMaskExt, trainQuantizedImage, detectQuantizedImage; Mat trainImageExt, trainMaskExt, trainQuantizedImage, queryQuantizedImage;
Mat trainMagnitudesExt, trainAnglesExt; Mat trainMagnitudesExt, trainAnglesExt;
computeWinData( image, mask, trainParams.winSize, computeWinData( image, mask, trainParams.winSize,
trainImageExt, trainMaskExt, trainImageExt, trainMaskExt,
trainMagnitudesExt, trainAnglesExt, regionSize_2 ); trainMagnitudesExt, trainAnglesExt, regionSize_2 );
static int index_ = 0;
{
stringstream ss;
ss << "/files/Datasets/test_temp/" << index_ << ".png";
index_++;
imwrite( ss.str(), trainImageExt );
}
quantizeToTrain( trainMagnitudesExt, trainAnglesExt, trainMaskExt, trainQuantizedImage, trainParams ); quantizeToTrain( trainMagnitudesExt, trainAnglesExt, trainMaskExt, trainQuantizedImage, trainParams );
quantizeToDetect( trainMagnitudesExt, trainAnglesExt, detectQuantizedImage, trainParams ); quantizeToDetect( trainMagnitudesExt, trainAnglesExt, queryQuantizedImage,
trainParams.regionSize, trainParams );
vector<vector<Rect> > rects; vector<vector<Rect> > rects;
vector<vector<float> > ratios; vector<vector<float> > ratios;
vector<vector<int> > trainTemplatesIdxs; vector<vector<int> > dotTemplateIndices;
detectQuantized( detectQuantizedImage, trainParams.minRatio, rects, ratios, trainTemplatesIdxs );
detectQuantized( queryQuantizedImage, trainParams.minRatio, rects, ratios, dotTemplateIndices );
Mat maskedTrainImage, trainGradientMask; Mat trainMaskedImage, trainStrongestGradientMask;
if( isAddImageAndGradientMask ) if( isAddImageAndGradientMask )
{ {
trainImageExt.copyTo( maskedTrainImage, trainMaskExt); trainImageExt.copyTo( trainMaskedImage, trainMaskExt );
computeTrainUsedStrongestMask( trainMagnitudesExt, trainAnglesExt, trainMaskExt, trainQuantizedImage, computeTrainUsedStrongestMask( trainMagnitudesExt, trainAnglesExt, trainMaskExt, trainQuantizedImage,
trainGradientMask, trainParams.regionSize, trainParams.minMagnitude ); trainStrongestGradientMask, trainParams.regionSize, trainParams.minMagnitude );
} }
int classID = classNames.size()-1; int objectClassID = objectClassNames.size()-1;
bool isFound = false; bool isFound = false;
for( size_t cIdx = 0; cIdx < trainTemplatesIdxs.size(); cIdx++ ) for( size_t cIdx = 0; cIdx < dotTemplateIndices.size(); cIdx++ )
{ {
if( trainTemplatesIdxs[cIdx].size() ) if( dotTemplateIndices[cIdx].size() )
{ {
for( size_t i = 0; i < trainTemplatesIdxs[cIdx].size(); i++ ) for( size_t i = 0; i < dotTemplateIndices[cIdx].size(); i++ )
{ {
int tIdx = trainTemplatesIdxs[cIdx][i]; int tIdx = dotTemplateIndices[cIdx][i];
dotTemplates[tIdx].addClassID( classID, maskedTrainImage, trainGradientMask ); if( isAddImageAndGradientMask )
dotTemplates[tIdx].addObjectClassID( objectClassID, trainMaskedImage, trainStrongestGradientMask );
else
dotTemplates[tIdx].addObjectClassID( objectClassID );
isFound = true; isFound = true;
} }
} }
} }
if( !isFound ) if( !isFound )
{ {
dotTemplates.push_back( DOTTemplate(trainQuantizedImage, classID, maskedTrainImage, trainGradientMask) ); if( isAddImageAndGradientMask )
dotTemplates.push_back( DOTTemplate(trainQuantizedImage, objectClassID, trainMaskedImage, trainStrongestGradientMask) );
else
dotTemplates.push_back( DOTTemplate(trainQuantizedImage, objectClassID ) );
} }
cout << "dot templates size = " << dotTemplates.size() << endl; cout << "dot templates size = " << dotTemplates.size() << endl;
...@@ -740,8 +778,10 @@ void DOTDetector::train( const string& _baseDirName, const TrainParams& _trainPa ...@@ -740,8 +778,10 @@ void DOTDetector::train( const string& _baseDirName, const TrainParams& _trainPa
} }
} }
void DOTDetector::detectQuantized( const Mat& testQuantizedImage, float minRatio, void DOTDetector::detectQuantized( const Mat& queryQuantizedImage, float minRatio,
vector<vector<Rect> >& rects, vector<vector<float> >& ratios, vector<vector<int> >& trainTemlateIdxs ) const vector<vector<Rect> >& rects,
vector<vector<float> >& ratios,
vector<vector<int> >& dotTemplateIndices ) const
{ {
if( dotTemplates.empty() ) if( dotTemplates.empty() )
return; return;
...@@ -749,29 +789,29 @@ void DOTDetector::detectQuantized( const Mat& testQuantizedImage, float minRatio ...@@ -749,29 +789,29 @@ void DOTDetector::detectQuantized( const Mat& testQuantizedImage, float minRatio
const int regionsPerRow = dotTemplates[0].quantizedImage.rows; const int regionsPerRow = dotTemplates[0].quantizedImage.rows;
const int regionsPerCol = dotTemplates[0].quantizedImage.cols; const int regionsPerCol = dotTemplates[0].quantizedImage.cols;
int classCount = classNames.size(); int objectClassCount = objectClassNames.size();
rects.resize( classCount ); rects.resize( objectClassCount );
ratios.resize( classCount ); ratios.resize( objectClassCount );
trainTemlateIdxs.resize( classCount ); dotTemplateIndices.resize( objectClassCount );
for( size_t tIdx = 0; tIdx < dotTemplates.size(); tIdx++ ) for( size_t tIdx = 0; tIdx < dotTemplates.size(); tIdx++ )
{ {
Rect r( 0, 0, regionsPerCol, regionsPerRow ); Rect r( 0, 0, regionsPerCol, regionsPerRow );
for( r.y = 0; r.y <= testQuantizedImage.rows-r.height; r.y++ ) for( r.y = 0; r.y <= queryQuantizedImage.rows-r.height; r.y++ )
{ {
for( r.x = 0; r.x <= testQuantizedImage.cols-r.width; r.x++ ) for( r.x = 0; r.x <= queryQuantizedImage.cols-r.width; r.x++ )
{ {
float ratio, texturelessRatio; float ratio, texturelessRatio;
andQuantizedImages( testQuantizedImage(r), dotTemplates[tIdx].quantizedImage, ratio, texturelessRatio ); andQuantizedImages( queryQuantizedImage(r), dotTemplates[tIdx].quantizedImage, ratio, texturelessRatio );
if( ratio > minRatio && texturelessRatio < dotTemplates[tIdx].texturelessRatio ) if( ratio > minRatio && texturelessRatio < dotTemplates[tIdx].texturelessRatio )
{ {
for( size_t cIdx = 0; cIdx < dotTemplates[tIdx].classIDs.size(); cIdx++ ) for( size_t cIdx = 0; cIdx < dotTemplates[tIdx].objectClassIDs.size(); cIdx++ )
{ {
int classID = dotTemplates[tIdx].classIDs[cIdx]; int objectClassID = dotTemplates[tIdx].objectClassIDs[cIdx];
rects[classID].push_back( r ); rects[objectClassID].push_back( r );
ratios[classID].push_back( ratio ); ratios[objectClassID].push_back( ratio );
trainTemlateIdxs[classID].push_back( tIdx ); dotTemplateIndices[objectClassID].push_back( tIdx );
} }
} }
} }
...@@ -780,23 +820,23 @@ void DOTDetector::detectQuantized( const Mat& testQuantizedImage, float minRatio ...@@ -780,23 +820,23 @@ void DOTDetector::detectQuantized( const Mat& testQuantizedImage, float minRatio
} }
void DOTDetector::detectMultiScale( const Mat& image, vector<vector<Rect> >& rects, void DOTDetector::detectMultiScale( const Mat& image, vector<vector<Rect> >& rects,
const DetectParams& detectParams, vector<vector<float> >* ratios, vector<vector<int> >* trainTemplateIndices ) const const DetectParams& detectParams, vector<vector<float> >* ratios, vector<vector<int> >* dotTemplateIndices ) const
{ {
detectParams.asserts( trainParams.minRatio ); detectParams.isConsistent( trainParams.minRatio );
int classCount = classNames.size(); int objectClassCount = objectClassNames.size();
rects.resize( classCount ); rects.resize( objectClassCount );
if( ratios ) if( ratios )
{ {
ratios->clear(); ratios->clear();
if( !detectParams.isGroup ) if( !detectParams.isGroup )
ratios->resize( classCount ); ratios->resize( objectClassCount );
} }
if( trainTemplateIndices ) if( dotTemplateIndices )
{ {
trainTemplateIndices->clear(); dotTemplateIndices->clear();
if( !detectParams.isGroup ) if( !detectParams.isGroup )
trainTemplateIndices->resize( classCount ); dotTemplateIndices->resize( objectClassCount );
} }
Mat magnitudes, angles; Mat magnitudes, angles;
...@@ -806,11 +846,11 @@ void DOTDetector::detectMultiScale( const Mat& image, vector<vector<Rect> >& rec ...@@ -806,11 +846,11 @@ void DOTDetector::detectMultiScale( const Mat& image, vector<vector<Rect> >& rec
Mat quantizedImage; Mat quantizedImage;
vector<vector<Rect> > curRects; vector<vector<Rect> > curRects;
vector<vector<float> > curRatios; vector<vector<float> > curRatios;
vector<vector<int> > curTrainTemlateIdxs; vector<vector<int> > curDotTemlateIndices;
quantizeToDetect( magnitudes, angles, quantizedImage, trainParams ); quantizeToDetect( magnitudes, angles, quantizedImage, regionSize, trainParams );
detectQuantized( quantizedImage, detectParams.minRatio, curRects, curRatios, curTrainTemlateIdxs ); detectQuantized( quantizedImage, detectParams.minRatio, curRects, curRatios, curDotTemlateIndices );
for( int ci = 0; ci < classCount; ci++ ) for( int ci = 0; ci < objectClassCount; ci++ )
{ {
for( size_t ri = 0; ri < curRects[ci].size(); ri++ ) for( size_t ri = 0; ri < curRects[ci].size(); ri++ )
{ {
...@@ -823,8 +863,8 @@ void DOTDetector::detectMultiScale( const Mat& image, vector<vector<Rect> >& rec ...@@ -823,8 +863,8 @@ void DOTDetector::detectMultiScale( const Mat& image, vector<vector<Rect> >& rec
rects[ci].push_back( r ); rects[ci].push_back( r );
if( ratios && !detectParams.isGroup ) if( ratios && !detectParams.isGroup )
(*ratios)[ci].push_back( curRatios[ci][ri] ); (*ratios)[ci].push_back( curRatios[ci][ri] );
if( trainTemplateIndices && !detectParams.isGroup ) if( dotTemplateIndices && !detectParams.isGroup )
(*trainTemplateIndices)[ci].push_back( curTrainTemlateIdxs[ci][ri] ); (*dotTemplateIndices)[ci].push_back( curDotTemlateIndices[ci][ri] );
} }
} }
} }
...@@ -839,9 +879,9 @@ const vector<DOTDetector::DOTTemplate>& DOTDetector::getDOTTemplates() const ...@@ -839,9 +879,9 @@ const vector<DOTDetector::DOTTemplate>& DOTDetector::getDOTTemplates() const
return dotTemplates; return dotTemplates;
} }
const vector<string>& DOTDetector::getClassNames() const const vector<string>& DOTDetector::getObjectClassNames() const
{ {
return classNames; return objectClassNames;
} }
void DOTDetector::groupRectanglesList( std::vector<std::vector<cv::Rect> >& rectList, int groupThreshold, double eps ) void DOTDetector::groupRectanglesList( std::vector<std::vector<cv::Rect> >& rectList, int groupThreshold, double eps )
......
...@@ -7,7 +7,8 @@ ...@@ -7,7 +7,8 @@
using namespace cv; using namespace cv;
using namespace std; using namespace std;
#define SHOW_ALL_RECTS_BY_ONE 1 #define SHOW_ALL_RECTS_BY_ONE 0
static void fillColors( vector<Scalar>& colors ) static void fillColors( vector<Scalar>& colors )
{ {
cv::RNG rng = theRNG(); cv::RNG rng = theRNG();
...@@ -34,6 +35,8 @@ static void readTestImageNames( const string& descrFilename, vector<string>& nam ...@@ -34,6 +35,8 @@ static void readTestImageNames( const string& descrFilename, vector<string>& nam
file.close(); file.close();
} }
// find -name "image_*.png" | grep -v mask | sed 's/.\///' >> images.txt
int main( int argc, char **argv ) int main( int argc, char **argv )
{ {
if( argc != 1 && argc != 3 ) if( argc != 1 && argc != 3 )
...@@ -68,10 +71,10 @@ int main( int argc, char **argv ) ...@@ -68,10 +71,10 @@ int main( int argc, char **argv )
DOTDetector dotDetector; DOTDetector dotDetector;
dotDetector.train( baseDirName, trainParams, true ); dotDetector.train( baseDirName, trainParams, true );
const vector<string>& classNames = dotDetector.getClassNames(); const vector<string>& objectClassNames = dotDetector.getObjectClassNames();
const vector<DOTDetector::DOTTemplate>& dotTemplates = dotDetector.getDOTTemplates(); const vector<DOTDetector::DOTTemplate>& dotTemplates = dotDetector.getDOTTemplates();
vector<Scalar> colors( classNames.size() ); vector<Scalar> colors( objectClassNames.size() );
fillColors( colors ); fillColors( colors );
cout << "Templates count " << dotTemplates.size() << endl; cout << "Templates count " << dotTemplates.size() << endl;
...@@ -88,6 +91,7 @@ int main( int argc, char **argv ) ...@@ -88,6 +91,7 @@ int main( int argc, char **argv )
detectParams.minRatio = 0.8f; detectParams.minRatio = 0.8f;
detectParams.minRegionSize = 5; detectParams.minRegionSize = 5;
detectParams.maxRegionSize = 11; detectParams.maxRegionSize = 11;
#if SHOW_ALL_RECTS_BY_ONE #if SHOW_ALL_RECTS_BY_ONE
detectParams.isGroup = false; detectParams.isGroup = false;
#endif #endif
...@@ -102,26 +106,43 @@ int main( int argc, char **argv ) ...@@ -102,26 +106,43 @@ int main( int argc, char **argv )
continue; continue;
cout << "Detection start ..." << endl; cout << "Detection start ..." << endl;
vector<vector<Rect> > rects; vector<vector<Rect> > rects;
#if SHOW_ALL_RECTS_BY_ONE
vector<vector<float> > ratios; vector<vector<float> > ratios;
vector<vector<int> > trainTemlateIdxs; vector<vector<int> > dotTemlateIndices;
dotDetector.detectMultiScale( queryImage, rects, detectParams, &ratios, &trainTemlateIdxs ); dotDetector.detectMultiScale( queryImage, rects, detectParams, &ratios, &dotTemlateIndices );
const vector<DOTDetector::DOTTemplate>& dotTemplates = dotDetector.getDOTTemplates();
#else
dotDetector.detectMultiScale( queryImage, rects, detectParams );
#endif
cout << "end" << endl; cout << "end" << endl;
Mat draw; Mat draw;
cvtColor( queryImage, draw, CV_GRAY2BGR ); cvtColor( queryImage, draw, CV_GRAY2BGR );
#if SHOW_ALL_RECTS_BY_ONE
DOTDetector::groupRectanglesList( rects, 3, 0.2 );
#endif
const int textStep = 25; const int textStep = 25;
for( size_t ci = 0; ci < classNames.size(); ci++ ) for( size_t ci = 0; ci < objectClassNames.size(); ci++ )
{ {
putText( draw, classNames[ci], Point(textStep, textStep*(1+ci)), 1, 2, colors[ci], 3 ); putText( draw, objectClassNames[ci], Point(textStep, textStep*(1+ci)), 1, 2, colors[ci], 3 );
for( size_t ri = 0; ri < rects[ci].size(); ri++ ) for( size_t ri = 0; ri < rects[ci].size(); ri++ )
{ {
rectangle( draw, rects[ci][ri], colors[ci], 3 ); rectangle( draw, rects[ci][ri], colors[ci], 3 );
#if SHOW_ALL_RECTS_BY_ONE
int dotTemplateIndex = dotTemlateIndices[ci][ri];
const DOTDetector::DOTTemplate::TrainData* trainData = dotTemplates[dotTemplateIndex].getTrainData(ci);
imshow( "maskedImage", trainData->maskedImage );
imshow( "strongestGradientsMask", trainData->strongestGradientsMask );
Mat scaledDraw;
cv::resize( draw, scaledDraw, Size(640, 480) );
imshow( "detection result", scaledDraw );
cv::waitKey();
#endif
} }
} }
Mat scaledDraw; Mat scaledDraw;
...@@ -130,5 +151,4 @@ int main( int argc, char **argv ) ...@@ -130,5 +151,4 @@ int main( int argc, char **argv )
cv::waitKey(); cv::waitKey();
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment