/ENB355Linux/BlobResult.cpp

https://bitbucket.org/rako/enb355linux · C++ · 943 lines · 320 code · 67 blank · 556 comment · 86 complexity · 872bc5d4aa6e179989d68822489a9e29 MD5 · raw file

  1. /************************************************************************
  2. BlobResult.cpp
  3. FUNCIONALITAT: Implementació de la classe CBlobResult
  4. AUTOR: Inspecta S.L.
  5. MODIFICACIONS (Modificació, Autor, Data):
  6. **************************************************************************/
  7. #include <limits.h>
  8. #include <stdio.h>
  9. #include <functional>
  10. #include <algorithm>
  11. #include "BlobResult.h"
  12. //! Show errors functions: only works for windows releases
  13. /* #ifdef _SHOW_ERRORS
  14. #include <afx.h> //suport per a CStrings
  15. #include <afxwin.h> //suport per a AfxMessageBox
  16. #endif */
  17. /**************************************************************************
  18. Constructors / Destructors
  19. **************************************************************************/
  20. /**
  21. - FUNCIÓ: CBlobResult
  22. - FUNCIONALITAT: Constructor estandard.
  23. - PARÀMETRES:
  24. - RESULTAT:
  25. - Crea un CBlobResult sense cap blob
  26. - RESTRICCIONS:
  27. - AUTOR: Ricard Borràs
  28. - DATA DE CREACIÓ: 20-07-2004.
  29. - MODIFICACIÓ: Data. Autor. Descripció.
  30. */
  31. /**
  32. - FUNCTION: CBlobResult
  33. - FUNCTIONALITY: Standard constructor
  34. - PARAMETERS:
  35. - RESULT:
  36. - creates an empty set of blobs
  37. - RESTRICTIONS:
  38. - AUTHOR: Ricard Borràs
  39. - CREATION DATE: 25-05-2005.
  40. - MODIFICATION: Date. Author. Description.
  41. */
  42. CBlobResult::CBlobResult()
  43. {
  44. m_blobs = Blob_vector();
  45. }
  46. /**
  47. - FUNCIÓ: CBlobResult
  48. - FUNCIONALITAT: Constructor a partir d'una imatge. Inicialitza la seqüència de blobs
  49. amb els blobs resultants de l'anàlisi de blobs de la imatge.
  50. - PARÀMETRES:
  51. - source: imatge d'on s'extreuran els blobs
  52. - mask: màscara a aplicar. Només es calcularan els blobs on la màscara sigui
  53. diferent de 0. Els blobs que toquin a un pixel 0 de la màscara seran
  54. considerats exteriors.
  55. - threshold: llindar que s'aplicarà a la imatge source abans de calcular els blobs
  56. - findmoments: indica si s'han de calcular els moments de cada blob
  57. - blackBlobs: true per buscar blobs negres a la binaritzazió (it will join all extern white blobs).
  58. false per buscar blobs negres a la binaritzazió (it will join all extern black blobs).
  59. - RESULTAT:
  60. - objecte CBlobResult amb els blobs de la imatge source
  61. - RESTRICCIONS:
  62. - AUTOR: Ricard Borràs
  63. - DATA DE CREACIÓ: 25-05-2005.
  64. - MODIFICACIÓ: Data. Autor. Descripció.
  65. */
  66. /**
  67. - FUNCTION: CBlob
  68. - FUNCTIONALITY: Constructor from an image. Fills an object with all the blobs in
  69. the image
  70. - PARAMETERS:
  71. - source: image to extract the blobs from
  72. - mask: optional mask to apply. The blobs will be extracted where the mask is
  73. not 0. All the neighbouring blobs where the mask is 0 will be extern blobs
  74. - threshold: threshold level to apply to the image before computing blobs
  75. - findmoments: true to calculate the blob moments (slower) (needed to calculate elipses!)
  76. - blackBlobs: true to search for black blobs in the binarization (it will join all extern white blobs).
  77. false to search for white blobs in the binarization (it will join all extern black blobs).
  78. - RESULT:
  79. - object with all the blobs in the image. It throws an EXCEPCIO_CALCUL_BLOBS
  80. if some error appears in the BlobAnalysis function
  81. - RESTRICTIONS:
  82. - AUTHOR: Ricard Borràs
  83. - CREATION DATE: 25-05-2005.
  84. - MODIFICATION: Date. Author. Description.
  85. */
  86. CBlobResult::CBlobResult(IplImage *source, IplImage *mask, uchar backgroundColor )
  87. {
  88. bool success;
  89. try
  90. {
  91. success = ComponentLabeling( source, mask, backgroundColor, m_blobs );
  92. }
  93. catch(...)
  94. {
  95. success = false;
  96. }
  97. if( !success ) throw EXCEPCIO_CALCUL_BLOBS;
  98. }
  99. /**
  100. - FUNCIÓ: CBlobResult
  101. - FUNCIONALITAT: Constructor de còpia. Inicialitza la seqüència de blobs
  102. amb els blobs del paràmetre.
  103. - PARÀMETRES:
  104. - source: objecte que es copiarà
  105. - RESULTAT:
  106. - objecte CBlobResult amb els blobs de l'objecte source
  107. - RESTRICCIONS:
  108. - AUTOR: Ricard Borràs
  109. - DATA DE CREACIÓ: 25-05-2005.
  110. - MODIFICACIÓ: Data. Autor. Descripció.
  111. */
  112. /**
  113. - FUNCTION: CBlobResult
  114. - FUNCTIONALITY: Copy constructor
  115. - PARAMETERS:
  116. - source: object to copy
  117. - RESULT:
  118. - RESTRICTIONS:
  119. - AUTHOR: Ricard Borràs
  120. - CREATION DATE: 25-05-2005.
  121. - MODIFICATION: Date. Author. Description.
  122. */
  123. CBlobResult::CBlobResult( const CBlobResult &source )
  124. {
  125. m_blobs = Blob_vector( source.GetNumBlobs() );
  126. // creem el nou a partir del passat com a paràmetre
  127. m_blobs = Blob_vector( source.GetNumBlobs() );
  128. // copiem els blobs de l'origen a l'actual
  129. Blob_vector::const_iterator pBlobsSrc = source.m_blobs.begin();
  130. Blob_vector::iterator pBlobsDst = m_blobs.begin();
  131. while( pBlobsSrc != source.m_blobs.end() )
  132. {
  133. // no podem cridar a l'operador = ja que Blob_vector és un
  134. // vector de CBlob*. Per tant, creem un blob nou a partir del
  135. // blob original
  136. *pBlobsDst = new CBlob(**pBlobsSrc);
  137. pBlobsSrc++;
  138. pBlobsDst++;
  139. }
  140. }
  141. /**
  142. - FUNCIÓ: ~CBlobResult
  143. - FUNCIONALITAT: Destructor estandard.
  144. - PARÀMETRES:
  145. - RESULTAT:
  146. - Allibera la memòria reservada de cadascun dels blobs de la classe
  147. - RESTRICCIONS:
  148. - AUTOR: Ricard Borràs
  149. - DATA DE CREACIÓ: 25-05-2005.
  150. - MODIFICACIÓ: Data. Autor. Descripció.
  151. */
  152. /**
  153. - FUNCTION: ~CBlobResult
  154. - FUNCTIONALITY: Destructor
  155. - PARAMETERS:
  156. - RESULT:
  157. - RESTRICTIONS:
  158. - AUTHOR: Ricard Borràs
  159. - CREATION DATE: 25-05-2005.
  160. - MODIFICATION: Date. Author. Description.
  161. */
  162. CBlobResult::~CBlobResult()
  163. {
  164. ClearBlobs();
  165. }
  166. /**************************************************************************
  167. Operadors / Operators
  168. **************************************************************************/
  169. /**
  170. - FUNCIÓ: operador =
  171. - FUNCIONALITAT: Assigna un objecte source a l'actual
  172. - PARÀMETRES:
  173. - source: objecte a assignar
  174. - RESULTAT:
  175. - Substitueix els blobs actuals per els de l'objecte source
  176. - RESTRICCIONS:
  177. - AUTOR: Ricard Borràs
  178. - DATA DE CREACIÓ: 25-05-2005.
  179. - MODIFICACIÓ: Data. Autor. Descripció.
  180. */
  181. /**
  182. - FUNCTION: Assigment operator
  183. - FUNCTIONALITY:
  184. - PARAMETERS:
  185. - RESULT:
  186. - RESTRICTIONS:
  187. - AUTHOR: Ricard Borràs
  188. - CREATION DATE: 25-05-2005.
  189. - MODIFICATION: Date. Author. Description.
  190. */
  191. CBlobResult& CBlobResult::operator=(const CBlobResult& source)
  192. {
  193. // si ja són el mateix, no cal fer res
  194. if (this != &source)
  195. {
  196. // alliberem el conjunt de blobs antic
  197. for( int i = 0; i < GetNumBlobs(); i++ )
  198. {
  199. delete m_blobs[i];
  200. }
  201. m_blobs.clear();
  202. // creem el nou a partir del passat com a paràmetre
  203. m_blobs = Blob_vector( source.GetNumBlobs() );
  204. // copiem els blobs de l'origen a l'actual
  205. Blob_vector::const_iterator pBlobsSrc = source.m_blobs.begin();
  206. Blob_vector::iterator pBlobsDst = m_blobs.begin();
  207. while( pBlobsSrc != source.m_blobs.end() )
  208. {
  209. // no podem cridar a l'operador = ja que Blob_vector és un
  210. // vector de CBlob*. Per tant, creem un blob nou a partir del
  211. // blob original
  212. *pBlobsDst = new CBlob(**pBlobsSrc);
  213. pBlobsSrc++;
  214. pBlobsDst++;
  215. }
  216. }
  217. return *this;
  218. }
  219. /**
  220. - FUNCIÓ: operador +
  221. - FUNCIONALITAT: Concatena els blobs de dos CBlobResult
  222. - PARÀMETRES:
  223. - source: d'on s'agafaran els blobs afegits a l'actual
  224. - RESULTAT:
  225. - retorna un nou CBlobResult amb els dos CBlobResult concatenats
  226. - RESTRICCIONS:
  227. - AUTOR: Ricard Borràs
  228. - DATA DE CREACIÓ: 25-05-2005.
  229. - NOTA: per la implementació, els blobs del paràmetre es posen en ordre invers
  230. - MODIFICACIÓ: Data. Autor. Descripció.
  231. */
  232. /**
  233. - FUNCTION: + operator
  234. - FUNCTIONALITY: Joins the blobs in source with the current ones
  235. - PARAMETERS:
  236. - source: object to copy the blobs
  237. - RESULT:
  238. - object with the actual blobs and the source blobs
  239. - RESTRICTIONS:
  240. - AUTHOR: Ricard Borràs
  241. - CREATION DATE: 25-05-2005.
  242. - MODIFICATION: Date. Author. Description.
  243. */
  244. CBlobResult CBlobResult::operator+( const CBlobResult& source ) const
  245. {
  246. //creem el resultat a partir dels blobs actuals
  247. CBlobResult resultat( *this );
  248. // reservem memòria per als nous blobs
  249. resultat.m_blobs.resize( resultat.GetNumBlobs() + source.GetNumBlobs() );
  250. // declarem els iterador per recòrrer els blobs d'origen i desti
  251. Blob_vector::const_iterator pBlobsSrc = source.m_blobs.begin();
  252. Blob_vector::iterator pBlobsDst = resultat.m_blobs.end();
  253. // insertem els blobs de l'origen a l'actual
  254. while( pBlobsSrc != source.m_blobs.end() )
  255. {
  256. pBlobsDst--;
  257. *pBlobsDst = new CBlob(**pBlobsSrc);
  258. pBlobsSrc++;
  259. }
  260. return resultat;
  261. }
  262. /**************************************************************************
  263. Operacions / Operations
  264. **************************************************************************/
  265. /**
  266. - FUNCIÓ: AddBlob
  267. - FUNCIONALITAT: Afegeix un blob al conjunt
  268. - PARÀMETRES:
  269. - blob: blob a afegir
  270. - RESULTAT:
  271. - modifica el conjunt de blobs actual
  272. - RESTRICCIONS:
  273. - AUTOR: Ricard Borràs
  274. - DATA DE CREACIÓ: 2006/03/01
  275. - MODIFICACIÓ: Data. Autor. Descripció.
  276. */
  277. void CBlobResult::AddBlob( CBlob *blob )
  278. {
  279. if( blob != NULL )
  280. m_blobs.push_back( new CBlob( blob ) );
  281. }
  282. #ifdef MATRIXCV_ACTIU
  283. /**
  284. - FUNCIÓ: GetResult
  285. - FUNCIONALITAT: Calcula el resultat especificat sobre tots els blobs de la classe
  286. - PARÀMETRES:
  287. - evaluador: Qualsevol objecte derivat de COperadorBlob
  288. - RESULTAT:
  289. - Retorna un array de double's amb el resultat per cada blob
  290. - RESTRICCIONS:
  291. - AUTOR: Ricard Borràs
  292. - DATA DE CREACIÓ: 25-05-2005.
  293. - MODIFICACIÓ: Data. Autor. Descripció.
  294. */
  295. /**
  296. - FUNCTION: GetResult
  297. - FUNCTIONALITY: Computes the function evaluador on all the blobs of the class
  298. and returns a vector with the result
  299. - PARAMETERS:
  300. - evaluador: function to apply to each blob (any object derived from the
  301. COperadorBlob class )
  302. - RESULT:
  303. - vector with all the results in the same order as the blobs
  304. - RESTRICTIONS:
  305. - AUTHOR: Ricard Borràs
  306. - CREATION DATE: 25-05-2005.
  307. - MODIFICATION: Date. Author. Description.
  308. */
  309. double_vector CBlobResult::GetResult( funcio_calculBlob *evaluador ) const
  310. {
  311. if( GetNumBlobs() <= 0 )
  312. {
  313. return double_vector();
  314. }
  315. // definim el resultat
  316. double_vector result = double_vector( GetNumBlobs() );
  317. // i iteradors sobre els blobs i el resultat
  318. double_vector::iterator itResult = result.GetIterator();
  319. Blob_vector::const_iterator itBlobs = m_blobs.begin();
  320. // avaluem la funció en tots els blobs
  321. while( itBlobs != m_blobs.end() )
  322. {
  323. *itResult = (*evaluador)(**itBlobs);
  324. itBlobs++;
  325. itResult++;
  326. }
  327. return result;
  328. }
  329. #endif
  330. /**
  331. - FUNCIÓ: GetSTLResult
  332. - FUNCIONALITAT: Calcula el resultat especificat sobre tots els blobs de la classe
  333. - PARÀMETRES:
  334. - evaluador: Qualsevol objecte derivat de COperadorBlob
  335. - RESULTAT:
  336. - Retorna un array de double's STL amb el resultat per cada blob
  337. - RESTRICCIONS:
  338. - AUTOR: Ricard Borràs
  339. - DATA DE CREACIÓ: 25-05-2005.
  340. - MODIFICACIÓ: Data. Autor. Descripció.
  341. */
  342. /**
  343. - FUNCTION: GetResult
  344. - FUNCTIONALITY: Computes the function evaluador on all the blobs of the class
  345. and returns a vector with the result
  346. - PARAMETERS:
  347. - evaluador: function to apply to each blob (any object derived from the
  348. COperadorBlob class )
  349. - RESULT:
  350. - vector with all the results in the same order as the blobs
  351. - RESTRICTIONS:
  352. - AUTHOR: Ricard Borràs
  353. - CREATION DATE: 25-05-2005.
  354. - MODIFICATION: Date. Author. Description.
  355. */
  356. double_stl_vector CBlobResult::GetSTLResult( funcio_calculBlob *evaluador ) const
  357. {
  358. if( GetNumBlobs() <= 0 )
  359. {
  360. return double_stl_vector();
  361. }
  362. // definim el resultat
  363. double_stl_vector result = double_stl_vector( GetNumBlobs() );
  364. // i iteradors sobre els blobs i el resultat
  365. double_stl_vector::iterator itResult = result.begin();
  366. Blob_vector::const_iterator itBlobs = m_blobs.begin();
  367. // avaluem la funció en tots els blobs
  368. while( itBlobs != m_blobs.end() )
  369. {
  370. *itResult = (*evaluador)(**itBlobs);
  371. itBlobs++;
  372. itResult++;
  373. }
  374. return result;
  375. }
  376. /**
  377. - FUNCIÓ: GetNumber
  378. - FUNCIONALITAT: Calcula el resultat especificat sobre un únic blob de la classe
  379. - PARÀMETRES:
  380. - evaluador: Qualsevol objecte derivat de COperadorBlob
  381. - indexblob: número de blob del que volem calcular el resultat.
  382. - RESULTAT:
  383. - Retorna un double amb el resultat
  384. - RESTRICCIONS:
  385. - AUTOR: Ricard Borràs
  386. - DATA DE CREACIÓ: 25-05-2005.
  387. - MODIFICACIÓ: Data. Autor. Descripció.
  388. */
  389. /**
  390. - FUNCTION: GetNumber
  391. - FUNCTIONALITY: Computes the function evaluador on a blob of the class
  392. - PARAMETERS:
  393. - indexBlob: index of the blob to compute the function
  394. - evaluador: function to apply to each blob (any object derived from the
  395. COperadorBlob class )
  396. - RESULT:
  397. - RESTRICTIONS:
  398. - AUTHOR: Ricard Borràs
  399. - CREATION DATE: 25-05-2005.
  400. - MODIFICATION: Date. Author. Description.
  401. */
  402. double CBlobResult::GetNumber( int indexBlob, funcio_calculBlob *evaluador ) const
  403. {
  404. /* if( indexBlob < 0 || indexBlob >= GetNumBlobs() )
  405. RaiseError( EXCEPTION_BLOB_OUT_OF_BOUNDS ); */
  406. return (*evaluador)( *m_blobs[indexBlob] );
  407. }
  408. /////////////////////////// FILTRAT DE BLOBS ////////////////////////////////////
  409. /**
  410. - FUNCIÓ: Filter
  411. - FUNCIONALITAT: Filtra els blobs de la classe i deixa el resultat amb només
  412. els blobs que han passat el filtre.
  413. El filtrat es basa en especificar condicions sobre un resultat dels blobs
  414. i seleccionar (o excloure) aquells blobs que no compleixen una determinada
  415. condicio
  416. - PARÀMETRES:
  417. - dst: variable per deixar els blobs filtrats
  418. - filterAction: acció de filtrat. Incloure els blobs trobats (B_INCLUDE),
  419. o excloure els blobs trobats (B_EXCLUDE)
  420. - evaluador: Funció per evaluar els blobs (qualsevol objecte derivat de COperadorBlob
  421. - Condition: tipus de condició que ha de superar la mesura (FilterType)
  422. sobre cada blob per a ser considerat.
  423. B_EQUAL,B_NOT_EQUAL,B_GREATER,B_LESS,B_GREATER_OR_EQUAL,
  424. B_LESS_OR_EQUAL,B_INSIDE,B_OUTSIDE
  425. - LowLimit: valor numèric per a la comparació (Condition) de la mesura (FilterType)
  426. - HighLimit: valor numèric per a la comparació (Condition) de la mesura (FilterType)
  427. (només té sentit per a aquelles condicions que tenen dos valors
  428. (B_INSIDE, per exemple).
  429. - RESULTAT:
  430. - Deixa els blobs resultants del filtrat a destination
  431. - RESTRICCIONS:
  432. - AUTOR: Ricard Borràs
  433. - DATA DE CREACIÓ: 25-05-2005.
  434. - MODIFICACIÓ: Data. Autor. Descripció.
  435. */
  436. /**
  437. - FUNCTION: Filter
  438. - FUNCTIONALITY: Get some blobs from the class based on conditions on measures
  439. of the blobs.
  440. - PARAMETERS:
  441. - dst: where to store the selected blobs
  442. - filterAction: B_INCLUDE: include the blobs which pass the filter in the result
  443. B_EXCLUDE: exclude the blobs which pass the filter in the result
  444. - evaluador: Object to evaluate the blob
  445. - Condition: How to decide if the result returned by evaluador on each blob
  446. is included or not. It can be:
  447. B_EQUAL,B_NOT_EQUAL,B_GREATER,B_LESS,B_GREATER_OR_EQUAL,
  448. B_LESS_OR_EQUAL,B_INSIDE,B_OUTSIDE
  449. - LowLimit: numerical value to evaluate the Condition on evaluador(blob)
  450. - HighLimit: numerical value to evaluate the Condition on evaluador(blob).
  451. Only useful for B_INSIDE and B_OUTSIDE
  452. - RESULT:
  453. - It returns on dst the blobs that accomplish (B_INCLUDE) or discards (B_EXCLUDE)
  454. the Condition on the result returned by evaluador on each blob
  455. - RESTRICTIONS:
  456. - AUTHOR: Ricard Borràs
  457. - CREATION DATE: 25-05-2005.
  458. - MODIFICATION: Date. Author. Description.
  459. */
  460. void CBlobResult::Filter(CBlobResult &dst,
  461. int filterAction,
  462. funcio_calculBlob *evaluador,
  463. int condition,
  464. double lowLimit, double highLimit /*=0*/) const
  465. {
  466. // do the job
  467. DoFilter(dst, filterAction, evaluador, condition, lowLimit, highLimit );
  468. }
  469. /**
  470. - FUNCIÓ: Filter (const version)
  471. - FUNCIONALITAT: Filtra els blobs de la classe i deixa el resultat amb només
  472. els blobs que han passat el filtre.
  473. El filtrat es basa en especificar condicions sobre un resultat dels blobs
  474. i seleccionar (o excloure) aquells blobs que no compleixen una determinada
  475. condicio
  476. - PARÀMETRES:
  477. - dst: variable per deixar els blobs filtrats
  478. - filterAction: acció de filtrat. Incloure els blobs trobats (B_INCLUDE),
  479. o excloure els blobs trobats (B_EXCLUDE)
  480. - evaluador: Funció per evaluar els blobs (qualsevol objecte derivat de COperadorBlob
  481. - Condition: tipus de condició que ha de superar la mesura (FilterType)
  482. sobre cada blob per a ser considerat.
  483. B_EQUAL,B_NOT_EQUAL,B_GREATER,B_LESS,B_GREATER_OR_EQUAL,
  484. B_LESS_OR_EQUAL,B_INSIDE,B_OUTSIDE
  485. - LowLimit: valor numèric per a la comparació (Condition) de la mesura (FilterType)
  486. - HighLimit: valor numèric per a la comparació (Condition) de la mesura (FilterType)
  487. (només té sentit per a aquelles condicions que tenen dos valors
  488. (B_INSIDE, per exemple).
  489. - RESULTAT:
  490. - Deixa els blobs resultants del filtrat a destination
  491. - RESTRICCIONS:
  492. - AUTOR: Ricard Borràs
  493. - DATA DE CREACIÓ: 25-05-2005.
  494. - MODIFICACIÓ: Data. Autor. Descripció.
  495. */
  496. /**
  497. - FUNCTION: Filter (const version)
  498. - FUNCTIONALITY: Get some blobs from the class based on conditions on measures
  499. of the blobs.
  500. - PARAMETERS:
  501. - dst: where to store the selected blobs
  502. - filterAction: B_INCLUDE: include the blobs which pass the filter in the result
  503. B_EXCLUDE: exclude the blobs which pass the filter in the result
  504. - evaluador: Object to evaluate the blob
  505. - Condition: How to decide if the result returned by evaluador on each blob
  506. is included or not. It can be:
  507. B_EQUAL,B_NOT_EQUAL,B_GREATER,B_LESS,B_GREATER_OR_EQUAL,
  508. B_LESS_OR_EQUAL,B_INSIDE,B_OUTSIDE
  509. - LowLimit: numerical value to evaluate the Condition on evaluador(blob)
  510. - HighLimit: numerical value to evaluate the Condition on evaluador(blob).
  511. Only useful for B_INSIDE and B_OUTSIDE
  512. - RESULT:
  513. - It returns on dst the blobs that accomplish (B_INCLUDE) or discards (B_EXCLUDE)
  514. the Condition on the result returned by evaluador on each blob
  515. - RESTRICTIONS:
  516. - AUTHOR: Ricard Borràs
  517. - CREATION DATE: 25-05-2005.
  518. - MODIFICATION: Date. Author. Description.
  519. */
  520. void CBlobResult::Filter(CBlobResult &dst,
  521. int filterAction,
  522. funcio_calculBlob *evaluador,
  523. int condition,
  524. double lowLimit, double highLimit /*=0*/)
  525. {
  526. int numBlobs = GetNumBlobs();
  527. // do the job
  528. DoFilter(dst, filterAction, evaluador, condition, lowLimit, highLimit );
  529. // inline operation: remove previous blobs
  530. if( &dst == this )
  531. {
  532. // esborrem els primers blobs ( que són els originals )
  533. // ja que els tindrem replicats al final si passen el filtre
  534. Blob_vector::iterator itBlobs = m_blobs.begin();
  535. for( int i = 0; i < numBlobs; i++ )
  536. {
  537. delete *itBlobs;
  538. itBlobs++;
  539. }
  540. m_blobs.erase( m_blobs.begin(), itBlobs );
  541. }
  542. }
  543. //! Does the Filter method job
  544. void CBlobResult::DoFilter(CBlobResult &dst, int filterAction, funcio_calculBlob *evaluador,
  545. int condition, double lowLimit, double highLimit/* = 0*/) const
  546. {
  547. int i, numBlobs;
  548. bool resultavaluacio;
  549. double_stl_vector avaluacioBlobs;
  550. double_stl_vector::iterator itavaluacioBlobs;
  551. if( GetNumBlobs() <= 0 ) return;
  552. if( !evaluador ) return;
  553. //avaluem els blobs amb la funció pertinent
  554. avaluacioBlobs = GetSTLResult(evaluador);
  555. itavaluacioBlobs = avaluacioBlobs.begin();
  556. numBlobs = GetNumBlobs();
  557. switch(condition)
  558. {
  559. case B_EQUAL:
  560. for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
  561. {
  562. resultavaluacio= *itavaluacioBlobs == lowLimit;
  563. if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
  564. ( !resultavaluacio && filterAction == B_EXCLUDE ))
  565. {
  566. dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
  567. }
  568. }
  569. break;
  570. case B_NOT_EQUAL:
  571. for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
  572. {
  573. resultavaluacio = *itavaluacioBlobs != lowLimit;
  574. if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
  575. ( !resultavaluacio && filterAction == B_EXCLUDE ))
  576. {
  577. dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
  578. }
  579. }
  580. break;
  581. case B_GREATER:
  582. for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
  583. {
  584. resultavaluacio= *itavaluacioBlobs > lowLimit;
  585. if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
  586. ( !resultavaluacio && filterAction == B_EXCLUDE ))
  587. {
  588. dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
  589. }
  590. }
  591. break;
  592. case B_LESS:
  593. for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
  594. {
  595. resultavaluacio= *itavaluacioBlobs < lowLimit;
  596. if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
  597. ( !resultavaluacio && filterAction == B_EXCLUDE ))
  598. {
  599. dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
  600. }
  601. }
  602. break;
  603. case B_GREATER_OR_EQUAL:
  604. for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
  605. {
  606. resultavaluacio= *itavaluacioBlobs>= lowLimit;
  607. if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
  608. ( !resultavaluacio && filterAction == B_EXCLUDE ))
  609. {
  610. dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
  611. }
  612. }
  613. break;
  614. case B_LESS_OR_EQUAL:
  615. for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
  616. {
  617. resultavaluacio= *itavaluacioBlobs <= lowLimit;
  618. if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
  619. ( !resultavaluacio && filterAction == B_EXCLUDE ))
  620. {
  621. dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
  622. }
  623. }
  624. break;
  625. case B_INSIDE:
  626. for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
  627. {
  628. resultavaluacio=( *itavaluacioBlobs >= lowLimit) && ( *itavaluacioBlobs <= highLimit);
  629. if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
  630. ( !resultavaluacio && filterAction == B_EXCLUDE ))
  631. {
  632. dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
  633. }
  634. }
  635. break;
  636. case B_OUTSIDE:
  637. for(i=0;i<numBlobs;i++, itavaluacioBlobs++)
  638. {
  639. resultavaluacio=( *itavaluacioBlobs < lowLimit) || ( *itavaluacioBlobs > highLimit);
  640. if( ( resultavaluacio && filterAction == B_INCLUDE ) ||
  641. ( !resultavaluacio && filterAction == B_EXCLUDE ))
  642. {
  643. dst.m_blobs.push_back( new CBlob( GetBlob( i ) ));
  644. }
  645. }
  646. break;
  647. }
  648. }
  649. /**
  650. - FUNCIÓ: GetBlob
  651. - FUNCIONALITAT: Retorna un blob si aquest existeix (index != -1)
  652. - PARÀMETRES:
  653. - indexblob: index del blob a retornar
  654. - RESULTAT:
  655. - RESTRICCIONS:
  656. - AUTOR: Ricard Borràs
  657. - DATA DE CREACIÓ: 25-05-2005.
  658. - MODIFICACIÓ: Data. Autor. Descripció.
  659. */
  660. /*
  661. - FUNCTION: GetBlob
  662. - FUNCTIONALITY: Gets the n-th blob (without ordering the blobs)
  663. - PARAMETERS:
  664. - indexblob: index in the blob array
  665. - RESULT:
  666. - RESTRICTIONS:
  667. - AUTHOR: Ricard Borràs
  668. - CREATION DATE: 25-05-2005.
  669. - MODIFICATION: Date. Author. Description.
  670. */
  671. CBlob CBlobResult::GetBlob(int indexblob) const
  672. {
  673. /* if( indexblob < 0 || indexblob >= GetNumBlobs() )
  674. RaiseError( EXCEPTION_BLOB_OUT_OF_BOUNDS ); */
  675. return *m_blobs[indexblob];
  676. }
  677. CBlob *CBlobResult::GetBlob(int indexblob)
  678. {
  679. /* if( indexblob < 0 || indexblob >= GetNumBlobs() )
  680. RaiseError( EXCEPTION_BLOB_OUT_OF_BOUNDS ); */
  681. return m_blobs[indexblob];
  682. }
  683. /**
  684. - FUNCIÓ: GetNthBlob
  685. - FUNCIONALITAT: Retorna l'enèssim blob segons un determinat criteri
  686. - PARÀMETRES:
  687. - criteri: criteri per ordenar els blobs (objectes derivats de COperadorBlob)
  688. - nBlob: index del blob a retornar
  689. - dst: on es retorna el resultat
  690. - RESULTAT:
  691. - retorna el blob nBlob a dst ordenant els blobs de la classe segons el criteri
  692. en ordre DESCENDENT. Per exemple, per obtenir el blob major:
  693. GetNthBlob( CBlobGetArea(), 0, blobMajor );
  694. GetNthBlob( CBlobGetArea(), 1, blobMajor ); (segon blob més gran)
  695. - RESTRICCIONS:
  696. - AUTOR: Ricard Borràs
  697. - DATA DE CREACIÓ: 25-05-2005.
  698. - MODIFICACIÓ: Data. Autor. Descripció.
  699. */
  700. /*
  701. - FUNCTION: GetNthBlob
  702. - FUNCTIONALITY: Gets the n-th blob ordering first the blobs with some criteria
  703. - PARAMETERS:
  704. - criteri: criteria to order the blob array
  705. - nBlob: index of the returned blob in the ordered blob array
  706. - dst: where to store the result
  707. - RESULT:
  708. - RESTRICTIONS:
  709. - AUTHOR: Ricard Borràs
  710. - CREATION DATE: 25-05-2005.
  711. - MODIFICATION: Date. Author. Description.
  712. */
  713. void CBlobResult::GetNthBlob( funcio_calculBlob *criteri, int nBlob, CBlob &dst ) const
  714. {
  715. // verifiquem que no estem accedint fora el vector de blobs
  716. if( nBlob < 0 || nBlob >= GetNumBlobs() )
  717. {
  718. //RaiseError( EXCEPTION_BLOB_OUT_OF_BOUNDS );
  719. dst = CBlob();
  720. return;
  721. }
  722. double_stl_vector avaluacioBlobs, avaluacioBlobsOrdenat;
  723. double valorEnessim;
  724. //avaluem els blobs amb la funció pertinent
  725. avaluacioBlobs = GetSTLResult(criteri);
  726. avaluacioBlobsOrdenat = double_stl_vector( GetNumBlobs() );
  727. // obtenim els nBlob primers resultats (en ordre descendent)
  728. std::partial_sort_copy( avaluacioBlobs.begin(),
  729. avaluacioBlobs.end(),
  730. avaluacioBlobsOrdenat.begin(),
  731. avaluacioBlobsOrdenat.end(),
  732. std::greater<double>() );
  733. valorEnessim = avaluacioBlobsOrdenat[nBlob];
  734. // busquem el primer blob que té el valor n-ssim
  735. double_stl_vector::const_iterator itAvaluacio = avaluacioBlobs.begin();
  736. bool trobatBlob = false;
  737. int indexBlob = 0;
  738. while( itAvaluacio != avaluacioBlobs.end() && !trobatBlob )
  739. {
  740. if( *itAvaluacio == valorEnessim )
  741. {
  742. trobatBlob = true;
  743. dst = CBlob( GetBlob(indexBlob));
  744. }
  745. itAvaluacio++;
  746. indexBlob++;
  747. }
  748. }
  749. /**
  750. - FUNCIÓ: ClearBlobs
  751. - FUNCIONALITAT: Elimina tots els blobs de l'objecte
  752. - PARÀMETRES:
  753. - RESULTAT:
  754. - Allibera tota la memòria dels blobs
  755. - RESTRICCIONS:
  756. - AUTOR: Ricard Borràs Navarra
  757. - DATA DE CREACIÓ: 25-05-2005.
  758. - MODIFICACIÓ: Data. Autor. Descripció.
  759. */
  760. /*
  761. - FUNCTION: ClearBlobs
  762. - FUNCTIONALITY: Clears all the blobs from the object and releases all its memory
  763. - PARAMETERS:
  764. - RESULT:
  765. - RESTRICTIONS:
  766. - AUTHOR: Ricard Borràs
  767. - CREATION DATE: 25-05-2005.
  768. - MODIFICATION: Date. Author. Description.
  769. */
  770. void CBlobResult::ClearBlobs()
  771. {
  772. Blob_vector::iterator itBlobs = m_blobs.begin();
  773. while( itBlobs != m_blobs.end() )
  774. {
  775. delete *itBlobs;
  776. itBlobs++;
  777. }
  778. m_blobs.clear();
  779. }
  780. /**
  781. - FUNCIÓ: RaiseError
  782. - FUNCIONALITAT: Funció per a notificar errors al l'usuari (en debug) i llença
  783. les excepcions
  784. - PARÀMETRES:
  785. - errorCode: codi d'error
  786. - RESULTAT:
  787. - Ensenya un missatge a l'usuari (en debug) i llença una excepció
  788. - RESTRICCIONS:
  789. - AUTOR: Ricard Borràs Navarra
  790. - DATA DE CREACIÓ: 25-05-2005.
  791. - MODIFICACIÓ: Data. Autor. Descripció.
  792. */
  793. /*
  794. - FUNCTION: RaiseError
  795. - FUNCTIONALITY: Error handling function
  796. - PARAMETERS:
  797. - errorCode: reason of the error
  798. - RESULT:
  799. - in _SHOW_ERRORS version, shows a message box with the error. In release is silent.
  800. In both cases throws an exception with the error.
  801. - RESTRICTIONS:
  802. - AUTHOR: Ricard Borràs
  803. - CREATION DATE: 25-05-2005.
  804. - MODIFICATION: Date. Author. Description.
  805. */
  806. /* void CBlobResult::RaiseError(const int errorCode) const
  807. {
  808. //! Do we need to show errors?
  809. #ifdef _SHOW_ERRORS
  810. CString msg, format = "Error en CBlobResult: %s";
  811. switch (errorCode)
  812. {
  813. case EXCEPTION_BLOB_OUT_OF_BOUNDS:
  814. msg.Format(format, "Intentant accedir a un blob no existent");
  815. break;
  816. default:
  817. msg.Format(format, "Codi d'error desconegut");
  818. break;
  819. }
  820. AfxMessageBox(msg);
  821. #endif
  822. throw errorCode;
  823. } */
  824. /**************************************************************************
  825. Auxiliars / Auxiliary functions
  826. **************************************************************************/
  827. /**
  828. - FUNCIÓ: PrintBlobs
  829. - FUNCIONALITAT: Escriu els paràmetres (àrea, perímetre, exterior, mitjana)
  830. de tots els blobs a un fitxer.
  831. - PARÀMETRES:
  832. - nom_fitxer: path complet del fitxer amb el resultat
  833. - RESULTAT:
  834. - RESTRICCIONS:
  835. - AUTOR: Ricard Borràs
  836. - DATA DE CREACIÓ: 25-05-2005.
  837. - MODIFICACIÓ: Data. Autor. Descripció.
  838. */
  839. /*
  840. - FUNCTION: PrintBlobs
  841. - FUNCTIONALITY: Prints some blob features in an ASCII file
  842. - PARAMETERS:
  843. - nom_fitxer: full path + filename to generate
  844. - RESULT:
  845. - RESTRICTIONS:
  846. - AUTHOR: Ricard Borràs
  847. - CREATION DATE: 25-05-2005.
  848. - MODIFICATION: Date. Author. Description.
  849. */
  850. void CBlobResult::PrintBlobs( char *nom_fitxer ) const
  851. {
  852. double_stl_vector area, /*perimetre,*/ exterior, compacitat, longitud,
  853. externPerimeter, perimetreConvex, perimetre;
  854. int i;
  855. FILE *fitxer_sortida;
  856. area = GetSTLResult( CBlobGetArea());
  857. perimetre = GetSTLResult( CBlobGetPerimeter());
  858. exterior = GetSTLResult( CBlobGetExterior());
  859. compacitat = GetSTLResult(CBlobGetCompactness());
  860. longitud = GetSTLResult( CBlobGetLength());
  861. externPerimeter = GetSTLResult( CBlobGetExternPerimeter());
  862. perimetreConvex = GetSTLResult( CBlobGetHullPerimeter());
  863. fitxer_sortida = fopen( nom_fitxer, "w" );
  864. for(i=0; i<GetNumBlobs(); i++)
  865. {
  866. fprintf( fitxer_sortida, "blob %d ->\t a=%7.0f\t p=%8.2f (%8.2f extern)\t pconvex=%8.2f\t ext=%.0f\t m=%7.2f\t c=%3.2f\t l=%8.2f\n",
  867. i, area[i], perimetre[i], externPerimeter[i], perimetreConvex[i], exterior[i], compacitat[i], longitud[i] );
  868. }
  869. fclose( fitxer_sortida );
  870. }