Commit 67ff9508 authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

added openfabmap code, contributed by Arren Glover. fixed several warnings in…

added openfabmap code, contributed by Arren Glover. fixed several warnings in the new versions of retina filters
parent 6ee7ecb6
This diff is collapsed.
...@@ -967,6 +967,8 @@ namespace cv ...@@ -967,6 +967,8 @@ namespace cv
#include "opencv2/contrib/retina.hpp" #include "opencv2/contrib/retina.hpp"
#include "opencv2/contrib/openfabmap.hpp"
#endif #endif
#endif #endif
......
This diff is collapsed.
...@@ -115,9 +115,9 @@ ...@@ -115,9 +115,9 @@
//using namespace std; //using namespace std;
namespace cv namespace cv
{ {
class BasicRetinaFilter class BasicRetinaFilter
{ {
public: public:
/** /**
* constructor of the base bio-inspired toolbox, parameters are only linked to imae input size and number of filtering capabilities of the object * constructor of the base bio-inspired toolbox, parameters are only linked to imae input size and number of filtering capabilities of the object
...@@ -349,7 +349,7 @@ public: ...@@ -349,7 +349,7 @@ public:
*/ */
inline void setMaxInputValue(const float newMaxInputValue){this->_maxInputValue=newMaxInputValue;}; inline void setMaxInputValue(const float newMaxInputValue){this->_maxInputValue=newMaxInputValue;};
protected: protected:
///////////////////////// /////////////////////////
// data buffers // data buffers
...@@ -437,20 +437,20 @@ protected: ...@@ -437,20 +437,20 @@ protected:
void _local_verticalAnticausalFilter_multGain(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd, const unsigned int *integrationAreas); // this functions affects _gain at the output void _local_verticalAnticausalFilter_multGain(float *outputFrame, unsigned int IDcolumnStart, unsigned int IDcolumnEnd, const unsigned int *integrationAreas); // this functions affects _gain at the output
#ifdef MAKE_PARALLEL #ifdef MAKE_PARALLEL
/****************************************************** /******************************************************
** IF some parallelizing thread methods are available, then, main loops are parallelized using these functors ** IF some parallelizing thread methods are available, then, main loops are parallelized using these functors
** ==> main idea paralellise main filters loops, then, only the most used methods are parallelized... TODO : increase the number of parallelised methods as necessary ** ==> main idea paralellise main filters loops, then, only the most used methods are parallelized... TODO : increase the number of parallelised methods as necessary
** ==> functors names = Parallel_$$$ where $$$= the name of the serial method that is parallelised ** ==> functors names = Parallel_$$$ where $$$= the name of the serial method that is parallelised
** ==> functors constructors can differ from the parameters used with their related serial functions ** ==> functors constructors can differ from the parameters used with their related serial functions
*/ */
#define _DEBUG_TBB // define DEBUG_TBB in order to display additionnal data on stdout #define _DEBUG_TBB // define DEBUG_TBB in order to display additionnal data on stdout
class Parallel_horizontalAnticausalFilter: public cv::ParallelLoopBody class Parallel_horizontalAnticausalFilter: public cv::ParallelLoopBody
{ {
private: private:
float *outputFrame; float *outputFrame;
const unsigned int IDrowEnd, nbColumns; unsigned int IDrowEnd, nbColumns;
const float filterParam_a; float filterParam_a;
public: public:
// constructor which takes the input image pointer reference reference and limits // constructor which takes the input image pointer reference reference and limits
Parallel_horizontalAnticausalFilter(float *bufferToProcess, const unsigned int idEnd, const unsigned int nbCols, const float a ) Parallel_horizontalAnticausalFilter(float *bufferToProcess, const unsigned int idEnd, const unsigned int nbCols, const float a )
...@@ -492,8 +492,8 @@ protected: ...@@ -492,8 +492,8 @@ protected:
private: private:
const float *inputFrame; const float *inputFrame;
float *outputFrame; float *outputFrame;
const unsigned int IDrowStart, nbColumns; unsigned int IDrowStart, nbColumns;
const float filterParam_a, filterParam_tau; float filterParam_a, filterParam_tau;
public: public:
Parallel_horizontalCausalFilter_addInput(const float *bufferToAddAsInputProcess, float *bufferToProcess, const unsigned int idStart, const unsigned int nbCols, const float a, const float tau) Parallel_horizontalCausalFilter_addInput(const float *bufferToAddAsInputProcess, float *bufferToProcess, const unsigned int idStart, const unsigned int nbCols, const float a, const float tau)
:inputFrame(bufferToAddAsInputProcess), outputFrame(bufferToProcess), IDrowStart(idStart), nbColumns(nbCols), filterParam_a(a), filterParam_tau(tau){} :inputFrame(bufferToAddAsInputProcess), outputFrame(bufferToProcess), IDrowStart(idStart), nbColumns(nbCols), filterParam_a(a), filterParam_tau(tau){}
...@@ -517,8 +517,8 @@ protected: ...@@ -517,8 +517,8 @@ protected:
{ {
private: private:
float *outputFrame; float *outputFrame;
const unsigned int nbRows, nbColumns; unsigned int nbRows, nbColumns;
const float filterParam_a; float filterParam_a;
public: public:
Parallel_verticalCausalFilter(float *bufferToProcess, const unsigned int nbRws, const unsigned int nbCols, const float a ) Parallel_verticalCausalFilter(float *bufferToProcess, const unsigned int nbRws, const unsigned int nbCols, const float a )
:outputFrame(bufferToProcess), nbRows(nbRws), nbColumns(nbCols), filterParam_a(a){} :outputFrame(bufferToProcess), nbRows(nbRws), nbColumns(nbCols), filterParam_a(a){}
...@@ -544,8 +544,8 @@ protected: ...@@ -544,8 +544,8 @@ protected:
{ {
private: private:
float *outputFrame; float *outputFrame;
const unsigned int nbRows, nbColumns; unsigned int nbRows, nbColumns;
const float filterParam_a, filterParam_gain; float filterParam_a, filterParam_gain;
public: public:
Parallel_verticalAnticausalFilter_multGain(float *bufferToProcess, const unsigned int nbRws, const unsigned int nbCols, const float a, const float gain) Parallel_verticalAnticausalFilter_multGain(float *bufferToProcess, const unsigned int nbRws, const unsigned int nbCols, const float a, const float gain)
:outputFrame(bufferToProcess), nbRows(nbRws), nbColumns(nbCols), filterParam_a(a), filterParam_gain(gain){} :outputFrame(bufferToProcess), nbRows(nbRws), nbColumns(nbCols), filterParam_a(a), filterParam_gain(gain){}
...@@ -573,7 +573,7 @@ protected: ...@@ -573,7 +573,7 @@ protected:
private: private:
const float *localLuminance, *inputFrame; const float *localLuminance, *inputFrame;
float *outputFrame; float *outputFrame;
const float localLuminanceFactor, localLuminanceAddon, maxInputValue; float localLuminanceFactor, localLuminanceAddon, maxInputValue;
public: public:
Parallel_localAdaptation(const float *localLum, const float *inputImg, float *bufferToProcess, const float localLuminanceFact, const float localLuminanceAdd, const float maxInputVal) Parallel_localAdaptation(const float *localLum, const float *inputImg, float *bufferToProcess, const float localLuminanceFact, const float localLuminanceAdd, const float maxInputVal)
:localLuminance(localLum), inputFrame(inputImg),outputFrame(bufferToProcess), localLuminanceFactor(localLuminanceFact), localLuminanceAddon(localLuminanceAdd), maxInputValue(maxInputVal) {}; :localLuminance(localLum), inputFrame(inputImg),outputFrame(bufferToProcess), localLuminanceFactor(localLuminanceFact), localLuminanceAddon(localLuminanceAdd), maxInputValue(maxInputVal) {};
...@@ -586,25 +586,25 @@ protected: ...@@ -586,25 +586,25 @@ protected:
{ {
float X0=*(localLuminancePTR++)*localLuminanceFactor+localLuminanceAddon; float X0=*(localLuminancePTR++)*localLuminanceFactor+localLuminanceAddon;
// TODO : the following line can lead to a divide by zero ! A small offset is added, take care if the offset is too large in case of High Dynamic Range images which can use very small values... // TODO : the following line can lead to a divide by zero ! A small offset is added, take care if the offset is too large in case of High Dynamic Range images which can use very small values...
*(outputFramePTR) = (maxInputValue+X0)**inputFramePTR/(*inputFramePTR +X0+0.00000000001); *(outputFramePTR) = (maxInputValue+X0)**inputFramePTR/(*inputFramePTR +X0+0.00000000001f);
//std::cout<<"BasicRetinaFilter::inputFrame[IDpixel]=%f, X0=%f, outputFrame[IDpixel]=%f\n", inputFrame[IDpixel], X0, outputFrame[IDpixel]); //std::cout<<"BasicRetinaFilter::inputFrame[IDpixel]=%f, X0=%f, outputFrame[IDpixel]=%f\n", inputFrame[IDpixel], X0, outputFrame[IDpixel]);
} }
} }
}; };
////////////////////////////////////////// //////////////////////////////////////////
/// Specific filtering methods which manage non const spatial filtering parameter (used By retinacolor and LogProjectors) /// Specific filtering methods which manage non const spatial filtering parameter (used By retinacolor and LogProjectors)
class Parallel_horizontalAnticausalFilter_Irregular: public cv::ParallelLoopBody class Parallel_horizontalAnticausalFilter_Irregular: public cv::ParallelLoopBody
{ {
private: private:
float *outputFrame; float *outputFrame;
const float *spatialConstantBuffer; const float *spatialConstantBuffer;
const unsigned int IDrowEnd, nbColumns; unsigned int IDrowEnd, nbColumns;
public: public:
Parallel_horizontalAnticausalFilter_Irregular(float *bufferToProcess, const float *spatialConst, const unsigned int idEnd, const unsigned int nbCols) Parallel_horizontalAnticausalFilter_Irregular(float *bufferToProcess, const float *spatialConst, const unsigned int idEnd, const unsigned int nbCols)
:outputFrame(bufferToProcess), spatialConstantBuffer(spatialConst), IDrowEnd(idEnd), nbColumns(nbCols){} :outputFrame(bufferToProcess), spatialConstantBuffer(spatialConst), IDrowEnd(idEnd), nbColumns(nbCols){}
virtual void operator()( const Range& r ) const { virtual void operator()( const Range& r ) const {
for (int IDrow=r.start; IDrow!=r.end; ++IDrow) for (int IDrow=r.start; IDrow!=r.end; ++IDrow)
{ {
...@@ -625,7 +625,7 @@ virtual void operator()( const Range& r ) const { ...@@ -625,7 +625,7 @@ virtual void operator()( const Range& r ) const {
private: private:
float *outputFrame; float *outputFrame;
const float *spatialConstantBuffer; const float *spatialConstantBuffer;
const unsigned int nbRows, nbColumns; unsigned int nbRows, nbColumns;
public: public:
Parallel_verticalCausalFilter_Irregular(float *bufferToProcess, const float *spatialConst, const unsigned int nbRws, const unsigned int nbCols) Parallel_verticalCausalFilter_Irregular(float *bufferToProcess, const float *spatialConst, const unsigned int nbRws, const unsigned int nbCols)
:outputFrame(bufferToProcess), spatialConstantBuffer(spatialConst), nbRows(nbRws), nbColumns(nbCols){} :outputFrame(bufferToProcess), spatialConstantBuffer(spatialConst), nbRows(nbRws), nbColumns(nbCols){}
...@@ -649,7 +649,7 @@ virtual void operator()( const Range& r ) const { ...@@ -649,7 +649,7 @@ virtual void operator()( const Range& r ) const {
#endif #endif
}; };
} }
#endif #endif
......
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
// This file originates from the openFABMAP project:
// [http://code.google.com/p/openfabmap/]
//
// For published work which uses all or part of OpenFABMAP, please cite:
// [http://ieeexplore.ieee.org/xpl/articleDetails.jsp?arnumber=6224843]
//
// Original Algorithm by Mark Cummins and Paul Newman:
// [http://ijr.sagepub.com/content/27/6/647.short]
// [http://ieeexplore.ieee.org/xpl/articleDetails.jsp?arnumber=5613942]
// [http://ijr.sagepub.com/content/30/9/1100.abstract]
//
// License Agreement
//
// Copyright (C) 2012 Arren Glover [aj.glover@qut.edu.au] and
// Will Maddern [w.maddern@qut.edu.au], all rights reserved.
//
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "precomp.hpp"
#include "opencv2/contrib/openfabmap.hpp"
namespace cv {
namespace of2 {
BOWMSCTrainer::BOWMSCTrainer(double _clusterSize) :
clusterSize(_clusterSize) {
}
BOWMSCTrainer::~BOWMSCTrainer() {
}
Mat BOWMSCTrainer::cluster() const {
CV_Assert(!descriptors.empty());
int descCount = 0;
for(size_t i = 0; i < descriptors.size(); i++)
descCount += descriptors[i].rows;
Mat mergedDescriptors(descCount, descriptors[0].cols,
descriptors[0].type());
for(size_t i = 0, start = 0; i < descriptors.size(); i++)
{
Mat submut = mergedDescriptors.rowRange((int)start,
(int)(start + descriptors[i].rows));
descriptors[i].copyTo(submut);
start += descriptors[i].rows;
}
return cluster(mergedDescriptors);
}
Mat BOWMSCTrainer::cluster(const Mat& descriptors) const {
CV_Assert(!descriptors.empty());
// TODO: sort the descriptors before clustering.
Mat icovar = Mat::eye(descriptors.cols,descriptors.cols,descriptors.type());
vector<Mat> initialCentres;
initialCentres.push_back(descriptors.row(0));
for (int i = 1; i < descriptors.rows; i++) {
double minDist = DBL_MAX;
for (size_t j = 0; j < initialCentres.size(); j++) {
minDist = std::min(minDist,
cv::Mahalanobis(descriptors.row(i),initialCentres[j],
icovar));
}
if (minDist > clusterSize)
initialCentres.push_back(descriptors.row(i));
}
std::vector<std::list<cv::Mat> > clusters;
clusters.resize(initialCentres.size());
for (int i = 0; i < descriptors.rows; i++) {
int index = 0; double dist = 0, minDist = DBL_MAX;
for (size_t j = 0; j < initialCentres.size(); j++) {
dist = cv::Mahalanobis(descriptors.row(i),initialCentres[j],icovar);
if (dist < minDist) {
minDist = dist;
index = (int)j;
}
}
clusters[index].push_back(descriptors.row(i));
}
// TODO: throw away small clusters.
Mat vocabulary;
Mat centre = Mat::zeros(1,descriptors.cols,descriptors.type());
for (size_t i = 0; i < clusters.size(); i++) {
centre.setTo(0);
for (std::list<cv::Mat>::iterator Ci = clusters[i].begin(); Ci != clusters[i].end(); Ci++) {
centre += *Ci;
}
centre /= (double)clusters[i].size();
vocabulary.push_back(centre);
}
return vocabulary;
}
}
}
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
// This file originates from the openFABMAP project:
// [http://code.google.com/p/openfabmap/]
//
// For published work which uses all or part of OpenFABMAP, please cite:
// [http://ieeexplore.ieee.org/xpl/articleDetails.jsp?arnumber=6224843]
//
// Original Algorithm by Mark Cummins and Paul Newman:
// [http://ijr.sagepub.com/content/27/6/647.short]
// [http://ieeexplore.ieee.org/xpl/articleDetails.jsp?arnumber=5613942]
// [http://ijr.sagepub.com/content/30/9/1100.abstract]
//
// License Agreement
//
// Copyright (C) 2012 Arren Glover [aj.glover@qut.edu.au] and
// Will Maddern [w.maddern@qut.edu.au], all rights reserved.
//
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "precomp.hpp"
#include "opencv2/contrib/openfabmap.hpp"
namespace cv {
namespace of2 {
ChowLiuTree::ChowLiuTree() {
}
ChowLiuTree::~ChowLiuTree() {
}
void ChowLiuTree::add(const Mat& imgDescriptor) {
CV_Assert(!imgDescriptor.empty());
if (!imgDescriptors.empty()) {
CV_Assert(imgDescriptors[0].cols == imgDescriptor.cols);
CV_Assert(imgDescriptors[0].type() == imgDescriptor.type());
}
imgDescriptors.push_back(imgDescriptor);
}
void ChowLiuTree::add(const vector<Mat>& _imgDescriptors) {
for (size_t i = 0; i < _imgDescriptors.size(); i++) {
add(_imgDescriptors[i]);
}
}
const std::vector<cv::Mat>& ChowLiuTree::getImgDescriptors() const {
return imgDescriptors;
}
Mat ChowLiuTree::make(double infoThreshold) {
CV_Assert(!imgDescriptors.empty());
unsigned int descCount = 0;
for (size_t i = 0; i < imgDescriptors.size(); i++)
descCount += imgDescriptors[i].rows;
mergedImgDescriptors = cv::Mat(descCount, imgDescriptors[0].cols,
imgDescriptors[0].type());
for (size_t i = 0, start = 0; i < imgDescriptors.size(); i++)
{
Mat submut = mergedImgDescriptors.rowRange((int)start,
(int)(start + imgDescriptors[i].rows));
imgDescriptors[i].copyTo(submut);
start += imgDescriptors[i].rows;
}
std::list<info> edges;
createBaseEdges(edges, infoThreshold);
// TODO: if it cv_asserts here they really won't know why.
CV_Assert(reduceEdgesToMinSpan(edges));
return buildTree(edges.front().word1, edges);
}
double ChowLiuTree::P(int a, bool za) {
if(za) {
return (0.98 * cv::countNonZero(mergedImgDescriptors.col(a)) /
mergedImgDescriptors.rows) + 0.01;
} else {
return 1 - ((0.98 * cv::countNonZero(mergedImgDescriptors.col(a)) /
mergedImgDescriptors.rows) + 0.01);
}
}
double ChowLiuTree::JP(int a, bool za, int b, bool zb) {
double count = 0;
for(int i = 0; i < mergedImgDescriptors.rows; i++) {
if((mergedImgDescriptors.at<float>(i,a) > 0) == za &&
(mergedImgDescriptors.at<float>(i,b) > 0) == zb) {
count++;
}
}
return count / mergedImgDescriptors.rows;
}
double ChowLiuTree::CP(int a, bool za, int b, bool zb){
int count = 0, total = 0;
for(int i = 0; i < mergedImgDescriptors.rows; i++) {
if((mergedImgDescriptors.at<float>(i,b) > 0) == zb) {
total++;
if((mergedImgDescriptors.at<float>(i,a) > 0) == za) {
count++;
}
}
}
if(total) {
return (double)(0.98 * count)/total + 0.01;
} else {
return (za) ? 0.01 : 0.99;
}
}
cv::Mat ChowLiuTree::buildTree(int root_word, std::list<info> &edges) {
int q = root_word;
cv::Mat cltree(4, (int)edges.size()+1, CV_64F);
cltree.at<double>(0, q) = q;
cltree.at<double>(1, q) = P(q, true);
cltree.at<double>(2, q) = P(q, true);
cltree.at<double>(3, q) = P(q, true);
//setting P(zq|zpq) to P(zq) gives the root node of the chow-liu
//independence from a parent node.
//find all children and do the same
vector<int> nextqs = extractChildren(edges, q);
int pq = q;
vector<int>::iterator nextq;
for(nextq = nextqs.begin(); nextq != nextqs.end(); nextq++) {
recAddToTree(cltree, *nextq, pq, edges);
}
return cltree;
}
void ChowLiuTree::recAddToTree(cv::Mat &cltree, int q, int pq,
std::list<info>& remaining_edges) {
cltree.at<double>(0, q) = pq;
cltree.at<double>(1, q) = P(q, true);
cltree.at<double>(2, q) = CP(q, true, pq, true);
cltree.at<double>(3, q) = CP(q, true, pq, false);
//find all children and do the same
vector<int> nextqs = extractChildren(remaining_edges, q);
pq = q;
vector<int>::iterator nextq;
for(nextq = nextqs.begin(); nextq != nextqs.end(); nextq++) {
recAddToTree(cltree, *nextq, pq, remaining_edges);
}
}
vector<int> ChowLiuTree::extractChildren(std::list<info> &remaining_edges, int q) {
std::vector<int> children;
std::list<info>::iterator edge = remaining_edges.begin();
while(edge != remaining_edges.end()) {
if(edge->word1 == q) {
children.push_back(edge->word2);
edge = remaining_edges.erase(edge);
continue;
}
if(edge->word2 == q) {
children.push_back(edge->word1);
edge = remaining_edges.erase(edge);
continue;
}
edge++;
}
return children;
}
bool ChowLiuTree::sortInfoScores(const info& first, const info& second) {
return first.score > second.score;
}
double ChowLiuTree::calcMutInfo(int word1, int word2) {
double accumulation = 0;
double P00 = JP(word1, false, word2, false);
if(P00) accumulation += P00 * log(P00 / (P(word1, false)*P(word2, false)));
double P01 = JP(word1, false, word2, true);
if(P01) accumulation += P01 * log(P01 / (P(word1, false)*P(word2, true)));
double P10 = JP(word1, true, word2, false);
if(P10) accumulation += P10 * log(P10 / (P(word1, true)*P(word2, false)));
double P11 = JP(word1, true, word2, true);
if(P11) accumulation += P11 * log(P11 / (P(word1, true)*P(word2, true)));
return accumulation;
}
void ChowLiuTree::createBaseEdges(std::list<info>& edges, double infoThreshold) {
int nWords = imgDescriptors[0].cols;
info mutInfo;
for(int word1 = 0; word1 < nWords; word1++) {
for(int word2 = word1 + 1; word2 < nWords; word2++) {
mutInfo.word1 = (short)word1;
mutInfo.word2 = (short)word2;
mutInfo.score = (float)calcMutInfo(word1, word2);
if(mutInfo.score >= infoThreshold)
edges.push_back(mutInfo);
}
}
edges.sort(sortInfoScores);
}
bool ChowLiuTree::reduceEdgesToMinSpan(std::list<info>& edges) {
std::map<int, int> groups;
std::map<int, int>::iterator groupIt;
for(int i = 0; i < imgDescriptors[0].cols; i++) groups[i] = i;
int group1, group2;
std::list<info>::iterator edge = edges.begin();
while(edge != edges.end()) {
if(groups[edge->word1] != groups[edge->word2]) {
group1 = groups[edge->word1];
group2 = groups[edge->word2];
for(groupIt = groups.begin(); groupIt != groups.end(); groupIt++)
if(groupIt->second == group2) groupIt->second = group1;
edge++;
} else {
edge = edges.erase(edge);
}
}
if(edges.size() != (unsigned int)imgDescriptors[0].cols - 1) {
return false;
} else {
return true;
}
}
}
}
...@@ -100,9 +100,9 @@ ...@@ -100,9 +100,9 @@
namespace cv namespace cv
{ {
class MagnoRetinaFilter: public BasicRetinaFilter class MagnoRetinaFilter: public BasicRetinaFilter
{ {
public: public:
/** /**
* constructor parameters are only linked to image input size * constructor parameters are only linked to image input size
* @param NBrows: number of rows of the input image * @param NBrows: number of rows of the input image
...@@ -172,7 +172,7 @@ public: ...@@ -172,7 +172,7 @@ public:
*/ */
inline float getTemporalConstant(){return this->_filteringCoeficientsTable[2];}; inline float getTemporalConstant(){return this->_filteringCoeficientsTable[2];};
private: private:
// related pointers to these buffers // related pointers to these buffers
std::valarray<float> _previousInput_ON; std::valarray<float> _previousInput_ON;
...@@ -193,18 +193,18 @@ private: ...@@ -193,18 +193,18 @@ private:
// amacrine cells filter : high pass temporal filter // amacrine cells filter : high pass temporal filter
void _amacrineCellsComputing(const float *ONinput, const float *OFFinput); void _amacrineCellsComputing(const float *ONinput, const float *OFFinput);
#ifdef MAKE_PARALLEL #ifdef MAKE_PARALLEL
/****************************************************** /******************************************************
** IF some parallelizing thread methods are available, then, main loops are parallelized using these functors ** IF some parallelizing thread methods are available, then, main loops are parallelized using these functors
** ==> main idea paralellise main filters loops, then, only the most used methods are parallelized... TODO : increase the number of parallelised methods as necessary ** ==> main idea paralellise main filters loops, then, only the most used methods are parallelized... TODO : increase the number of parallelised methods as necessary
** ==> functors names = Parallel_$$$ where $$$= the name of the serial method that is parallelised ** ==> functors names = Parallel_$$$ where $$$= the name of the serial method that is parallelised
** ==> functors constructors can differ from the parameters used with their related serial functions ** ==> functors constructors can differ from the parameters used with their related serial functions
*/ */
class Parallel_amacrineCellsComputing: public cv::ParallelLoopBody class Parallel_amacrineCellsComputing: public cv::ParallelLoopBody
{ {
private: private:
const float *OPL_ON, *OPL_OFF; const float *OPL_ON, *OPL_OFF;
float *previousInput_ON, *previousInput_OFF, *amacrinCellsTempOutput_ON, *amacrinCellsTempOutput_OFF; float *previousInput_ON, *previousInput_OFF, *amacrinCellsTempOutput_ON, *amacrinCellsTempOutput_OFF;
const float temporalCoefficient; float temporalCoefficient;
public: public:
Parallel_amacrineCellsComputing(const float *OPL_ON_PTR, const float *OPL_OFF_PTR, float *previousInput_ON_PTR, float *previousInput_OFF_PTR, float *amacrinCellsTempOutput_ON_PTR, float *amacrinCellsTempOutput_OFF_PTR, float temporalCoefficientVal) Parallel_amacrineCellsComputing(const float *OPL_ON_PTR, const float *OPL_OFF_PTR, float *previousInput_ON_PTR, float *previousInput_OFF_PTR, float *amacrinCellsTempOutput_ON_PTR, float *amacrinCellsTempOutput_OFF_PTR, float temporalCoefficientVal)
:OPL_ON(OPL_ON_PTR), OPL_OFF(OPL_OFF_PTR), previousInput_ON(previousInput_ON_PTR), previousInput_OFF(previousInput_OFF_PTR), amacrinCellsTempOutput_ON(amacrinCellsTempOutput_ON_PTR), amacrinCellsTempOutput_OFF(amacrinCellsTempOutput_OFF_PTR), temporalCoefficient(temporalCoefficientVal) {} :OPL_ON(OPL_ON_PTR), OPL_OFF(OPL_OFF_PTR), previousInput_ON(previousInput_ON_PTR), previousInput_OFF(previousInput_OFF_PTR), amacrinCellsTempOutput_ON(amacrinCellsTempOutput_ON_PTR), amacrinCellsTempOutput_OFF(amacrinCellsTempOutput_OFF_PTR), temporalCoefficient(temporalCoefficientVal) {}
...@@ -236,7 +236,7 @@ private: ...@@ -236,7 +236,7 @@ private:
}; };
#endif #endif
}; };
} }
......
This diff is collapsed.
...@@ -86,9 +86,9 @@ ...@@ -86,9 +86,9 @@
namespace cv namespace cv
{ {
class RetinaColor: public BasicRetinaFilter class RetinaColor: public BasicRetinaFilter
{ {
public: public:
/** /**
* @typedef which allows to select the type of photoreceptors color sampling * @typedef which allows to select the type of photoreceptors color sampling
*/ */
...@@ -216,7 +216,7 @@ public: ...@@ -216,7 +216,7 @@ public:
*/ */
inline void setDemultiplexedColorFrame(const std::valarray<float> &demultiplexedImage){_demultiplexedColorFrame=demultiplexedImage;}; inline void setDemultiplexedColorFrame(const std::valarray<float> &demultiplexedImage){_demultiplexedColorFrame=demultiplexedImage;};
protected: protected:
// private functions // private functions
RETINA_COLORSAMPLINGMETHOD _samplingMethod; RETINA_COLORSAMPLINGMETHOD _samplingMethod;
...@@ -257,14 +257,14 @@ protected: ...@@ -257,14 +257,14 @@ protected:
void _applyImageColorSpaceConversion(const std::valarray<float> &inputFrame, std::valarray<float> &outputFrame, const float *transformTable); void _applyImageColorSpaceConversion(const std::valarray<float> &inputFrame, std::valarray<float> &outputFrame, const float *transformTable);
#ifdef MAKE_PARALLEL #ifdef MAKE_PARALLEL
/****************************************************** /******************************************************
** IF some parallelizing thread methods are available, then, main loops are parallelized using these functors ** IF some parallelizing thread methods are available, then, main loops are parallelized using these functors
** ==> main idea paralellise main filters loops, then, only the most used methods are parallelized... TODO : increase the number of parallelised methods as necessary ** ==> main idea paralellise main filters loops, then, only the most used methods are parallelized... TODO : increase the number of parallelised methods as necessary
** ==> functors names = Parallel_$$$ where $$$= the name of the serial method that is parallelised ** ==> functors names = Parallel_$$$ where $$$= the name of the serial method that is parallelised
** ==> functors constructors can differ from the parameters used with their related serial functions ** ==> functors constructors can differ from the parameters used with their related serial functions
*/ */
/* Template : /* Template :
class Parallel_ : public cv::ParallelLoopBody class Parallel_ : public cv::ParallelLoopBody
{ {
private: private:
...@@ -277,13 +277,13 @@ protected: ...@@ -277,13 +277,13 @@ protected:
} }
}: }:
*/ */
class Parallel_adaptiveHorizontalCausalFilter_addInput: public cv::ParallelLoopBody class Parallel_adaptiveHorizontalCausalFilter_addInput: public cv::ParallelLoopBody
{ {
private: private:
float *outputFrame; float *outputFrame;
const float *inputFrame, *imageGradient; const float *inputFrame, *imageGradient;
const unsigned int nbColumns; unsigned int nbColumns;
public: public:
Parallel_adaptiveHorizontalCausalFilter_addInput(const float *inputImg, float *bufferToProcess, const float *imageGrad, const unsigned int nbCols) Parallel_adaptiveHorizontalCausalFilter_addInput(const float *inputImg, float *bufferToProcess, const float *imageGrad, const unsigned int nbCols)
:outputFrame(bufferToProcess), inputFrame(inputImg), imageGradient(imageGrad), nbColumns(nbCols) {}; :outputFrame(bufferToProcess), inputFrame(inputImg), imageGradient(imageGrad), nbColumns(nbCols) {};
...@@ -309,8 +309,8 @@ protected: ...@@ -309,8 +309,8 @@ protected:
private: private:
float *outputFrame; float *outputFrame;
const float *imageGradient; const float *imageGradient;
const unsigned int nbRows, nbColumns; unsigned int nbRows, nbColumns;
const float filterParam_gain; float filterParam_gain;
public: public:
Parallel_adaptiveVerticalAnticausalFilter_multGain(float *bufferToProcess, const float *imageGrad, const unsigned int nbRws, const unsigned int nbCols, const float gain) Parallel_adaptiveVerticalAnticausalFilter_multGain(float *bufferToProcess, const float *imageGrad, const unsigned int nbRws, const unsigned int nbCols, const float gain)
:outputFrame(bufferToProcess), imageGradient(imageGrad), nbRows(nbRws), nbColumns(nbCols), filterParam_gain(gain){} :outputFrame(bufferToProcess), imageGradient(imageGrad), nbRows(nbRws), nbColumns(nbCols), filterParam_gain(gain){}
...@@ -334,7 +334,7 @@ protected: ...@@ -334,7 +334,7 @@ protected:
} }
}; };
#endif #endif
}; };
} }
#endif /*RETINACOLOR_HPP_*/ #endif /*RETINACOLOR_HPP_*/
......
...@@ -82,7 +82,7 @@ class Parallel_clipBufferValues: public cv::ParallelLoopBody ...@@ -82,7 +82,7 @@ class Parallel_clipBufferValues: public cv::ParallelLoopBody
{ {
private: private:
type *bufferToClip; type *bufferToClip;
const type minValue, maxValue; type minValue, maxValue;
public: public:
Parallel_clipBufferValues(type* bufferToProcess, const type min, const type max) Parallel_clipBufferValues(type* bufferToProcess, const type min, const type max)
...@@ -105,16 +105,16 @@ public: ...@@ -105,16 +105,16 @@ public:
namespace cv namespace cv
{ {
/** /**
* @class TemplateBuffer * @class TemplateBuffer
* @brief this class is a simple template memory buffer which contains basic functions to get information on or normalize the buffer content * @brief this class is a simple template memory buffer which contains basic functions to get information on or normalize the buffer content
* note that thanks to the parent STL template class "valarray", it is possible to perform easily operations on the full array such as addition, product etc. * note that thanks to the parent STL template class "valarray", it is possible to perform easily operations on the full array such as addition, product etc.
* @author Alexandre BENOIT (benoit.alexandre.vision@gmail.com), helped by Gelu IONESCU (gelu.ionescu@lis.inpg.fr) * @author Alexandre BENOIT (benoit.alexandre.vision@gmail.com), helped by Gelu IONESCU (gelu.ionescu@lis.inpg.fr)
* creation date: september 2007 * creation date: september 2007
*/ */
template <class type> class TemplateBuffer : public std::valarray<type> template <class type> class TemplateBuffer : public std::valarray<type>
{ {
public: public:
/** /**
* constructor for monodimensional array * constructor for monodimensional array
...@@ -409,7 +409,7 @@ public: ...@@ -409,7 +409,7 @@ public:
*/ */
inline double getMean(){return this->sum()/this->size();}; inline double getMean(){return this->sum()/this->size();};
protected: protected:
size_t _NBrows; size_t _NBrows;
size_t _NBcolumns; size_t _NBcolumns;
size_t _NBdepths; size_t _NBdepths;
...@@ -418,13 +418,13 @@ protected: ...@@ -418,13 +418,13 @@ protected:
// utilities // utilities
static type _abs(const type x); static type _abs(const type x);
}; };
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
/// normalize output between 0 and 255, can be applied on images of different size that the declared size if nbPixels parameters is setted up; /// normalize output between 0 and 255, can be applied on images of different size that the declared size if nbPixels parameters is setted up;
template <class type> template <class type>
void TemplateBuffer<type>::normalizeGrayOutput_0_maxOutputValue(type *inputOutputBuffer, const size_t processedPixels, const type maxOutputValue) void TemplateBuffer<type>::normalizeGrayOutput_0_maxOutputValue(type *inputOutputBuffer, const size_t processedPixels, const type maxOutputValue)
{ {
type maxValue=inputOutputBuffer[0], minValue=inputOutputBuffer[0]; type maxValue=inputOutputBuffer[0], minValue=inputOutputBuffer[0];
// get the min and max value // get the min and max value
...@@ -446,11 +446,11 @@ void TemplateBuffer<type>::normalizeGrayOutput_0_maxOutputValue(type *inputOutpu ...@@ -446,11 +446,11 @@ void TemplateBuffer<type>::normalizeGrayOutput_0_maxOutputValue(type *inputOutpu
for (register size_t j = 0; j < processedPixels; ++j, ++inputOutputBufferPTR) for (register size_t j = 0; j < processedPixels; ++j, ++inputOutputBufferPTR)
*inputOutputBufferPTR=*(inputOutputBufferPTR)*factor+offset; *inputOutputBufferPTR=*(inputOutputBufferPTR)*factor+offset;
} }
// normalize data with a sigmoide close to 0 (saturates values for those superior to 0) // normalize data with a sigmoide close to 0 (saturates values for those superior to 0)
template <class type> template <class type>
void TemplateBuffer<type>::normalizeGrayOutputNearZeroCentreredSigmoide(type *inputBuffer, type *outputBuffer, const type sensitivity, const type maxOutputValue) void TemplateBuffer<type>::normalizeGrayOutputNearZeroCentreredSigmoide(type *inputBuffer, type *outputBuffer, const type sensitivity, const type maxOutputValue)
{ {
if (inputBuffer==NULL) if (inputBuffer==NULL)
inputBuffer=Buffer(); inputBuffer=Buffer();
if (outputBuffer==NULL) if (outputBuffer==NULL)
...@@ -467,12 +467,12 @@ void TemplateBuffer<type>::normalizeGrayOutputNearZeroCentreredSigmoide(type *in ...@@ -467,12 +467,12 @@ void TemplateBuffer<type>::normalizeGrayOutputNearZeroCentreredSigmoide(type *in
type currentCubeLuminance=*inputBufferPTR**inputBufferPTR**inputBufferPTR; type currentCubeLuminance=*inputBufferPTR**inputBufferPTR**inputBufferPTR;
*(outputBufferPTR++)=maxOutputValue*currentCubeLuminance/(currentCubeLuminance+X0cube); *(outputBufferPTR++)=maxOutputValue*currentCubeLuminance/(currentCubeLuminance+X0cube);
} }
} }
// normalize and adjust luminance with a centered to 128 sigmode // normalize and adjust luminance with a centered to 128 sigmode
template <class type> template <class type>
void TemplateBuffer<type>::normalizeGrayOutputCentredSigmoide(const type meanValue, const type sensitivity, const type maxOutputValue, type *inputBuffer, type *outputBuffer, const unsigned int nbPixels) void TemplateBuffer<type>::normalizeGrayOutputCentredSigmoide(const type meanValue, const type sensitivity, const type maxOutputValue, type *inputBuffer, type *outputBuffer, const unsigned int nbPixels)
{ {
if (sensitivity==1.0) if (sensitivity==1.0)
{ {
...@@ -489,12 +489,12 @@ void TemplateBuffer<type>::normalizeGrayOutputCentredSigmoide(const type meanVal ...@@ -489,12 +489,12 @@ void TemplateBuffer<type>::normalizeGrayOutputCentredSigmoide(const type meanVal
for (register size_t j = 0; j < nbPixels; ++j, ++inputBufferPTR) for (register size_t j = 0; j < nbPixels; ++j, ++inputBufferPTR)
*(outputBufferPTR++)=(meanValue+(meanValue+X0)*(*(inputBufferPTR)-meanValue)/(_abs(*(inputBufferPTR)-meanValue)+X0)); *(outputBufferPTR++)=(meanValue+(meanValue+X0)*(*(inputBufferPTR)-meanValue)/(_abs(*(inputBufferPTR)-meanValue)+X0));
} }
// center and reduct the image (image-mean)/std // center and reduct the image (image-mean)/std
template <class type> template <class type>
void TemplateBuffer<type>::centerReductImageLuminance(type *inputOutputBuffer) void TemplateBuffer<type>::centerReductImageLuminance(type *inputOutputBuffer)
{ {
// if outputBuffer unsassigned, the rewrite the buffer // if outputBuffer unsassigned, the rewrite the buffer
if (inputOutputBuffer==NULL) if (inputOutputBuffer==NULL)
inputOutputBuffer=Buffer(); inputOutputBuffer=Buffer();
...@@ -518,35 +518,35 @@ void TemplateBuffer<type>::centerReductImageLuminance(type *inputOutputBuffer) ...@@ -518,35 +518,35 @@ void TemplateBuffer<type>::centerReductImageLuminance(type *inputOutputBuffer)
inputOutputBufferPTR=inputOutputBuffer; inputOutputBufferPTR=inputOutputBuffer;
for (size_t index=0;index<_NBpixels;++index, ++inputOutputBufferPTR) for (size_t index=0;index<_NBpixels;++index, ++inputOutputBufferPTR)
*inputOutputBufferPTR=(*(inputOutputBufferPTR)-meanValue)/stdValue; *inputOutputBufferPTR=(*(inputOutputBufferPTR)-meanValue)/stdValue;
} }
template <class type> template <class type>
type TemplateBuffer<type>::_abs(const type x) type TemplateBuffer<type>::_abs(const type x)
{ {
if (x>0) if (x>0)
return x; return x;
else else
return -x; return -x;
} }
template < > template < >
inline int TemplateBuffer<int>::_abs(const int x) inline int TemplateBuffer<int>::_abs(const int x)
{ {
return std::abs(x); return std::abs(x);
} }
template < > template < >
inline double TemplateBuffer<double>::_abs(const double x) inline double TemplateBuffer<double>::_abs(const double x)
{ {
return std::fabs(x); return std::fabs(x);
} }
template < > template < >
inline float TemplateBuffer<float>::_abs(const float x) inline float TemplateBuffer<float>::_abs(const float x)
{ {
return std::fabs(x); return std::fabs(x);
} }
} }
#endif #endif
......
...@@ -856,8 +856,8 @@ bool DepthNormalPyramid::extractTemplate(Template& templ) const ...@@ -856,8 +856,8 @@ bool DepthNormalPyramid::extractTemplate(Template& templ) const
std::stable_sort(candidates.begin(), candidates.end()); std::stable_sort(candidates.begin(), candidates.end());
// Use heuristic based on object area for initial distance threshold // Use heuristic based on object area for initial distance threshold
int area = static_cast<int>(no_mask ? normal.total() : countNonZero(local_mask)); float area = no_mask ? (float)normal.total() : (float)countNonZero(local_mask);
float distance = sqrtf(static_cast<float>(area)) / sqrtf(static_cast<float>(num_features)) + 1.5f; float distance = sqrtf(area) / sqrtf((float)num_features) + 1.5f;
selectScatteredFeatures(candidates, templ.features, num_features, distance); selectScatteredFeatures(candidates, templ.features, num_features, distance);
// Size determined externally, needs to match templates for other modalities // Size determined externally, needs to match templates for other modalities
......
This diff is collapsed.
This diff is collapsed.
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
// This file originates from the openFABMAP project:
// [http://code.google.com/p/openfabmap/]
//
// For published work which uses all or part of OpenFABMAP, please cite:
// [http://ieeexplore.ieee.org/xpl/articleDetails.jsp?arnumber=6224843]
//
// Original Algorithm by Mark Cummins and Paul Newman:
// [http://ijr.sagepub.com/content/27/6/647.short]
// [http://ieeexplore.ieee.org/xpl/articleDetails.jsp?arnumber=5613942]
// [http://ijr.sagepub.com/content/30/9/1100.abstract]
//
// License Agreement
//
// Copyright (C) 2012 Arren Glover [aj.glover@qut.edu.au] and
// Will Maddern [w.maddern@qut.edu.au], all rights reserved.
//
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "opencv2/opencv.hpp"
#include "opencv2/nonfree/nonfree.hpp"
using namespace cv;
using namespace std;
int main(int argc, char * argv[]) {
cout << "This sample program demonstrates the FAB-MAP image matching "
"algorithm" << endl << endl;
string dataDir;
if (argc == 1) {
dataDir = "fabmap/";
} else if (argc == 2) {
dataDir = string(argv[1]);
dataDir += "/";
} else {
//incorrect arguments
cout << "Usage: fabmap_sample <sample data directory>" <<
endl;
return -1;
}
FileStorage fs;
//load/generate vocab
cout << "Loading Vocabulary: " <<
dataDir + string("vocab_small.yml") << endl << endl;
fs.open(dataDir + string("vocab_small.yml"), FileStorage::READ);
Mat vocab;
fs["Vocabulary"] >> vocab;
if (vocab.empty()) {
cerr << "Vocabulary not found" << endl;
return -1;
}
fs.release();
//load/generate training data
cout << "Loading Training Data: " <<
dataDir + string("train_data_small.yml") << endl << endl;
fs.open(dataDir + string("train_data_small.yml"), FileStorage::READ);
Mat trainData;
fs["BOWImageDescs"] >> trainData;
if (trainData.empty()) {
cerr << "Training Data not found" << endl;
return -1;
}
fs.release();
//create Chow-liu tree
cout << "Making Chow-Liu Tree from training data" << endl <<
endl;
of2::ChowLiuTree treeBuilder;
treeBuilder.add(trainData);
Mat tree = treeBuilder.make();
//generate test data
cout << "Extracting Test Data from images" << endl <<
endl;
Ptr<FeatureDetector> detector =
new DynamicAdaptedFeatureDetector(
AdjusterAdapter::create("STAR"), 130, 150, 5);
Ptr<DescriptorExtractor> extractor =
new SurfDescriptorExtractor(1000, 4, 2, false, true);
Ptr<DescriptorMatcher> matcher =
DescriptorMatcher::create("FlannBased");
BOWImgDescriptorExtractor bide(extractor, matcher);
bide.setVocabulary(vocab);
vector<string> imageNames;
imageNames.push_back(string("stlucia_test_small0000.jpeg"));
imageNames.push_back(string("stlucia_test_small0001.jpeg"));
imageNames.push_back(string("stlucia_test_small0002.jpeg"));
imageNames.push_back(string("stlucia_test_small0003.jpeg"));
imageNames.push_back(string("stlucia_test_small0004.jpeg"));
imageNames.push_back(string("stlucia_test_small0005.jpeg"));
imageNames.push_back(string("stlucia_test_small0006.jpeg"));
imageNames.push_back(string("stlucia_test_small0007.jpeg"));
imageNames.push_back(string("stlucia_test_small0008.jpeg"));
imageNames.push_back(string("stlucia_test_small0009.jpeg"));
Mat testData;
Mat frame;
Mat bow;
vector<KeyPoint> kpts;
for(size_t i = 0; i < imageNames.size(); i++) {
cout << dataDir + imageNames[i] << endl;
frame = imread(dataDir + imageNames[i]);
if(frame.empty()) {
cerr << "Test images not found" << endl;
return -1;
}
detector->detect(frame, kpts);
bide.compute(frame, kpts, bow);
testData.push_back(bow);
drawKeypoints(frame, kpts, frame);
imshow(imageNames[i], frame);
waitKey(10);
}
//run fabmap
cout << "Running FAB-MAP algorithm" << endl <<
endl;
Ptr<of2::FabMap> fabmap;
fabmap = new of2::FabMap2(tree, 0.39, 0, of2::FabMap::SAMPLED |
of2::FabMap::CHOW_LIU);
fabmap->addTraining(trainData);
vector<of2::IMatch> matches;
fabmap->compare(testData, matches, true);
//display output
Mat result_small = Mat::zeros(10, 10, CV_8UC1);
vector<of2::IMatch>::iterator l;
for(l = matches.begin(); l != matches.end(); l++) {
if(l->imgIdx < 0) {
result_small.at<char>(l->queryIdx, l->queryIdx) =
(char)(l->match*255);
} else {
result_small.at<char>(l->queryIdx, l->imgIdx) =
(char)(l->match*255);
}
}
Mat result_large(100, 100, CV_8UC1);
resize(result_small, result_large, Size(500, 500), 0, 0, CV_INTER_NN);
imshow("Confusion Matrix", result_large);
waitKey();
cout << endl << "Press any key to exit" << endl;
return 0;
}
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