Commit dae0dc9c authored by jaco's avatar jaco

BING Objectness porting progress

parent 6f1b6eb4
...@@ -74,7 +74,7 @@ class CV_EXPORTS_W Saliency : public virtual Algorithm ...@@ -74,7 +74,7 @@ class CV_EXPORTS_W Saliency : public virtual Algorithm
* \return true if the saliency map is computed, false otherwise * \return true if the saliency map is computed, false otherwise
*/ */
//bool computeSaliency( const Mat& image, Mat& saliencyMap ); //bool computeSaliency( const Mat& image, Mat& saliencyMap );
bool computeSaliency( const InputArray& image, OutputArray& saliencyMap ); bool computeSaliency( const InputArray image, OutputArray saliencyMap );
/** /**
* \brief Get the name of the specific saliency type * \brief Get the name of the specific saliency type
...@@ -84,7 +84,7 @@ class CV_EXPORTS_W Saliency : public virtual Algorithm ...@@ -84,7 +84,7 @@ class CV_EXPORTS_W Saliency : public virtual Algorithm
protected: protected:
//virtual bool computeSaliencyImpl( const Mat& image, Mat& saliencyMap ) = 0; //virtual bool computeSaliencyImpl( const Mat& image, Mat& saliencyMap ) = 0;
virtual bool computeSaliencyImpl( const InputArray& image, OutputArray& saliencyMap ) = 0; virtual bool computeSaliencyImpl( const InputArray image, OutputArray saliencyMap ) = 0;
String className; String className;
}; };
...@@ -96,7 +96,7 @@ class CV_EXPORTS_W StaticSaliency : public virtual Saliency ...@@ -96,7 +96,7 @@ class CV_EXPORTS_W StaticSaliency : public virtual Saliency
bool computeBinaryMap( const Mat& saliencyMap, Mat& binaryMap ); bool computeBinaryMap( const Mat& saliencyMap, Mat& binaryMap );
protected: protected:
virtual bool computeSaliencyImpl( const InputArray& image, OutputArray& saliencyMap ) = 0; virtual bool computeSaliencyImpl( const InputArray image, OutputArray saliencyMap ) = 0;
}; };
...@@ -106,7 +106,7 @@ class CV_EXPORTS_W MotionSaliency : public virtual Saliency ...@@ -106,7 +106,7 @@ class CV_EXPORTS_W MotionSaliency : public virtual Saliency
protected: protected:
virtual bool computeSaliencyImpl( const InputArray& image, OutputArray& saliencyMap ) = 0; virtual bool computeSaliencyImpl( const InputArray image, OutputArray saliencyMap ) = 0;
}; };
...@@ -116,7 +116,7 @@ class CV_EXPORTS_W Objectness : public virtual Saliency ...@@ -116,7 +116,7 @@ class CV_EXPORTS_W Objectness : public virtual Saliency
{ {
protected: protected:
virtual bool computeSaliencyImpl( const InputArray& image, OutputArray& saliencyMap ) = 0; virtual bool computeSaliencyImpl( const InputArray image, OutputArray saliencyMap ) = 0;
}; };
......
...@@ -90,7 +90,7 @@ class CV_EXPORTS_W StaticSaliencySpectralResidual : public StaticSaliency ...@@ -90,7 +90,7 @@ class CV_EXPORTS_W StaticSaliencySpectralResidual : public StaticSaliency
void write( FileStorage& fs ) const; void write( FileStorage& fs ) const;
protected: protected:
bool computeSaliencyImpl( const InputArray& src, OutputArray& dst ); bool computeSaliencyImpl( const InputArray src, OutputArray dst );
AlgorithmInfo* info() const; //{ return 0; } AlgorithmInfo* info() const; //{ return 0; }
CV_PROP_RW Ptr<Size> resizedImageSize; CV_PROP_RW Ptr<Size> resizedImageSize;
...@@ -124,7 +124,7 @@ class CV_EXPORTS_W MotionSaliencyPBAS : public MotionSaliency ...@@ -124,7 +124,7 @@ class CV_EXPORTS_W MotionSaliencyPBAS : public MotionSaliency
void write( FileStorage& fs ) const; void write( FileStorage& fs ) const;
protected: protected:
bool computeSaliencyImpl( const InputArray& src, OutputArray& dst ); bool computeSaliencyImpl( const InputArray src, OutputArray dst );
AlgorithmInfo* info() const; // { return 0; } AlgorithmInfo* info() const; // { return 0; }
private: private:
...@@ -154,7 +154,8 @@ class CV_EXPORTS_W ObjectnessBING : public Objectness ...@@ -154,7 +154,8 @@ class CV_EXPORTS_W ObjectnessBING : public Objectness
// The trained model should be prepared before calling this function: loadTrainedModel() or trainStageI() + trainStageII(). // The trained model should be prepared before calling this function: loadTrainedModel() or trainStageI() + trainStageII().
// Use numDet to control the final number of proposed bounding boxes, and number of per size (scale and aspect ratio) // Use numDet to control the final number of proposed bounding boxes, and number of per size (scale and aspect ratio)
void getObjBndBoxes(CMat &img3u, ValStructVec<float, Vec4i> &valBoxes, int numDetPerSize = 120); void getObjBndBoxes(CMat &img3u, ValStructVec<float, Vec4i> &valBoxes, int numDetPerSize = 120);
void getObjBndBoxesForImage(Mat img, ValStructVec<float, Vec4i> &boxes, int numDetPerSize); void getObjBndBoxesForSingleImage(Mat img, ValStructVec<float, Vec4i> &boxes, int numDetPerSize);
vector<float> getobjectnessValues();
void setColorSpace(int clr = MAXBGR); void setColorSpace(int clr = MAXBGR);
...@@ -167,18 +168,19 @@ class CV_EXPORTS_W ObjectnessBING : public Objectness ...@@ -167,18 +168,19 @@ class CV_EXPORTS_W ObjectnessBING : public Objectness
protected: protected:
bool computeSaliencyImpl( const InputArray& src, OutputArray& dst ); bool computeSaliencyImpl( const InputArray src, OutputArray dst );
AlgorithmInfo* info() const; //{ return 0; } AlgorithmInfo* info() const; //{ return 0; }
private: // Parameters private: // Parameters
const double _base, _logBase; // base for window size quantization double _base, _logBase; // base for window size quantization
const int _W; // As described in the paper: #Size, Size(_W, _H) of feature window. int _W; // As described in the paper: #Size, Size(_W, _H) of feature window.
const int _NSS; // Size for non-maximal suppress int _NSS; // Size for non-maximal suppress
const int _maxT, _minT, _numT; // The minimal and maximal dimensions of the template int _maxT, _minT, _numT; // The minimal and maximal dimensions of the template
int _Clr; // int _Clr; //
static const char* _clrName[3]; static const char* _clrName[3];
//TODO Probably remove this parameters
//DataSetVOC &_voc; // The dataset for training, testing //DataSetVOC &_voc; // The dataset for training, testing
std:: string _modelName, _trainDirSI, _bbResDir; std:: string _modelName, _trainDirSI, _bbResDir;
...@@ -187,6 +189,11 @@ class CV_EXPORTS_W ObjectnessBING : public Objectness ...@@ -187,6 +189,11 @@ class CV_EXPORTS_W ObjectnessBING : public Objectness
FilterTIG _tigF; // TIG filter FilterTIG _tigF; // TIG filter
Mat _svmReW1f; // Re-weight parameters learned at stage II. Mat _svmReW1f; // Re-weight parameters learned at stage II.
// List of the rectangles' objectness value, in the same order as
// vector<Vec4i> objectnessBoundingBox returned by the algorithm (in computeSaliencyImpl function)
vector<float> objectnessValues;
//vector<Vec4i> objectnessBoundingBox;
private: // Help functions private: // Help functions
bool filtersLoaded() {int n = _svmSzIdxs.size(); return n > 0 && _svmReW1f.size() == Size(2, n) && _svmFilter.size() == Size(_W, _W);} bool filtersLoaded() {int n = _svmSzIdxs.size(); return n > 0 && _svmReW1f.size() == Size(2, n) && _svmFilter.size() == Size(_W, _W);}
......
#include "kyheader.h"
#include "CmFile.h"
// Get image names from a wildcard. Eg: GetNames("D:\\*.jpg", imgNames);
int CmFile::GetNames(CStr &_nameW, vecS &_names, string _dir)
{
_dir = GetFolder(_nameW);
_names.clear();
DIR *dir;
struct dirent *ent;
if((dir = opendir(_dir.c_str()))!=NULL){
//print all the files and directories within directory
while((ent = readdir(dir))!=NULL){
if(ent->d_name[0] == '.')
continue;
if(ent->d_type ==4)
continue;
_names.push_back(ent->d_name);
}
closedir(dir);
} else {
perror("");
return EXIT_FAILURE;
}
return (int)_names.size();
}
int CmFile::GetSubFolders(CStr &folder, vecS &subFolders)
{
subFolders.clear();
string nameWC = GetFolder(folder);//folder + "/*";
DIR *dir;
struct dirent *ent;
if((dir = opendir(nameWC.c_str()))!=NULL){
while((ent = readdir(dir))!=NULL){
if(ent->d_name[0] == '.')
continue;
if(ent->d_type == 4){
subFolders.push_back(ent->d_name);
}
}
closedir(dir);
} else {
perror("");
return EXIT_FAILURE;
}
return (int)subFolders.size();
}
int CmFile::GetNames(CStr& rootFolder, CStr &fileW, vecS &names)
{
GetNames(rootFolder + fileW, names);
vecS subFolders, tmpNames;
int subNum = CmFile::GetSubFolders(rootFolder, subFolders);//
for (int i = 0; i < subNum; i++){
subFolders[i] += "/";
int subNum = GetNames(rootFolder + subFolders[i], fileW, tmpNames);
for (int j = 0; j < subNum; j++)
names.push_back(subFolders[i] + tmpNames[j]);
}
return (int)names.size();
}
int CmFile::GetNamesNE(CStr& nameWC, vecS &names, string dir, string ext)
{
int fNum = GetNames(nameWC, names, dir);
ext = GetExtention(nameWC);
for (int i = 0; i < fNum; i++)
names[i] = GetNameNE(names[i]);
return fNum;
}
int CmFile::GetNamesNE(CStr& rootFolder, CStr &fileW, vecS &names)
{
int fNum = GetNames(rootFolder, fileW, names);
int extS = GetExtention(fileW).size();
for (int i = 0; i < fNum; i++)
names[i].resize(names[i].size() - extS);
return fNum;
}
bool CmFile::MkDir(CStr &_path)
{
if(_path.size() == 0)
return false;
static char buffer[1024];
strcpy(buffer, _S(_path));
#ifdef _WIN32
for (int i = 0; buffer[i] != 0; i ++) {
if (buffer[i] == '\\' || buffer[i] == '/') {
buffer[i] = '\0';
CreateDirectoryA(buffer, 0);
buffer[i] = '/';
}
}
return CreateDirectoryA(_S(_path), 0);
#else
for (int i = 0; buffer[i] != 0; i ++) {
if (buffer[i] == '\\' || buffer[i] == '/') {
buffer[i] = '\0';
mkdir(buffer, 0);
buffer[i] = '/';
}
}
return mkdir(_S(_path), 0);
#endif
}
void CmFile::loadStrList(CStr &fName, vecS & strs, bool flag)
{
ifstream fIn(fName);
string line;
//vecS strs;
while(getline(fIn, line)){
unsigned sz = line.size();
if(flag)
line.resize(sz - 1);
printf("%s\n",_S(line));
strs.push_back(line);
}
//return strs;
}
bool CmFile::writeStrList(CStr &fName, const vecS &strs)
{
FILE *f = fopen(_S(fName), "w");
if (f == NULL)
return false;
for (size_t i = 0; i < strs.size(); i++)
fprintf(f, "%s\n", _S(strs[i]));
fclose(f);
return true;
}
#pragma once
#ifdef _WIN32
#include <windows.h>
#else
#include <iostream>
#include <stdlib.h>
#include <sys/stat.h>
#include <dirent.h>
#endif
struct CmFile
{
static inline string GetFolder(CStr& path);
static inline string GetName(CStr& path);
static inline string GetNameNE(CStr& path);
static inline string GetPathNE(CStr& path);
// Get file names from a wildcard. Eg: GetNames("D:\\*.jpg", imgNames);
static int GetNames(CStr &nameW, vecS &names, std::string _dir = std::string());
static int GetNames(CStr& rootFolder, CStr &fileW, vecS &names);
static int GetNamesNE(CStr& nameWC, vecS &names, string dir = string(), string ext = string());
static int GetNamesNE(CStr& rootFolder, CStr &fileW, vecS &names);
static inline string GetExtention(CStr name);
static int GetSubFolders(CStr& folder, vecS& subFolders);
static inline string GetWkDir();
static bool MkDir(CStr& path);
static void loadStrList(CStr &fName, vecS &strs, bool flag=false);
static bool writeStrList(CStr &fName, const vecS &strs);
};
/************************************************************************/
/* Implementation of inline functions */
/************************************************************************/
string CmFile::GetFolder(CStr& path)
{
return path.substr(0, path.find_last_of("\\/")+1);
}
string CmFile::GetName(CStr& path)
{
int start = path.find_last_of("\\/")+1;
int end = path.find_last_not_of(' ')+1;
return path.substr(start, end - start);
}
string CmFile::GetNameNE(CStr& path)
{
int start = path.find_last_of("\\/")+1;
int end = path.find_last_of('.');
if (end >= 0)
return path.substr(start, end - start);
else
return path.substr(start, path.find_last_not_of(' ')+1 - start);
}
string CmFile::GetPathNE(CStr& path)
{
int end = path.find_last_of('.');
if (end >= 0)
return path.substr(0, end);
else
return path.substr(0, path.find_last_not_of(' ') + 1);
}
string CmFile::GetExtention(CStr name)
{
return name.substr(name.find_last_of('.'));
}
/************************************************************************/
/* Implementations */
/************************************************************************/
...@@ -87,7 +87,7 @@ void MotionSaliencyPBAS::write( cv::FileStorage& fs ) const ...@@ -87,7 +87,7 @@ void MotionSaliencyPBAS::write( cv::FileStorage& fs ) const
//params.write( fs ); //params.write( fs );
} }
bool MotionSaliencyPBAS::computeSaliencyImpl( const InputArray& src, OutputArray& dst ) bool MotionSaliencyPBAS::computeSaliencyImpl( const InputArray src, OutputArray dst )
{ {
return true; return true;
......
...@@ -56,11 +56,11 @@ ObjectnessBING::ObjectnessBING() ...@@ -56,11 +56,11 @@ ObjectnessBING::ObjectnessBING()
_base = 2; // base for window size quantization _base = 2; // base for window size quantization
_W = 8; // feature window size (W, W) _W = 8; // feature window size (W, W)
_NSS = 2; //non-maximal suppress size NSS _NSS = 2; //non-maximal suppress size NSS
_logBase( log( _base ) ); _logBase=log( _base );
_minT( cvCeil( log( 10. ) / _logBase ) ); _minT=cvCeil( log( 10. ) / _logBase );
_maxT( cvCeil( log( 500. ) / _logBase ) ); _maxT=cvCeil( log( 500. ) / _logBase );
_numT( _maxT - _minT + 1 ); _numT= _maxT - _minT + 1 ;
_Clr( MAXBGR ); _Clr= MAXBGR ;
setColorSpace( _Clr ); setColorSpace( _Clr );
...@@ -72,411 +72,396 @@ ObjectnessBING::~ObjectnessBING() ...@@ -72,411 +72,396 @@ ObjectnessBING::~ObjectnessBING()
} }
void ObjectnessBING::setColorSpace(int clr) void ObjectnessBING::setColorSpace( int clr )
{ {
_Clr = clr; _Clr = clr;
// _modelName = _voc.resDir + string(format("ObjNessB%gW%d%s", _base, _W, _clrName[_Clr]).c_str()); _modelName = "/home/puja/src/opencv_contrib/modules/saliency/src/ObjectnessTrainedModel" + string(format("ObjNessB%gW%d%s", _base, _W, _clrName[_Clr]).c_str());
// _trainDirSI = _voc.localDir + string(format("TrainS1B%gW%d%s/", _base, _W, _clrName[_Clr]).c_str()); // _trainDirSI = _voc.localDir + string(format("TrainS1B%gW%d%s/", _base, _W, _clrName[_Clr]).c_str());
// _bbResDir = _voc.resDir + string(format("BBoxesB%gW%d%s/", _base, _W, _clrName[_Clr]).c_str()); // _bbResDir = _voc.resDir + string(format("BBoxesB%gW%d%s/", _base, _W, _clrName[_Clr]).c_str());
} }
int ObjectnessBING::loadTrainedModel(string modelName) // Return -1, 0, or 1 if partial, none, or all loaded int ObjectnessBING::loadTrainedModel( string modelName ) // Return -1, 0, or 1 if partial, none, or all loaded
{ {
if (modelName.size() == 0) if( modelName.size() == 0 )
modelName = _modelName; modelName = _modelName;
CStr s1 = modelName + ".wS1", s2 = modelName + ".wS2", sI = modelName + ".idx"; CStr s1 = modelName + ".wS1", s2 = modelName + ".wS2", sI = modelName + ".idx";
Mat filters1f, reW1f, idx1i, show3u; Mat filters1f, reW1f, idx1i, show3u;
if (!matRead(s1, filters1f) || !matRead(sI, idx1i)){ if( !matRead( s1, filters1f ) || !matRead( sI, idx1i ) )
printf("Can't load model: %s or %s\n", _S(s1), _S(sI)); {
return 0; printf( "Can't load model: %s or %s\n", _S( s1 ), _S( sI ) );
} return 0;
}
//filters1f = aFilter(0.8f, 8);
//normalize(filters1f, filters1f, p, 1, NORM_MINMAX); //filters1f = aFilter(0.8f, 8);
//normalize(filters1f, filters1f, p, 1, NORM_MINMAX);
normalize(filters1f, show3u, 1, 255, NORM_MINMAX, CV_8U);
_tigF.update(filters1f); normalize( filters1f, show3u, 1, 255, NORM_MINMAX, CV_8U );
//_tigF.reconstruct(filters1f); _tigF.update( filters1f );
//_tigF.reconstruct(filters1f);
_svmSzIdxs = idx1i;
CV_Assert(_svmSzIdxs.size() > 1 && filters1f.size() == Size(_W, _W) && filters1f.type() == CV_32F); _svmSzIdxs = idx1i;
_svmFilter = filters1f; CV_Assert( _svmSzIdxs.size() > 1 && filters1f.size() == Size(_W, _W) && filters1f.type() == CV_32F );
_svmFilter = filters1f;
if (!matRead(s2, _svmReW1f) || _svmReW1f.size() != Size(2, _svmSzIdxs.size())){
_svmReW1f = Mat(); if( !matRead( s2, _svmReW1f ) || _svmReW1f.size() != Size( 2, _svmSzIdxs.size() ) )
return -1; {
} _svmReW1f = Mat();
return 1; return -1;
}
return 1;
} }
void ObjectnessBING::predictBBoxSI(CMat &img3u, ValStructVec<float, Vec4i> &valBoxes, vecI &sz, int NUM_WIN_PSZ, bool fast) void ObjectnessBING::predictBBoxSI( CMat &img3u, ValStructVec<float, Vec4i> &valBoxes, vecI &sz, int NUM_WIN_PSZ, bool fast )
{ {
const int numSz = _svmSzIdxs.size(); const int numSz = _svmSzIdxs.size();
const int imgW = img3u.cols, imgH = img3u.rows; const int imgW = img3u.cols, imgH = img3u.rows;
valBoxes.reserve(10000); valBoxes.reserve( 10000 );
sz.clear(); sz.reserve(10000); sz.clear();
for (int ir = numSz - 1; ir >= 0; ir--){ sz.reserve( 10000 );
int r = _svmSzIdxs[ir]; for ( int ir = numSz - 1; ir >= 0; ir-- )
int height = cvRound(pow(_base, r/_numT + _minT)), width = cvRound(pow(_base, r%_numT + _minT)); {
if (height > imgH * _base || width > imgW * _base) int r = _svmSzIdxs[ir];
continue; int height = cvRound( pow( _base, r / _numT + _minT ) ), width = cvRound( pow( _base, r % _numT + _minT ) );
if( height > imgH * _base || width > imgW * _base )
height = min(height, imgH), width = min(width, imgW); continue;
Mat im3u, matchCost1f, mag1u;
resize(img3u, im3u, Size(cvRound(_W*imgW*1.0/width), cvRound(_W*imgH*1.0/height))); height = min( height, imgH ), width = min( width, imgW );
gradientMag(im3u, mag1u); Mat im3u, matchCost1f, mag1u;
resize( img3u, im3u, Size( cvRound( _W * imgW * 1.0 / width ), cvRound( _W * imgH * 1.0 / height ) ) );
//imwrite(_voc.localDir + format("%d.png", r), mag1u); gradientMag( im3u, mag1u );
//Mat mag1f;
//mag1u.convertTo(mag1f, CV_32F); //imwrite(_voc.localDir + format("%d.png", r), mag1u);
//matchTemplate(mag1f, _svmFilter, matchCost1f, CV_TM_CCORR); //Mat mag1f;
//mag1u.convertTo(mag1f, CV_32F);
matchCost1f = _tigF.matchTemplate(mag1u); //matchTemplate(mag1f, _svmFilter, matchCost1f, CV_TM_CCORR);
ValStructVec<float, Point> matchCost; matchCost1f = _tigF.matchTemplate( mag1u );
nonMaxSup(matchCost1f, matchCost, _NSS, NUM_WIN_PSZ, fast);
ValStructVec<float, Point> matchCost;
// Find true locations and match values nonMaxSup( matchCost1f, matchCost, _NSS, NUM_WIN_PSZ, fast );
double ratioX = width/_W, ratioY = height/_W;
int iMax = min(matchCost.size(), NUM_WIN_PSZ); // Find true locations and match values
for (int i = 0; i < iMax; i++){ double ratioX = width / _W, ratioY = height / _W;
float mVal = matchCost(i); int iMax = min( matchCost.size(), NUM_WIN_PSZ );
Point pnt = matchCost[i]; for ( int i = 0; i < iMax; i++ )
Vec4i box(cvRound(pnt.x * ratioX), cvRound(pnt.y*ratioY)); {
box[2] = cvRound(min(box[0] + width, imgW)); float mVal = matchCost( i );
box[3] = cvRound(min(box[1] + height, imgH)); Point pnt = matchCost[i];
box[0] ++; Vec4i box( cvRound( pnt.x * ratioX ), cvRound( pnt.y * ratioY ) );
box[1] ++; box[2] = cvRound( min( box[0] + width, imgW ) );
valBoxes.pushBack(mVal, box); box[3] = cvRound( min( box[1] + height, imgH ) );
sz.push_back(ir); box[0]++;
} box[1]++;
valBoxes.pushBack( mVal, box );
sz.push_back( ir );
} }
}
} }
void ObjectnessBING::predictBBoxSII(ValStructVec<float, Vec4i> &valBoxes, const vecI &sz) void ObjectnessBING::predictBBoxSII( ValStructVec<float, Vec4i> &valBoxes, const vecI &sz )
{ {
int numI = valBoxes.size(); int numI = valBoxes.size();
for (int i = 0; i < numI; i++){ for ( int i = 0; i < numI; i++ )
const float* svmIIw = _svmReW1f.ptr<float>(sz[i]); {
valBoxes(i) = valBoxes(i) * svmIIw[0] + svmIIw[1]; const float* svmIIw = _svmReW1f.ptr<float>( sz[i] );
} valBoxes( i ) = valBoxes( i ) * svmIIw[0] + svmIIw[1];
valBoxes.sort(); }
//valBoxes.sort();
// Ascending order. At the top there are the values with lower
// values of ​​objectness, ie more likely to have objects in the their corresponding rectangles.
valBoxes.sort( false );
} }
// Get potential bounding boxes, each of which is represented by a Vec4i for (minX, minY, maxX, maxY). // Get potential bounding boxes, each of which is represented by a Vec4i for (minX, minY, maxX, maxY).
// The trained model should be prepared before calling this function: loadTrainedModel() or trainStageI() + trainStageII(). // The trained model should be prepared before calling this function: loadTrainedModel() or trainStageI() + trainStageII().
// Use numDet to control the final number of proposed bounding boxes, and number of per size (scale and aspect ratio) // Use numDet to control the final number of proposed bounding boxes, and number of per size (scale and aspect ratio)
void ObjectnessBING::getObjBndBoxes(CMat &img3u, ValStructVec<float, Vec4i> &valBoxes, int numDetPerSize) void ObjectnessBING::getObjBndBoxes( CMat &img3u, ValStructVec<float, Vec4i> &valBoxes, int numDetPerSize )
{ {
//CV_Assert_(filtersLoaded() , ("SVM filters should be initialized before getting object proposals\n")); //CV_Assert_(filtersLoaded() , ("SVM filters should be initialized before getting object proposals\n"));
vecI sz; vecI sz;
predictBBoxSI(img3u, valBoxes, sz, numDetPerSize, false); predictBBoxSI( img3u, valBoxes, sz, numDetPerSize, false );
predictBBoxSII(valBoxes, sz); predictBBoxSII( valBoxes, sz );
return; return;
} }
void ObjectnessBING::nonMaxSup(CMat &matchCost1f, ValStructVec<float, Point> &matchCost, int NSS, int maxPoint, bool fast) void ObjectnessBING::nonMaxSup( CMat &matchCost1f, ValStructVec<float, Point> &matchCost, int NSS, int maxPoint, bool fast )
{ {
const int _h = matchCost1f.rows, _w = matchCost1f.cols; const int _h = matchCost1f.rows, _w = matchCost1f.cols;
Mat isMax1u = Mat::ones(_h, _w, CV_8U), costSmooth1f; Mat isMax1u = Mat::ones( _h, _w, CV_8U ), costSmooth1f;
ValStructVec<float, Point> valPnt; ValStructVec<float, Point> valPnt;
matchCost.reserve(_h * _w); matchCost.reserve( _h * _w );
valPnt.reserve(_h * _w); valPnt.reserve( _h * _w );
if (fast){ if( fast )
blur(matchCost1f, costSmooth1f, Size(3, 3)); {
for (int r = 0; r < _h; r++){ blur( matchCost1f, costSmooth1f, Size( 3, 3 ) );
const float* d = matchCost1f.ptr<float>(r); for ( int r = 0; r < _h; r++ )
const float* ds = costSmooth1f.ptr<float>(r); {
for (int c = 0; c < _w; c++) const float* d = matchCost1f.ptr<float>( r );
if (d[c] >= ds[c]) const float* ds = costSmooth1f.ptr<float>( r );
valPnt.pushBack(d[c], Point(c, r)); for ( int c = 0; c < _w; c++ )
} if( d[c] >= ds[c] )
valPnt.pushBack( d[c], Point( c, r ) );
} }
else{ }
for (int r = 0; r < _h; r++){ else
const float* d = matchCost1f.ptr<float>(r); {
for (int c = 0; c < _w; c++) for ( int r = 0; r < _h; r++ )
valPnt.pushBack(d[c], Point(c, r)); {
} const float* d = matchCost1f.ptr<float>( r );
for ( int c = 0; c < _w; c++ )
valPnt.pushBack( d[c], Point( c, r ) );
} }
}
valPnt.sort(); valPnt.sort();
for (int i = 0; i < valPnt.size(); i++){ for ( int i = 0; i < valPnt.size(); i++ )
Point &pnt = valPnt[i]; {
if (isMax1u.at<byte>(pnt)){ Point &pnt = valPnt[i];
matchCost.pushBack(valPnt(i), pnt); if( isMax1u.at<byte>( pnt ) )
for (int dy = -NSS; dy <= NSS; dy++) for (int dx = -NSS; dx <= NSS; dx++){ {
Point neighbor = pnt + Point(dx, dy); matchCost.pushBack( valPnt( i ), pnt );
if (!CHK_IND(neighbor)) for ( int dy = -NSS; dy <= NSS; dy++ )
continue; for ( int dx = -NSS; dx <= NSS; dx++ )
isMax1u.at<byte>(neighbor) = false; {
} Point neighbor = pnt + Point( dx, dy );
if( !CHK_IND( neighbor ) )
continue;
isMax1u.at<byte>( neighbor ) = false;
} }
if (matchCost.size() >= maxPoint)
return;
} }
if( matchCost.size() >= maxPoint )
return;
}
} }
void ObjectnessBING::gradientMag(CMat &imgBGR3u, Mat &mag1u) void ObjectnessBING::gradientMag( CMat &imgBGR3u, Mat &mag1u )
{ {
switch (_Clr){ switch ( _Clr )
{
case MAXBGR: case MAXBGR:
gradientRGB(imgBGR3u, mag1u); break; gradientRGB( imgBGR3u, mag1u );
break;
case G: case G:
gradientGray(imgBGR3u, mag1u); break; gradientGray( imgBGR3u, mag1u );
break;
case HSV: case HSV:
gradientHSV(imgBGR3u, mag1u); break; gradientHSV( imgBGR3u, mag1u );
break;
default: default:
printf("Error: not recognized color space\n"); printf( "Error: not recognized color space\n" );
} }
} }
void ObjectnessBING::gradientRGB(CMat &bgr3u, Mat &mag1u) void ObjectnessBING::gradientRGB( CMat &bgr3u, Mat &mag1u )
{ {
const int H = bgr3u.rows, W = bgr3u.cols; const int H = bgr3u.rows, W = bgr3u.cols;
Mat Ix(H, W, CV_32S), Iy(H, W, CV_32S); Mat Ix( H, W, CV_32S ), Iy( H, W, CV_32S );
// Left/right most column Ix // Left/right most column Ix
for (int y = 0; y < H; y++){ for ( int y = 0; y < H; y++ )
Ix.at<int>(y, 0) = bgrMaxDist(bgr3u.at<Vec3b>(y, 1), bgr3u.at<Vec3b>(y, 0))*2; {
Ix.at<int>(y, W-1) = bgrMaxDist(bgr3u.at<Vec3b>(y, W-1), bgr3u.at<Vec3b>(y, W-2))*2; Ix.at<int>( y, 0 ) = bgrMaxDist( bgr3u.at<Vec3b>( y, 1 ), bgr3u.at<Vec3b>( y, 0 ) ) * 2;
} Ix.at<int>( y, W - 1 ) = bgrMaxDist( bgr3u.at<Vec3b>( y, W - 1 ), bgr3u.at<Vec3b>( y, W - 2 ) ) * 2;
}
// Top/bottom most column Iy
for (int x = 0; x < W; x++) { // Top/bottom most column Iy
Iy.at<int>(0, x) = bgrMaxDist(bgr3u.at<Vec3b>(1, x), bgr3u.at<Vec3b>(0, x))*2; for ( int x = 0; x < W; x++ )
Iy.at<int>(H-1, x) = bgrMaxDist(bgr3u.at<Vec3b>(H-1, x), bgr3u.at<Vec3b>(H-2, x))*2; {
} Iy.at<int>( 0, x ) = bgrMaxDist( bgr3u.at<Vec3b>( 1, x ), bgr3u.at<Vec3b>( 0, x ) ) * 2;
Iy.at<int>( H - 1, x ) = bgrMaxDist( bgr3u.at<Vec3b>( H - 1, x ), bgr3u.at<Vec3b>( H - 2, x ) ) * 2;
// Find the gradient for inner regions }
for (int y = 0; y < H; y++){
const Vec3b *dataP = bgr3u.ptr<Vec3b>(y); // Find the gradient for inner regions
for (int x = 2; x < W; x++) for ( int y = 0; y < H; y++ )
Ix.at<int>(y, x-1) = bgrMaxDist(dataP[x-2], dataP[x]); // bgr3u.at<Vec3b>(y, x+1), bgr3u.at<Vec3b>(y, x-1)); {
} const Vec3b *dataP = bgr3u.ptr<Vec3b>( y );
for (int y = 1; y < H-1; y++){ for ( int x = 2; x < W; x++ )
const Vec3b *tP = bgr3u.ptr<Vec3b>(y-1); Ix.at<int>( y, x - 1 ) = bgrMaxDist( dataP[x - 2], dataP[x] ); // bgr3u.at<Vec3b>(y, x+1), bgr3u.at<Vec3b>(y, x-1));
const Vec3b *bP = bgr3u.ptr<Vec3b>(y+1); }
for (int x = 0; x < W; x++) for ( int y = 1; y < H - 1; y++ )
Iy.at<int>(y, x) = bgrMaxDist(tP[x], bP[x]); {
} const Vec3b *tP = bgr3u.ptr<Vec3b>( y - 1 );
gradientXY(Ix, Iy, mag1u); const Vec3b *bP = bgr3u.ptr<Vec3b>( y + 1 );
for ( int x = 0; x < W; x++ )
Iy.at<int>( y, x ) = bgrMaxDist( tP[x], bP[x] );
}
gradientXY( Ix, Iy, mag1u );
} }
void ObjectnessBING::gradientGray(CMat &bgr3u, Mat &mag1u) void ObjectnessBING::gradientGray( CMat &bgr3u, Mat &mag1u )
{ {
Mat g1u; Mat g1u;
cvtColor(bgr3u, g1u, COLOR_BGR2GRAY); cvtColor( bgr3u, g1u, COLOR_BGR2GRAY );
const int H = g1u.rows, W = g1u.cols; const int H = g1u.rows, W = g1u.cols;
Mat Ix(H, W, CV_32S), Iy(H, W, CV_32S); Mat Ix( H, W, CV_32S ), Iy( H, W, CV_32S );
// Left/right most column Ix // Left/right most column Ix
for (int y = 0; y < H; y++){ for ( int y = 0; y < H; y++ )
Ix.at<int>(y, 0) = abs(g1u.at<byte>(y, 1) - g1u.at<byte>(y, 0)) * 2; {
Ix.at<int>(y, W-1) = abs(g1u.at<byte>(y, W-1) - g1u.at<byte>(y, W-2)) * 2; Ix.at<int>( y, 0 ) = abs( g1u.at<byte>( y, 1 ) - g1u.at<byte>( y, 0 ) ) * 2;
} Ix.at<int>( y, W - 1 ) = abs( g1u.at<byte>( y, W - 1 ) - g1u.at<byte>( y, W - 2 ) ) * 2;
}
// Top/bottom most column Iy
for (int x = 0; x < W; x++) { // Top/bottom most column Iy
Iy.at<int>(0, x) = abs(g1u.at<byte>(1, x) - g1u.at<byte>(0, x)) * 2; for ( int x = 0; x < W; x++ )
Iy.at<int>(H-1, x) = abs(g1u.at<byte>(H-1, x) - g1u.at<byte>(H-2, x)) * 2; {
} Iy.at<int>( 0, x ) = abs( g1u.at<byte>( 1, x ) - g1u.at<byte>( 0, x ) ) * 2;
Iy.at<int>( H - 1, x ) = abs( g1u.at<byte>( H - 1, x ) - g1u.at<byte>( H - 2, x ) ) * 2;
// Find the gradient for inner regions }
for (int y = 0; y < H; y++)
for (int x = 1; x < W-1; x++) // Find the gradient for inner regions
Ix.at<int>(y, x) = abs(g1u.at<byte>(y, x+1) - g1u.at<byte>(y, x-1)); for ( int y = 0; y < H; y++ )
for (int y = 1; y < H-1; y++) for ( int x = 1; x < W - 1; x++ )
for (int x = 0; x < W; x++) Ix.at<int>( y, x ) = abs( g1u.at<byte>( y, x + 1 ) - g1u.at<byte>( y, x - 1 ) );
Iy.at<int>(y, x) = abs(g1u.at<byte>(y+1, x) - g1u.at<byte>(y-1, x)); for ( int y = 1; y < H - 1; y++ )
for ( int x = 0; x < W; x++ )
gradientXY(Ix, Iy, mag1u); Iy.at<int>( y, x ) = abs( g1u.at<byte>( y + 1, x ) - g1u.at<byte>( y - 1, x ) );
gradientXY( Ix, Iy, mag1u );
} }
void ObjectnessBING::gradientHSV( CMat &bgr3u, Mat &mag1u )
void ObjectnessBING::gradientHSV(CMat &bgr3u, Mat &mag1u)
{ {
Mat hsv3u; Mat hsv3u;
cvtColor(bgr3u, hsv3u, COLOR_BGR2HSV); cvtColor( bgr3u, hsv3u, COLOR_BGR2HSV );
const int H = hsv3u.rows, W = hsv3u.cols; const int H = hsv3u.rows, W = hsv3u.cols;
Mat Ix(H, W, CV_32S), Iy(H, W, CV_32S); Mat Ix( H, W, CV_32S ), Iy( H, W, CV_32S );
// Left/right most column Ix // Left/right most column Ix
for (int y = 0; y < H; y++){ for ( int y = 0; y < H; y++ )
Ix.at<int>(y, 0) = vecDist3b(hsv3u.at<Vec3b>(y, 1), hsv3u.at<Vec3b>(y, 0)); {
Ix.at<int>(y, W-1) = vecDist3b(hsv3u.at<Vec3b>(y, W-1), hsv3u.at<Vec3b>(y, W-2)); Ix.at<int>( y, 0 ) = vecDist3b( hsv3u.at<Vec3b>( y, 1 ), hsv3u.at<Vec3b>( y, 0 ) );
} Ix.at<int>( y, W - 1 ) = vecDist3b( hsv3u.at<Vec3b>( y, W - 1 ), hsv3u.at<Vec3b>( y, W - 2 ) );
}
// Top/bottom most column Iy
for (int x = 0; x < W; x++) { // Top/bottom most column Iy
Iy.at<int>(0, x) = vecDist3b(hsv3u.at<Vec3b>(1, x), hsv3u.at<Vec3b>(0, x)); for ( int x = 0; x < W; x++ )
Iy.at<int>(H-1, x) = vecDist3b(hsv3u.at<Vec3b>(H-1, x), hsv3u.at<Vec3b>(H-2, x)); {
} Iy.at<int>( 0, x ) = vecDist3b( hsv3u.at<Vec3b>( 1, x ), hsv3u.at<Vec3b>( 0, x ) );
Iy.at<int>( H - 1, x ) = vecDist3b( hsv3u.at<Vec3b>( H - 1, x ), hsv3u.at<Vec3b>( H - 2, x ) );
// Find the gradient for inner regions }
for (int y = 0; y < H; y++)
for (int x = 1; x < W-1; x++) // Find the gradient for inner regions
Ix.at<int>(y, x) = vecDist3b(hsv3u.at<Vec3b>(y, x+1), hsv3u.at<Vec3b>(y, x-1))/2; for ( int y = 0; y < H; y++ )
for (int y = 1; y < H-1; y++) for ( int x = 1; x < W - 1; x++ )
for (int x = 0; x < W; x++) Ix.at<int>( y, x ) = vecDist3b( hsv3u.at<Vec3b>( y, x + 1 ), hsv3u.at<Vec3b>( y, x - 1 ) ) / 2;
Iy.at<int>(y, x) = vecDist3b(hsv3u.at<Vec3b>(y+1, x), hsv3u.at<Vec3b>(y-1, x))/2; for ( int y = 1; y < H - 1; y++ )
for ( int x = 0; x < W; x++ )
gradientXY(Ix, Iy, mag1u); Iy.at<int>( y, x ) = vecDist3b( hsv3u.at<Vec3b>( y + 1, x ), hsv3u.at<Vec3b>( y - 1, x ) ) / 2;
gradientXY( Ix, Iy, mag1u );
} }
void ObjectnessBING::gradientXY(CMat &x1i, CMat &y1i, Mat &mag1u) void ObjectnessBING::gradientXY( CMat &x1i, CMat &y1i, Mat &mag1u )
{ {
const int H = x1i.rows, W = x1i.cols; const int H = x1i.rows, W = x1i.cols;
mag1u.create(H, W, CV_8U); mag1u.create( H, W, CV_8U );
for (int r = 0; r < H; r++){ for ( int r = 0; r < H; r++ )
const int *x = x1i.ptr<int>(r), *y = y1i.ptr<int>(r); {
byte* m = mag1u.ptr<byte>(r); const int *x = x1i.ptr<int>( r ), *y = y1i.ptr<int>( r );
for (int c = 0; c < W; c++) byte* m = mag1u.ptr<byte>( r );
m[c] = min(x[c] + y[c], 255); //((int)sqrt(sqr(x[c]) + sqr(y[c])), 255); for ( int c = 0; c < W; c++ )
} m[c] = min( x[c] + y[c], 255 ); //((int)sqrt(sqr(x[c]) + sqr(y[c])), 255);
}
} }
void ObjectnessBING::getObjBndBoxesForImage(Mat img, ValStructVec<float, Vec4i> &finalBoxes, int numDetPerSize) void ObjectnessBING::getObjBndBoxesForSingleImage( Mat img, ValStructVec<float, Vec4i> &finalBoxes, int numDetPerSize )
{ {
const int TestNum = 1;
vecM imgs3u(TestNum);
vector<ValStructVec<float, Vec4i>> boxesTests;
boxesTests.resize(TestNum);
#pragma omp parallel for int scales[3] =
for (int i = 0; i < TestNum; i++){ { 1, 3, 5 };
imgs3u[i] = img; for ( int clr = MAXBGR; clr <= G; clr++ )
boxesTests[i].reserve(10000); {
} setColorSpace( clr );
loadTrainedModel();
int scales[3] = {1, 3, 5}; CmTimer tm( "Predict" );
for (int clr = MAXBGR; clr <= G; clr++){ tm.Start();
setColorSpace(clr);
loadTrainedModel();
CmTimer tm("Predict");
//tm.Start();
#pragma omp parallel for
for (int i = 0; i < TestNum; i++){
ValStructVec<float, Vec4i> boxes;
getObjBndBoxes(imgs3u[i], boxes, numDetPerSize);
boxesTests[i].append(boxes, scales[clr]);
//boxes.valIdxes[0].first;
}
//tm.Stop();
//printf("Average time for predicting an image (%s) is %gs\n", _clrName[_Clr], tm.TimeInSeconds()/TestNum);
}
/* _boxesTests.resize(TestNum); getObjBndBoxes( img, finalBoxes, numDetPerSize );
CmFile::MkDir(_bbResDir);
#pragma omp parallel for
for (int i = 0; i < TestNum; i++){
CStr fName = _bbResDir + _voc.testSet[i];
ValStructVec<float, Vec4i> &boxes = boxesTests[i];
FILE *f = fopen(_S(fName + ".txt"), "w");
fprintf(f, "%d\n", boxes.size());
for (size_t k = 0; k < boxes.size(); k++)
//fprintf(f, "%g, %s\n", boxes(k), _S(strVec4i(boxes[k])));
fclose(f);
_boxesTests[i].resize(boxesTests[i].size());
for (int j = 0; j < boxesTests[i].size(); j++)
_boxesTests[i][j] = boxesTests[i][j];
} */
//evaluatePerImgRecall(_boxesTests, "PerImgAllNS.m", 5000);
#pragma omp parallel for
for (int i = 0; i < TestNum; i++){
boxesTests[i].sort(false);
//for (int j = 0; j < boxesTests[i].size(); j++)
// _boxesTests[i][j] = boxesTests[i][j];
finalBoxes=boxesTests[i];
}
//evaluatePerImgRecall(_boxesTests, "PerImgAllS.m", 5000);
tm.Stop();
printf( "Average time for predicting an image (%s) is %gs\n", _clrName[_Clr], tm.TimeInSeconds() );
}
} }
struct MatchPathSeparator struct MatchPathSeparator
{ {
bool operator()( char ch ) const bool operator()( char ch ) const
{ {
return ch == '/'; return ch == '/';
} }
}; };
std::string inline basename( std::string const& pathname ) std::string inline basename( std::string const& pathname )
{ {
return std::string( return std::string( std::find_if( pathname.rbegin(), pathname.rend(), MatchPathSeparator() ).base(), pathname.end() );
std::find_if( pathname.rbegin(), pathname.rend(),
MatchPathSeparator() ).base(),
pathname.end() );
} }
std::string inline removeExtension( std::string const& filename ) std::string inline removeExtension( std::string const& filename )
{ {
std::string::const_reverse_iterator std::string::const_reverse_iterator pivot = std::find( filename.rbegin(), filename.rend(), '.' );
pivot return pivot == filename.rend() ? filename : std::string( filename.begin(), pivot.base() - 1 );
= std::find( filename.rbegin(), filename.rend(), '.' );
return pivot == filename.rend()
? filename
: std::string( filename.begin(), pivot.base() - 1 );
} }
// Read matrix from binary file // Read matrix from binary file
bool ObjectnessBING::matRead(const string& filename, Mat& _M){ bool ObjectnessBING::matRead( const string& filename, Mat& _M )
{
FileStorage fs2(filename+".yml.gz", FileStorage::READ);
String fileNameString(filename.c_str()); FileStorage fs2( filename + ".yml.gz", FileStorage::READ );
String fileNameString( filename.c_str() );
Mat M;
fs2[removeExtension(basename(fileNameString))]>> M; Mat M;
fs2[removeExtension( basename( fileNameString ) )] >> M;
/*FILE* f = fopen(_S(filename), "rb");
if (f == NULL) /*FILE* f = fopen(_S(filename), "rb");
return false; if (f == NULL)
char buf[8]; return false;
int pre = fread(buf,sizeof(char), 5, f); char buf[8];
if (strncmp(buf, "CmMat", 5) != 0) { int pre = fread(buf,sizeof(char), 5, f);
printf("Invalidate CvMat data file %s\n", _S(filename)); if (strncmp(buf, "CmMat", 5) != 0) {
return false; printf("Invalidate CvMat data file %s\n", _S(filename));
} return false;
int headData[3]; // Width, height, type }
fread(headData, sizeof(int), 3, f); int headData[3]; // Width, height, type
Mat M(headData[1], headData[0], headData[2]); fread(headData, sizeof(int), 3, f);
fread(M.data, sizeof(char), M.step * M.rows, f); Mat M(headData[1], headData[0], headData[2]);
fclose(f); */ fread(M.data, sizeof(char), M.step * M.rows, f);
fclose(f); */
M.copyTo(_M);
return true; M.copyTo( _M );
return true;
}
vector<float> ObjectnessBING::getobjectnessValues()
{
return objectnessValues;
} }
void ObjectnessBING::read( const cv::FileNode& fn ) void ObjectnessBING::read( const cv::FileNode& fn )
{ {
//params.read( fn );
} }
void ObjectnessBING::write( cv::FileStorage& fs ) const void ObjectnessBING::write( cv::FileStorage& fs ) const
{ {
//params.write( fs );
} }
bool ObjectnessBING::computeSaliencyImpl( const InputArray& src, OutputArray& dst ) bool ObjectnessBING::computeSaliencyImpl( const InputArray image, OutputArray objBoundingBox )
{ {
ValStructVec<float, Vec4i> &finalBoxes; ValStructVec<float, Vec4i> &finalBoxes;
getObjBndBoxesForImage( src.getMat(), finalBoxes, 250 ); getObjBndBoxesForSingleImage( image.getMat(), finalBoxes, 250 );
// list of rectangles returned by objectess function // List of rectangles returned by objectess function in ascending order.
//std::vector<Vec4i> boxesList = finalBoxes.structVals; // At the top there are the rectangles with lower values of ​​objectness, ie more
dst = finalBoxes.getSortedStructVal(); // likely to have objects in them.
//dst = finalBoxes.structVals; objBoundingBox = finalBoxes.getSortedStructVal();
// List of the rectangles' objectness value
unsigned long int valIdxesSize = finalBoxes.valIdxes.size();
objectnessValues.resize( valIdxesSize );
for ( uint i = 0; i < valIdxesSize; i++ )
objectnessValues[i] = finalBoxes.valIdxes[i].first;
return true; return true;
} }
......
...@@ -50,7 +50,10 @@ CV_INIT_ALGORITHM( StaticSaliencySpectralResidual, "SALIENCY.SPECTRAL_RESIDUAL", ...@@ -50,7 +50,10 @@ CV_INIT_ALGORITHM( StaticSaliencySpectralResidual, "SALIENCY.SPECTRAL_RESIDUAL",
CV_INIT_ALGORITHM( MotionSaliencyPBAS, "SALIENCY.PBAS",); CV_INIT_ALGORITHM( MotionSaliencyPBAS, "SALIENCY.PBAS",);
CV_INIT_ALGORITHM( ObjectnessBING, "SALIENCY.BING", ); CV_INIT_ALGORITHM( ObjectnessBING, "SALIENCY.BING",
obj.info()->addParam(obj, "_base", obj._base);
obj.info()->addParam(obj, "_NSS", obj._NSS);
obj.info()->addParam(obj, "_W", obj._W));
bool initModule_saliency( void ) bool initModule_saliency( void )
{ {
......
...@@ -97,7 +97,7 @@ void StaticSaliencySpectralResidual::write( cv::FileStorage& fs ) const ...@@ -97,7 +97,7 @@ void StaticSaliencySpectralResidual::write( cv::FileStorage& fs ) const
//params.write( fs ); //params.write( fs );
} }
bool StaticSaliencySpectralResidual::computeSaliencyImpl( const InputArray& image, OutputArray& saliencyMap ) bool StaticSaliencySpectralResidual::computeSaliencyImpl( const InputArray image, OutputArray saliencyMap )
{ {
Mat grayTemp, grayDown; Mat grayTemp, grayDown;
std::vector<Mat> mv; std::vector<Mat> mv;
......
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