664 lines
21 KiB
C++
664 lines
21 KiB
C++
/************************************************************************
|
|
BlobGroup.cpp
|
|
|
|
FUNCIONALITAT: Implementation de la classe BlobGroup
|
|
AUTOR: Inspecta S.L.
|
|
MODIFICACIONS (Modificacition, Autor, Data):
|
|
|
|
**************************************************************************/
|
|
|
|
#include "BlobGroup.h"
|
|
//! Show errors functions: only works for windows releases
|
|
#ifdef _SHOW_ERRORS
|
|
#include <afx.h> //suport per a CStrings
|
|
#include <afxwin.h> //suport per a AfxMessageBox
|
|
#endif
|
|
|
|
/**************************************************************************
|
|
Constructors / Destructors
|
|
**************************************************************************/
|
|
|
|
/**
|
|
- FUNCTION: BlobGroup
|
|
- FUNCTIONALITY: Standard constructor
|
|
- PARAMETERS:
|
|
- RESULT:
|
|
- creates an empty set of blobs
|
|
- RESTRICTIONS:
|
|
- AUTHOR: Ricard Borràs
|
|
- CREATION DATE: 25-05-2005.
|
|
- MODIFICATION: Date. Author. Description.
|
|
*/
|
|
BlobGroup::BlobGroup()
|
|
{
|
|
m_blobs = BlobVector();
|
|
}
|
|
|
|
/**
|
|
- FUNCTION: BlobGroup
|
|
- FUNCTIONALITY: Copy constructor
|
|
- PARAMETERS:
|
|
- source: object to copy
|
|
- RESULT:
|
|
- RESTRICTIONS:
|
|
- AUTHOR: Ricard Borràs
|
|
- CREATION DATE: 25-05-2005.
|
|
- MODIFICATION: Date. Author. Description.
|
|
*/
|
|
BlobGroup::BlobGroup(const BlobGroup& source)
|
|
{
|
|
// create the new from the past as a parameter
|
|
//m_blobs = BlobVector(source.getNumBlobs());
|
|
m_blobs.reserve(source.getNumBlobs());
|
|
// copy the blobs from the origin to the current one
|
|
BlobVector::const_iterator pBlobsSrc = source.m_blobs.begin();
|
|
//BlobVector::iterator pBlobsDst = m_blobs.begin();
|
|
while (pBlobsSrc != source.m_blobs.end()) {
|
|
// can't call the operator = since BlobVector is a
|
|
// Blob vector *. So create a new blob from the
|
|
// original blob
|
|
m_blobs.push_back(new Blob(**pBlobsSrc));
|
|
pBlobsSrc++;
|
|
}
|
|
}
|
|
|
|
/**
|
|
- FUNCTION: ~BlobGroup
|
|
- FUNCTIONALITY: Destructor
|
|
- PARAMETERS:
|
|
- RESULT:
|
|
- RESTRICTIONS:
|
|
- AUTHOR: Ricard Borràs
|
|
- CREATION DATE: 25-05-2005.
|
|
- MODIFICATION: Date. Author. Description.
|
|
*/
|
|
BlobGroup::~BlobGroup()
|
|
{
|
|
clearBlobs();
|
|
}
|
|
|
|
/**************************************************************************
|
|
Operadors / Operators
|
|
**************************************************************************/
|
|
|
|
/**
|
|
- FUNCTION: Assigment operator
|
|
- FUNCTIONALITY:
|
|
- PARAMETERS:
|
|
- RESULT:
|
|
- RESTRICTIONS:
|
|
- AUTHOR: Ricard Borràs
|
|
- CREATION DATE: 25-05-2005.
|
|
- MODIFICATION: Date. Author. Description.
|
|
*/
|
|
BlobGroup& BlobGroup::operator=(const BlobGroup& source)
|
|
{
|
|
// if they are already the same, nothing needs to be done
|
|
if (this != &source) {
|
|
// release the old set of blobs
|
|
for (int i = 0; i < getNumBlobs(); ++i) {
|
|
delete m_blobs[i];
|
|
}
|
|
m_blobs.clear();
|
|
// create the new from the past as a parameter
|
|
m_blobs = BlobVector(source.getNumBlobs());
|
|
// copy the blobs from the origin to the current one
|
|
BlobVector::const_iterator pBlobsSrc = source.m_blobs.begin();
|
|
BlobVector::iterator pBlobsDst = m_blobs.begin();
|
|
|
|
while (pBlobsSrc != source.m_blobs.end()) {
|
|
// can't call the operator = since BlobVector is a
|
|
// Blob vector *. So create a new blob from the
|
|
// original blob
|
|
*pBlobsDst = new Blob(**pBlobsSrc);
|
|
pBlobsSrc++;
|
|
pBlobsDst++;
|
|
}
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
/**
|
|
- FUNCTION: + operator
|
|
- FUNCTIONALITY: Joins the blobs in source with the current ones
|
|
- PARAMETERS:
|
|
- source: object to copy the blobs
|
|
- RESULT:
|
|
- object with the actual blobs and the source blobs
|
|
- RESTRICTIONS:
|
|
- AUTHOR: Ricard Borràs
|
|
- CREATION DATE: 25-05-2005.
|
|
- MODIFICATION: Date. Author. Description.
|
|
*/
|
|
BlobGroup BlobGroup::operator+(const BlobGroup& source) const
|
|
{
|
|
// create the result from the current blobs
|
|
BlobGroup result(*this);
|
|
|
|
// reserve memory for the new blobs
|
|
result.m_blobs.resize(result.getNumBlobs() + source.getNumBlobs());
|
|
|
|
// declare the iterators to cross the origin and destination blobs
|
|
BlobVector::const_iterator pBlobsSrc = source.m_blobs.begin();
|
|
BlobVector::iterator pBlobsDst = result.m_blobs.end();
|
|
|
|
// insert the blobs from the origin to the current one
|
|
while (pBlobsSrc != source.m_blobs.end()) {
|
|
pBlobsDst--;
|
|
*pBlobsDst = new Blob(**pBlobsSrc);
|
|
pBlobsSrc++;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**************************************************************************
|
|
Operacions / Operations
|
|
**************************************************************************/
|
|
|
|
/**
|
|
- FUNCTIONS: addBlob
|
|
- FUNCIONALITAT: Afegeix un blob al conjunt
|
|
- PARAMETERS:
|
|
- blob: blob a afegir
|
|
- RESULTAT:
|
|
- modifica el conjunt de blobs actual
|
|
- RESTRICCIONS:
|
|
- AUTOR: Ricard Borràs
|
|
- DATE OF CREATION: 2006/03/01
|
|
- MODIFICATION: Data. Autor. Description.
|
|
*/
|
|
void BlobGroup::addBlob(Blob* blob)
|
|
{
|
|
if (blob != NULL) {
|
|
Blob* tp = new Blob(blob);
|
|
m_blobs.push_back(tp);
|
|
}
|
|
}
|
|
|
|
#ifdef MATRIXCV_ACTIU
|
|
/**
|
|
- FUNCTION: getResult
|
|
- FUNCTIONALITY: Computes the function evaluator on all the blobs of the class
|
|
and returns a vector with the result
|
|
- PARAMETERS:
|
|
- evaluator: function to apply to each blob (any object derived from the
|
|
OperatorBlob class)
|
|
- RESULT:
|
|
- vector with all the results in the same order as the blobs
|
|
- RESTRICTIONS:
|
|
- AUTHOR: Ricard Borràs
|
|
- CREATION DATE: 25-05-2005.
|
|
- MODIFICATION: Date. Author. Description.
|
|
*/
|
|
DoubleVector BlobGroup::getResult(BlobOperator* evaluator) const
|
|
{
|
|
if (getNumBlobs() <= 0) {
|
|
return DoubleVector();
|
|
}
|
|
|
|
// define the result
|
|
DoubleVector result = DoubleVector(getNumBlobs());
|
|
// and iterators on the blobs and the result
|
|
DoubleVector::iterator itResult = result.GetIterator();
|
|
BlobVector::const_iterator itBlobs = m_blobs.begin();
|
|
|
|
// evaluate the function on all blobs
|
|
while (itBlobs != m_blobs.end()) {
|
|
*itResult = (*evaluator)(**itBlobs);
|
|
itBlobs++;
|
|
itResult++;
|
|
}
|
|
return result;
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
- FUNCTION: getResult
|
|
- FUNCTIONALITY: Computes the function evaluator on all the blobs of the class
|
|
and returns a vector with the result
|
|
- PARAMETERS:
|
|
- evaluator: function to apply to each blob (any object derived from the
|
|
OperatorBlob class)
|
|
- RESULT:
|
|
- vector with all the results in the same order as the blobs
|
|
- RESTRICTIONS:
|
|
- AUTHOR: Ricard Borràs
|
|
- CREATION DATE: 25-05-2005.
|
|
- MODIFICATION: Date. Author. Description.
|
|
*/
|
|
DoubleStlVector BlobGroup::getStlResult(BlobOperator* evaluator) const
|
|
{
|
|
if (getNumBlobs() <= 0) {
|
|
return DoubleStlVector();
|
|
}
|
|
|
|
// define the result
|
|
DoubleStlVector result = DoubleStlVector(getNumBlobs());
|
|
// and iterators on the blobs and the result
|
|
DoubleStlVector::iterator itResult = result.begin();
|
|
BlobVector::const_iterator itBlobs = m_blobs.begin();
|
|
|
|
// evaluate the function on all blobs
|
|
while (itBlobs != m_blobs.end()) {
|
|
*itResult = (*evaluator)(**itBlobs);
|
|
itBlobs++;
|
|
itResult++;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
- FUNCTION: getNumber
|
|
- FUNCTIONALITY: Computes the function evaluator on a blob of the class
|
|
- PARAMETERS:
|
|
- indexBlob: index of the blob to compute the function
|
|
- evaluator: function to apply to each blob (any object derived from the
|
|
OperatorBlob class)
|
|
- RESULT:
|
|
- RESTRICTIONS:
|
|
- AUTHOR: Ricard Borràs
|
|
- CREATION DATE: 25-05-2005.
|
|
- MODIFICATION: Date. Author. Description.
|
|
*/
|
|
double BlobGroup::getNumber(int indexBlob, BlobOperator* evaluator) const
|
|
{
|
|
if (indexBlob < 0 || indexBlob >= getNumBlobs()) {
|
|
raiseError(EXCEPTION_BLOB_OUT_OF_BOUNDS);
|
|
}
|
|
return (*evaluator)(*m_blobs[indexBlob]);
|
|
}
|
|
|
|
/**
|
|
- FUNCTION: filter (const version)
|
|
- FUNCTIONALITY: Get some blobs from the class based on conditions on measures
|
|
of the blobs.
|
|
- PARAMETERS:
|
|
- dst: where to store the selected blobs
|
|
- filterAction: B_INCLUDE: include the blobs which pass the filter in the result
|
|
B_EXCLUDE: exclude the blobs which pass the filter in the result
|
|
- evaluator: Object to evaluate the blob
|
|
- Condition: How to decide if the result returned by evaluator on each blob
|
|
is included or not. It can be:
|
|
B_EQUAL,B_NOT_EQUAL,B_GREATER,B_LESS,B_GREATER_OR_EQUAL,
|
|
B_LESS_OR_EQUAL,B_INSIDE,B_OUTSIDE
|
|
- LowLimit: numerical value to evaluate the Condition on evaluator(blob)
|
|
- HighLimit: numerical value to evaluate the Condition on evaluator(blob).
|
|
Only useful for B_INSIDE and B_OUTSIDE
|
|
- RESULT:
|
|
- It returns on dst the blobs that accomplish (B_INCLUDE) or discards (B_EXCLUDE)
|
|
the Condition on the result returned by evaluator on each blob
|
|
- RESTRICTIONS:
|
|
- AUTHOR: Ricard Borràs
|
|
- CREATION DATE: 25-05-2005.
|
|
- MODIFICATION: Date. Author. Description.
|
|
*/
|
|
/////////////////////////// FILTRAT DE BLOBS ////////////////////////////////////
|
|
void BlobGroup::filter(BlobGroup& dst, int filterAction, BlobOperator* evaluator, int condition, double lowLimit, double highLimit /*=0*/) const
|
|
|
|
{
|
|
// do the job
|
|
doFilter(dst, filterAction, evaluator, condition, lowLimit, highLimit);
|
|
}
|
|
|
|
/**
|
|
- FUNCTION: filter
|
|
- FUNCTIONALITY: Get some blobs from the class based on conditions on measures
|
|
of the blobs.
|
|
- PARAMETERS:
|
|
- dst: where to store the selected blobs
|
|
- filterAction: B_INCLUDE: include the blobs which pass the filter in the result
|
|
B_EXCLUDE: exclude the blobs which pass the filter in the result
|
|
- evaluator: Object to evaluate the blob
|
|
- Condition: How to decide if the result returned by evaluator on each blob
|
|
is included or not. It can be:
|
|
B_EQUAL,B_NOT_EQUAL,B_GREATER,B_LESS,B_GREATER_OR_EQUAL,
|
|
B_LESS_OR_EQUAL,B_INSIDE,B_OUTSIDE
|
|
- LowLimit: numerical value to evaluate the Condition on evaluator(blob)
|
|
- HighLimit: numerical value to evaluate the Condition on evaluator(blob).
|
|
Only useful for B_INSIDE and B_OUTSIDE
|
|
- RESULT:
|
|
- It returns on dst the blobs that accomplish (B_INCLUDE) or discards (B_EXCLUDE)
|
|
the Condition on the result returned by evaluator on each blob
|
|
- RESTRICTIONS:
|
|
- AUTHOR: Ricard Borràs
|
|
- CREATION DATE: 25-05-2005.
|
|
- MODIFICATION: Date. Author. Description.
|
|
*/
|
|
void BlobGroup::filter(BlobGroup& dst, int filterAction, BlobOperator* evaluator, int condition, double lowLimit, double highLimit /*=0*/)
|
|
|
|
{
|
|
int numBlobs = getNumBlobs();
|
|
|
|
// do the job
|
|
doFilter(dst, filterAction, evaluator, condition, lowLimit, highLimit);
|
|
|
|
// inline operation: remove previous blobs
|
|
if (&dst == this) {
|
|
// delete the first blobs (which are the originals)
|
|
// since we will have them replicated at the end if they pass the filter
|
|
BlobVector::iterator itBlobs = m_blobs.begin();
|
|
for (int i = 0; i < numBlobs; i++) {
|
|
delete *itBlobs;
|
|
itBlobs++;
|
|
}
|
|
m_blobs.erase(m_blobs.begin(), itBlobs);
|
|
}
|
|
}
|
|
|
|
void BlobGroup::filter(BlobGroup& dst, FilterAction filterAction, BlobOperator* evaluator, FilterCondition condition, double lowLimit, double highLimit /*= 0 */)
|
|
{
|
|
filter(dst, (int)filterAction, evaluator, (int)condition, lowLimit, highLimit);
|
|
}
|
|
|
|
|
|
//! Does the filter method job
|
|
void BlobGroup::doFilter(BlobGroup& dst, int filterAction, BlobOperator* evaluator, int condition, double lowLimit, double highLimit/* = 0*/) const
|
|
{
|
|
int i, numBlobs;
|
|
bool evaluationResult;
|
|
DoubleStlVector evaluationBlobs;
|
|
DoubleStlVector::iterator itEvaluationBlobs;
|
|
|
|
if (getNumBlobs() <= 0) { return; }
|
|
if (!evaluator) { return; }
|
|
// evaluate the blobs with the relevant function
|
|
evaluationBlobs = getStlResult(evaluator);
|
|
itEvaluationBlobs = evaluationBlobs.begin();
|
|
numBlobs = getNumBlobs();
|
|
switch(condition)
|
|
{
|
|
case B_EQUAL:
|
|
for (i = 0; i < numBlobs; ++i, ++itEvaluationBlobs) {
|
|
evaluationResult= *itEvaluationBlobs == lowLimit;
|
|
if ((evaluationResult && filterAction == B_INCLUDE) ||
|
|
(!evaluationResult && filterAction == B_EXCLUDE)) {
|
|
dst.m_blobs.push_back(new Blob(getBlob(i)));
|
|
}
|
|
}
|
|
break;
|
|
case B_NOT_EQUAL:
|
|
for (i = 0; i < numBlobs; ++i, ++itEvaluationBlobs) {
|
|
evaluationResult = *itEvaluationBlobs != lowLimit;
|
|
if ((evaluationResult && filterAction == B_INCLUDE) ||
|
|
(!evaluationResult && filterAction == B_EXCLUDE)) {
|
|
dst.m_blobs.push_back(new Blob(getBlob(i)));
|
|
}
|
|
}
|
|
break;
|
|
case B_GREATER:
|
|
for (i = 0; i < numBlobs; ++i, ++itEvaluationBlobs) {
|
|
evaluationResult = *itEvaluationBlobs > lowLimit;
|
|
if ((evaluationResult && filterAction == B_INCLUDE) ||
|
|
(!evaluationResult && filterAction == B_EXCLUDE)) {
|
|
dst.m_blobs.push_back(new Blob(getBlob(i)));
|
|
}
|
|
}
|
|
break;
|
|
case B_LESS:
|
|
for (i = 0; i < numBlobs; ++i, ++itEvaluationBlobs) {
|
|
evaluationResult = *itEvaluationBlobs < lowLimit;
|
|
if ((evaluationResult && filterAction == B_INCLUDE) ||
|
|
(!evaluationResult && filterAction == B_EXCLUDE)) {
|
|
dst.m_blobs.push_back(new Blob(getBlob(i)));
|
|
}
|
|
}
|
|
break;
|
|
case B_GREATER_OR_EQUAL:
|
|
for (i = 0; i < numBlobs; ++i, ++itEvaluationBlobs) {
|
|
evaluationResult = *itEvaluationBlobs>= lowLimit;
|
|
if ((evaluationResult && filterAction == B_INCLUDE) ||
|
|
(!evaluationResult && filterAction == B_EXCLUDE)) {
|
|
dst.m_blobs.push_back(new Blob(getBlob(i)));
|
|
}
|
|
}
|
|
break;
|
|
case B_LESS_OR_EQUAL:
|
|
for (i = 0; i < numBlobs; ++i, ++itEvaluationBlobs) {
|
|
evaluationResult = *itEvaluationBlobs <= lowLimit;
|
|
if ((evaluationResult && filterAction == B_INCLUDE) ||
|
|
(!evaluationResult && filterAction == B_EXCLUDE)) {
|
|
dst.m_blobs.push_back(new Blob(getBlob(i)));
|
|
}
|
|
}
|
|
break;
|
|
case B_INSIDE:
|
|
for (i = 0; i < numBlobs; ++i, ++itEvaluationBlobs) {
|
|
evaluationResult = (*itEvaluationBlobs >= lowLimit) && (*itEvaluationBlobs <= highLimit);
|
|
if ((evaluationResult && filterAction == B_INCLUDE) ||
|
|
(!evaluationResult && filterAction == B_EXCLUDE)) {
|
|
dst.m_blobs.push_back(new Blob(getBlob(i)));
|
|
}
|
|
}
|
|
break;
|
|
case B_OUTSIDE:
|
|
for (i = 0; i < numBlobs; ++i, ++itEvaluationBlobs) {
|
|
evaluationResult = (*itEvaluationBlobs < lowLimit) || (*itEvaluationBlobs > highLimit);
|
|
if ((evaluationResult && filterAction == B_INCLUDE) ||
|
|
(!evaluationResult && filterAction == B_EXCLUDE)) {
|
|
dst.m_blobs.push_back(new Blob(getBlob(i)));
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
- FUNCTION: getBlob
|
|
- FUNCTIONALITY: Gets the n-th blob (without ordering the blobs)
|
|
- PARAMETERS:
|
|
- index: index in the blob array
|
|
- RESULT:
|
|
- RESTRICTIONS:
|
|
- AUTHOR: Ricard Borràs
|
|
- CREATION DATE: 25-05-2005.
|
|
- MODIFICATION: Date. Author. Description.
|
|
*/
|
|
Blob BlobGroup::getBlob(int index) const
|
|
{
|
|
if (index < 0 || index >= getNumBlobs()) {
|
|
raiseError(EXCEPTION_BLOB_OUT_OF_BOUNDS);
|
|
}
|
|
|
|
return *m_blobs[index];
|
|
}
|
|
|
|
Blob *BlobGroup::getBlob(int index)
|
|
{
|
|
if (index < 0 || index >= getNumBlobs()) {
|
|
raiseError(EXCEPTION_BLOB_OUT_OF_BOUNDS);
|
|
}
|
|
return m_blobs[index];
|
|
}
|
|
|
|
Blob BlobGroup::getBlobByID(LabelID id) const{
|
|
for (int i = 0; i < getNumBlobs(); ++i) {
|
|
if (getBlob(i).getID() == id) {
|
|
return m_blobs[i];
|
|
}
|
|
}
|
|
raiseError(EXCEPTION_EXECUTE_FAULT);
|
|
return Blob();
|
|
}
|
|
|
|
Blob *BlobGroup::getBlobByID(LabelID id) {
|
|
for (int i = 0; i < getNumBlobs(); ++i) {
|
|
if (getBlob(i)->getID() == id) {
|
|
return m_blobs[i];
|
|
}
|
|
}
|
|
raiseError(EXCEPTION_EXECUTE_FAULT);
|
|
return (new Blob());
|
|
}
|
|
|
|
/**
|
|
- FUNCTION: getNthBlob
|
|
- FUNCTIONALITY: Gets the n-th blob ordering first the blobs with some criteria
|
|
- PARAMETERS:
|
|
- criteria: criteria to order the blob array
|
|
- nBlob: index of the returned blob in the ordered blob array
|
|
- dst: where to store the result
|
|
- RESULT:
|
|
- RESTRICTIONS:
|
|
- AUTHOR: Ricard Borràs
|
|
- CREATION DATE: 25-05-2005.
|
|
- MODIFICATION: Date. Author. Description.
|
|
*/
|
|
void BlobGroup::getNthBlob(BlobOperator* criteria, int nBlob, Blob& dst) const
|
|
{
|
|
// verify that we are not accessing out the blobs vector
|
|
if(nBlob < 0 || nBlob >= getNumBlobs()) {
|
|
//raiseError(EXCEPTION_BLOB_OUT_OF_BOUNDS);
|
|
dst = Blob();
|
|
return;
|
|
}
|
|
|
|
DoubleStlVector evaluationBlobs, evaluationBlobsOrdered;
|
|
double value;
|
|
|
|
// evaluate the blobs with the relevant function
|
|
evaluationBlobs = getStlResult(criteria);
|
|
|
|
evaluationBlobsOrdered = DoubleStlVector(getNumBlobs());
|
|
|
|
// get the nBlob first results (in descending order)
|
|
std::partial_sort_copy(evaluationBlobs.begin(),
|
|
evaluationBlobs.end(),
|
|
evaluationBlobsOrdered.begin(),
|
|
evaluationBlobsOrdered.end(),
|
|
std::greater<double>());
|
|
|
|
value = evaluationBlobsOrdered[nBlob];
|
|
|
|
// look for the first blob that has the value n-ssim
|
|
DoubleStlVector::const_iterator itEvaluation = evaluationBlobs.begin();
|
|
|
|
bool foundBlob = false;
|
|
int indexBlob = 0;
|
|
while (itEvaluation != evaluationBlobs.end() && !foundBlob) {
|
|
if (*itEvaluation == value) {
|
|
foundBlob = true;
|
|
dst = Blob(getBlob(indexBlob));
|
|
}
|
|
itEvaluation++;
|
|
indexBlob++;
|
|
}
|
|
}
|
|
|
|
/**
|
|
- FUNCTION: clearBlobs
|
|
- FUNCTIONALITY: Clears all the blobs from the object and releases all its memory
|
|
- PARAMETERS:
|
|
- RESULT:
|
|
- RESTRICTIONS:
|
|
- AUTHOR: Ricard Borràs
|
|
- CREATION DATE: 25-05-2005.
|
|
- MODIFICATION: Date. Author. Description.
|
|
*/
|
|
void BlobGroup::clearBlobs()
|
|
{
|
|
BlobVector::iterator itBlobs = m_blobs.begin();
|
|
while (itBlobs != m_blobs.end()) {
|
|
delete *itBlobs;
|
|
itBlobs++;
|
|
}
|
|
|
|
m_blobs.clear();
|
|
}
|
|
|
|
/**
|
|
- FUNCTION: raiseError
|
|
- FUNCTIONALITY: Error handling function
|
|
- PARAMETERS:
|
|
- errorCode: reason of the error
|
|
- RESULT:
|
|
- in _SHOW_ERRORS version, shows a message box with the error. In release is silent.
|
|
In both cases throws an exception with the error.
|
|
- RESTRICTIONS:
|
|
- AUTHOR: Ricard Borràs
|
|
- CREATION DATE: 25-05-2005.
|
|
- MODIFICATION: Date. Author. Description.
|
|
*/
|
|
void BlobGroup::raiseError(int errorCode) const
|
|
{
|
|
//! Do we need to show errors?
|
|
#ifdef _SHOW_ERRORS
|
|
CString msg, format = "Error en BlobGroup: %s";
|
|
|
|
switch (errorCode)
|
|
{
|
|
case EXCEPTION_BLOB_OUT_OF_BOUNDS:
|
|
msg.Format(format, "Intentant accedir a un blob no existent");
|
|
break;
|
|
default:
|
|
msg.Format(format, "Codi d'error desconegut");
|
|
break;
|
|
}
|
|
|
|
AfxMessageBox(msg);
|
|
|
|
#endif
|
|
throw errorCode;
|
|
}
|
|
|
|
/**************************************************************************
|
|
Auxiliars / Auxiliary functions
|
|
**************************************************************************/
|
|
|
|
/**
|
|
- FUNCTION: printBlobs
|
|
- FUNCTIONALITY: Prints some blob features in an ASCII file
|
|
- PARAMETERS:
|
|
- fileName: full path + filename to generate
|
|
- RESULT:
|
|
- RESTRICTIONS:
|
|
- AUTHOR: Ricard Borràs
|
|
- CREATION DATE: 25-05-2005.
|
|
- MODIFICATION: Date. Author. Description.
|
|
*/
|
|
void BlobGroup::printBlobs(char* fileName) const
|
|
{
|
|
DoubleStlVector area, /*perimeter,*/ exterior, compactness, length,
|
|
externalPerimeter, perimeterConvex, perimeter;
|
|
int i;
|
|
FILE* fp;
|
|
|
|
area = getStlResult(BlobGetArea());
|
|
perimeter = getStlResult(BlobGetPerimeter());
|
|
exterior = getStlResult(BlobGetExterior());
|
|
compactness = getStlResult(BlobGetCompactness());
|
|
length = getStlResult(BlobGetLength());
|
|
externalPerimeter = getStlResult(BlobGetExternalPerimeter());
|
|
perimeterConvex = getStlResult(BlobGetHullPerimeter());
|
|
|
|
fp = fopen(fileName, "w");
|
|
|
|
for (i = 0; i < getNumBlobs(); ++i) {
|
|
fprintf(fp, "blob %d ->\t a=%7.0f\t p=%8.2f (%8.2f external)\t pconvex=%8.2f\t ext=%.0f\t c=%3.2f\t l=%8.2f\n",
|
|
i, area[i], perimeter[i], externalPerimeter[i], perimeterConvex[i], exterior[i], compactness[i], length[i]);
|
|
}
|
|
fclose(fp);
|
|
|
|
}
|
|
|
|
Blob* BlobGroup::getBlobNearestTo(const cv::Point& pt)
|
|
{
|
|
float minD = FLT_MAX, d = 0;
|
|
int numBlobs = m_blobs.size();
|
|
int idxNearest = -1;
|
|
for (int i = 0; i < numBlobs; ++i) {
|
|
cv::Point diff = m_blobs[i]->getCenter() - pt;
|
|
d = diff.x * diff.x + diff.y * diff.y;
|
|
if (minD > d) {
|
|
idxNearest = i;
|
|
minD = d;
|
|
}
|
|
}
|
|
if (idxNearest != -1) {
|
|
return m_blobs[idxNearest];
|
|
}
|
|
else {
|
|
return NULL;
|
|
}
|
|
}
|