imgbase.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937
  1. //////////////////////////////////////////////////////////
  2. // imgBase.cpp : basic image processing functions
  3. //////////////////////////////////////////////////////////
  4. #include "img.h"
  5. #include "math.h"
  6. #include <fstream>
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. int blob_ord2(const void *, const void *);
  11. // Function : img
  12. // Description : Object constructor
  13. // Creation date : 08/04
  14. // Author : CJ
  15. // Inputs :
  16. // Outputs :
  17. img::img()
  18. {
  19. dimh = 256;
  20. dimv = 256;
  21. nbpix = dimh * dimv;
  22. itype = TYPE_UCHAR;
  23. init = 0;
  24. }
  25. // Function : ~img
  26. // Description : Object destructor
  27. // Creation date : 08/04
  28. // Author : CJ
  29. // Inputs :
  30. // Outputs :
  31. img::~img()
  32. {
  33. if ((data != 0) && (init == 1))
  34. {
  35. delete [] ((unsigned char *)data);
  36. }
  37. init = 0;
  38. }
  39. // Function : Del
  40. // Description : Free the image data
  41. // Creation date : 08/04
  42. // Author : CJ
  43. // Inputs :
  44. // Outputs :
  45. void img::Del()
  46. {
  47. if ((data != 0) && (init == 1))
  48. {
  49. delete [] ((unsigned char *)data);
  50. }
  51. init = 0;
  52. }
  53. // Function : Create
  54. // Description : Allocate the pixel data for the image
  55. // Creation date : 08/04
  56. // Author : CJ
  57. // Inputs :
  58. // Outputs : Return 1 if OK, 0 if default
  59. int img::Create(int it, int dh , int dv)
  60. {
  61. itype = it;
  62. dimh = dh;
  63. dimv = dv;
  64. nbpix = dimh * dimv;
  65. if (init == 0)
  66. {
  67. // Image 8 bits unsigned
  68. if (itype == TYPE_UCHAR)
  69. {
  70. data = (unsigned char *) new unsigned char[nbpix];
  71. }
  72. // Image 8 bits signed
  73. else if (itype == TYPE_SCHAR)
  74. {
  75. data = (char *) new char[nbpix];
  76. }
  77. // Image 16 bits unsigned
  78. else if (itype == TYPE_USHORT)
  79. {
  80. data = (unsigned short int *) new unsigned short[nbpix];
  81. }
  82. // Image 16 bits signed
  83. else if (itype == TYPE_SSHORT)
  84. {
  85. data = (short int*) new short int[nbpix];
  86. }
  87. // Image 32 bits of int
  88. else if (itype == TYPE_INT)
  89. {
  90. data = (int *) new int[nbpix];
  91. }
  92. // Image 64 bits unsigned
  93. else if (itype == TYPE_ULINT)
  94. {
  95. data = (unsigned long int *) new unsigned long int[nbpix];
  96. }
  97. // Image 32 bits of floats
  98. else if (itype == TYPE_FLOAT)
  99. {
  100. data = (float *) new float [nbpix];
  101. }
  102. // Image of doubles
  103. else if (itype == TYPE_DOUBLE)
  104. {
  105. data = (double *) new double[nbpix];
  106. }
  107. }
  108. // Allocation problem
  109. if (data == 0)
  110. {
  111. init = 0;
  112. }
  113. else
  114. {
  115. init = 1;
  116. }
  117. return init;
  118. }
  119. // Function : copyto
  120. // Description : Copy the current image to the image img2 (Image may have different types)
  121. // Creation date : 08/04
  122. // Author : CJ
  123. // Inputs :
  124. // Outputs :
  125. void img::CopyTo(img *img2)
  126. {
  127. if (itype == TYPE_UCHAR)
  128. {
  129. unsigned char *cadd;
  130. cadd = (unsigned char *) data;
  131. if (img2->itype == TYPE_UCHAR)
  132. {
  133. unsigned char *cadd2, *vcadd;
  134. cadd2 = (unsigned char *) img2->data;
  135. vcadd = (unsigned char *) memcpy(cadd2, cadd, (size_t) (nbpix * sizeof(unsigned char)));
  136. }
  137. else if (img2->itype == TYPE_USHORT)
  138. {
  139. unsigned short *sadd, *smax;
  140. sadd = (unsigned short *) img2->data;
  141. smax = sadd + img2->nbpix;
  142. while (sadd < smax)
  143. {
  144. *sadd = *cadd;
  145. cadd++;
  146. sadd++;
  147. }
  148. }
  149. }
  150. else if (itype == TYPE_USHORT)
  151. {
  152. unsigned short *cadd;
  153. cadd = (unsigned short *) data;
  154. if (img2->itype == TYPE_USHORT)
  155. {
  156. unsigned short *cadd2, *vcadd;
  157. cadd2 = (unsigned short *) img2->data;
  158. vcadd = (unsigned short *) memcpy(cadd2, cadd, (size_t) (nbpix * sizeof(unsigned short)));
  159. }
  160. else if (img2->itype == TYPE_UCHAR)
  161. {
  162. unsigned short *amax;
  163. unsigned char *cadd2;
  164. cadd2 = (unsigned char *) img2->data;
  165. amax = cadd + nbpix;
  166. while (cadd < amax)
  167. {
  168. *cadd2 = (unsigned char) *cadd;
  169. cadd++;
  170. cadd2++;
  171. }
  172. }
  173. }
  174. else if (itype == TYPE_INT)
  175. {
  176. int *cadd;
  177. cadd = (int *) data;
  178. if (img2->itype == TYPE_INT)
  179. {
  180. int *cadd2, *vcadd;
  181. cadd2 = (int *) img2->data;
  182. vcadd = (int *) memcpy(cadd2, cadd, (size_t) (nbpix * sizeof(char)));
  183. }
  184. else if (img2->itype == TYPE_UCHAR)
  185. {
  186. int *amax;
  187. unsigned char *cadd2;
  188. cadd2 = (unsigned char *) img2->data;
  189. amax = cadd + nbpix;
  190. while (cadd < amax)
  191. {
  192. *cadd2 = (unsigned char) *cadd;
  193. cadd++;
  194. cadd2++;
  195. }
  196. }
  197. else if (img2->itype == TYPE_USHORT)
  198. {
  199. int *amax;
  200. unsigned short *cadd2;
  201. cadd2 = (unsigned short *) img2->data;
  202. amax = cadd + nbpix;
  203. while (cadd < amax)
  204. {
  205. *cadd2 = (unsigned short) *cadd;
  206. cadd++;
  207. cadd2++;
  208. }
  209. }
  210. }
  211. }
  212. // Function : GetValue
  213. // Description : Get the value of a pixel
  214. // Creation date : 08/04
  215. // Author : CJ
  216. // Inputs :
  217. // Outputs :
  218. int img::GetValue(int x, int y)
  219. {
  220. int ng = 0;
  221. if ((x > 0) && (y > 0) && (x < dimh) && (y < dimv))
  222. {
  223. if ( itype == TYPE_UCHAR )
  224. {
  225. unsigned char *dadd;
  226. dadd = (unsigned char *) data;
  227. dadd += x + y * dimh;
  228. ng = *dadd;
  229. }
  230. else if ( itype == TYPE_USHORT )
  231. {
  232. unsigned short *dadd;
  233. dadd = (unsigned short *) data;
  234. dadd += x + y * dimh;
  235. ng = *dadd;
  236. }
  237. else if ( itype == TYPE_INT )
  238. {
  239. int *dadd;
  240. dadd = (int *) data;
  241. dadd += x + y * dimh;
  242. ng = *dadd;
  243. }
  244. }
  245. return(ng);
  246. }
  247. // Function : SetValue
  248. // Description : Set the value of a pixel
  249. // Creation date : 08/04
  250. // Author : CJ
  251. // Inputs :
  252. // Outputs :
  253. void img::SetValue(int x, int y, int value)
  254. {
  255. if ((x > 0) && (y > 0) && (x < dimh) && (y < dimv))
  256. {
  257. if ( itype == TYPE_UCHAR )
  258. {
  259. unsigned char *dadd;
  260. dadd = (unsigned char *) data;
  261. dadd += x + y * dimh;
  262. *dadd = (unsigned char) value;
  263. }
  264. else if ( itype == TYPE_USHORT )
  265. {
  266. unsigned short *dadd;
  267. dadd = (unsigned short *) data;
  268. dadd += x + y * dimh;
  269. *dadd = (unsigned short) value;
  270. }
  271. else if ( itype == TYPE_INT )
  272. {
  273. int *dadd;
  274. dadd = (int *) data;
  275. dadd += x + y * dimh;
  276. *dadd = value;
  277. }
  278. }
  279. }
  280. // Function : Equalize
  281. // Description : histogram equalization
  282. // Creation date : 08/04
  283. // Author : CJ
  284. // Inputs :
  285. // Outputs :
  286. void img::Equalize(int ngray)
  287. {
  288. double his[SIZEHISTO];
  289. double hissom = 0.0;
  290. int i = 0;
  291. int x = 0;
  292. int y = 0;
  293. int ng1 = 0;
  294. int ng2 = 0;
  295. for (i = 0; i < SIZEHISTO; i++) his[i] = 0;
  296. // fill the histogram
  297. for (x = 0; x < dimh; x++)
  298. {
  299. for (y = 0; y < dimv ;y++)
  300. {
  301. ng1 = GetValue(x, y);
  302. if ( ng1 < SIZEHISTO )
  303. {
  304. his[ng1]++;
  305. hissom++;
  306. }
  307. }
  308. }
  309. // cumulative histogram
  310. for (i = 1; i < SIZEHISTO; i++)
  311. {
  312. his[i] += his[i-1];
  313. }
  314. // normalisation
  315. for (i = 0; i < SIZEHISTO; i++)
  316. {
  317. his[i] = his[i] / hissom;
  318. }
  319. // Equalization
  320. for (x = 0; x < dimh; x++)
  321. {
  322. for (y = 0; y < dimv; y++)
  323. {
  324. ng1 = GetValue(x, y);
  325. if ( ng1 < SIZEHISTO )
  326. {
  327. ng2 = (int) ( ( (double) ( ngray - 1.0 ) * his[ng1] ) );
  328. if ( ng2 < SIZEHISTO )
  329. {
  330. SetValue(x, y, ng2);
  331. }
  332. }
  333. }
  334. }
  335. }
  336. // Function : Fill
  337. // Description : Fill all the image with a given gray level value
  338. // Creation date : 08/04
  339. // Author : CJ
  340. // Inputs : value of the gry level
  341. // Outputs :
  342. void img::Fill(int value)
  343. {
  344. if ( itype == TYPE_UCHAR )
  345. {
  346. unsigned char *dadd, *amax;
  347. dadd = (unsigned char *) data;
  348. amax = dadd + nbpix;
  349. while ( dadd < amax )
  350. {
  351. *dadd = (unsigned char) value;
  352. dadd++;
  353. }
  354. }
  355. else if ( itype == TYPE_USHORT )
  356. {
  357. unsigned short *dadd, *amax;
  358. dadd = (unsigned short *) data;
  359. amax = dadd + nbpix;
  360. while ( dadd < amax )
  361. {
  362. *dadd = (unsigned short) value;
  363. dadd++;
  364. }
  365. }
  366. else if ( itype == TYPE_INT )
  367. {
  368. int *dadd, *amax;
  369. dadd = (int *) data;
  370. amax = dadd + nbpix;
  371. while ( dadd < amax )
  372. {
  373. *dadd = value;
  374. dadd++;
  375. }
  376. }
  377. else if (itype == TYPE_DOUBLE)
  378. {
  379. double *dadd, *amax;
  380. dadd = (double *) data;
  381. amax = dadd + nbpix;
  382. while ( dadd < amax )
  383. {
  384. *dadd = value;
  385. dadd++;
  386. }
  387. }
  388. }
  389. //-------------------------------------------------
  390. // Basic functions of the mathematical morphology
  391. //-------------------------------------------------
  392. // Function : BinaryErosion
  393. // Description : mathematical morphological : binary erosion
  394. // Creation date : 08/04
  395. // Author : CJ
  396. // Inputs :
  397. // Outputs :
  398. void img::BinaryErosion(img *res)
  399. {
  400. unsigned short *dadd0;
  401. unsigned short *dadd;
  402. unsigned short *amax;
  403. unsigned short *dadd2;
  404. int i;
  405. int x;
  406. int y;
  407. int offset[8];
  408. int dx[8];
  409. int dy[8];
  410. dx[0] = -1; dy[0] = 1;
  411. dx[1] = 0; dy[1] = 1;
  412. dx[2] = 1; dy[2] = 1;
  413. dx[3] = -1; dy[3] = 0;
  414. dx[4] = 1; dy[4] = 0;
  415. dx[5] = -1; dy[5] = -1;
  416. dx[6] = 0; dy[6] = -1;
  417. dx[7] = 1; dy[7] = -1;
  418. offset[0] = -dimh - 1;
  419. offset[1] = -dimh;
  420. offset[2] = -dimh + 1;
  421. offset[3] = -1;
  422. offset[4] = 1;
  423. offset[5] = dimh - 1;
  424. offset[6] = dimh;
  425. offset[7] = dimh + 1;
  426. CopyTo(res);
  427. dadd0 = (unsigned short *) data;
  428. dadd = dadd0;
  429. amax = dadd0 + nbpix;
  430. dadd2 = (unsigned short *) res->data;
  431. x = 0;
  432. y = dimv -1;
  433. while ( dadd < amax )
  434. {
  435. if ( *dadd == 1 )
  436. {
  437. for(i = 0; i < 8; i++)
  438. {
  439. // Overflow
  440. if ( ( ( x + dx[i] ) < 0 ) || ( ( x + dx[i] ) > ( dimh - 1 ) )
  441. || ( ( y + dy[i] ) < 0 ) || ( ( y + dy[i] ) > ( dimv - 1 ) ) )
  442. *dadd2 = 0;
  443. else {
  444. if ( *( dadd + offset[i] ) == 0 ) {
  445. *dadd2 = 0;
  446. }
  447. }
  448. }
  449. }
  450. x++;
  451. if ( x >= dimh )
  452. {
  453. x = 0;
  454. y--;
  455. }
  456. dadd++;
  457. dadd2++;
  458. }
  459. }
  460. // Function : BinaryDilatation
  461. // Description : mathematical morphological : binary dilatation
  462. // Creation date : 08/04
  463. // Author : CJ
  464. // Inputs :
  465. // Outputs :
  466. void img::BinaryDilatation(img *res)
  467. {
  468. unsigned short *dadd0;
  469. unsigned short *dadd;
  470. unsigned short *amax;
  471. unsigned short *dadd2;
  472. int x = 0;
  473. int y = 0;
  474. int i = 0;
  475. int offset[9];
  476. int dx[8];
  477. int dy[8];
  478. offset[0] = -dimh - 1;
  479. offset[1] = -dimh;
  480. offset[2] = -dimh + 1;
  481. offset[3] = -1;
  482. offset[4] = 1;
  483. offset[5] = dimh - 1;
  484. offset[6] = dimh;
  485. offset[7] = dimh + 1;
  486. offset[8] = 0;
  487. dx[0] = -1; dy[0] = 1;
  488. dx[1] = 0; dy[1] = 1;
  489. dx[2] = 1; dy[2] = 1;
  490. dx[3] = -1; dy[3] = 0;
  491. dx[4] = 1; dy[4] = 0;
  492. dx[5] = -1; dy[5] = -1;
  493. dx[6] = 0; dy[6] = -1;
  494. dx[7] = 1; dy[7] = -1;
  495. dx[8] = 0; dy[8] = 0;
  496. CopyTo(res);
  497. dadd0 = (unsigned short *) data;
  498. dadd = dadd0 + 1 + dimh;
  499. amax = dadd0 + nbpix - 1 - dimh;
  500. dadd2 = (unsigned short *) res->data;
  501. dadd2+= 1 + dimh;
  502. x = 0;
  503. y = dimv - 1;
  504. while ( dadd < amax )
  505. {
  506. for(i = 0; i < 9; i++)
  507. {
  508. // Overflow
  509. if ( ( ( x + dx[i] ) < 0 ) || ( ( x + dx[i] ) > ( dimh - 1 ) )
  510. || ( ( y + dy[i] ) < 0 ) || ( ( y + dy[i] ) > ( dimv - 1 ) ) )
  511. *dadd2 = 0;
  512. else
  513. {
  514. if ( *( dadd + offset[i] ) == 1 )
  515. {
  516. *dadd2 = 1;
  517. }
  518. }
  519. }
  520. x++;
  521. if ( x > dimh - 1 )
  522. {
  523. x = 0;
  524. y--;
  525. }
  526. dadd++;
  527. dadd2++;
  528. }
  529. }
  530. // Function : BinaryOpening
  531. // Description : mathematical morphological : binary opening
  532. // Creation date : 08/04
  533. // Author : CJ
  534. // Inputs :
  535. // Outputs :
  536. void img::BinaryOpening(img *tamp)
  537. {
  538. img tamp1;
  539. BinaryErosion(tamp);
  540. tamp1.Create(itype, dimh, dimv);
  541. tamp->CopyTo(&tamp1);
  542. tamp1.BinaryDilatation(tamp);
  543. tamp1.Del();
  544. }
  545. // Function : BinaryClosing
  546. // Description : mathematical morphological : binary closing
  547. // Creation date : 08/04
  548. // Author : CJ
  549. // Inputs :
  550. // Outputs :
  551. void img::BinaryClosing(img *tamp)
  552. {
  553. img tamp1;
  554. BinaryDilatation(tamp);
  555. tamp1.Create(itype, dimh, dimv);
  556. tamp->CopyTo(&tamp1);
  557. tamp1.BinaryErosion(tamp);
  558. tamp1.Del();
  559. }
  560. void img::RemplaceCouleur(int a, int b)
  561. {
  562. int *dadd, *amax;
  563. dadd = (int *) data;
  564. amax = dadd + nbpix;
  565. while (dadd < amax)
  566. {
  567. if (*dadd == a)
  568. {
  569. *dadd = b;
  570. }
  571. dadd++;
  572. }
  573. }
  574. // Fonction de comparaison pour la fonction de quick sort qsort
  575. int blob_ord2(const void *arg1, const void *arg2)
  576. {
  577. struct blob *bl1, *bl2;
  578. bl1 = (struct blob *) arg1;
  579. bl2 = (struct blob *) arg2;
  580. if (bl1->size == bl2->size)
  581. {
  582. return 0;
  583. }
  584. else if (bl1->size < bl2->size)
  585. {
  586. return 1;
  587. }
  588. else
  589. {
  590. return -1;
  591. }
  592. }
  593. // Function : BlobColoring
  594. // Description : Algorithme du Blob Coloring
  595. // Creation date : 05/01/2010
  596. // Author : CJ
  597. // Inputs :
  598. // Outputs : Renvoie -1 si on dépasse MAXBLOB
  599. int img::BlobColoring(blob tblob[MAXBLOB], img *img1)
  600. {
  601. int i, j, ic, lastblob, nblob, vsup, vleft;
  602. unsigned char *dadd, *amax;
  603. unsigned int *badd, *badd0, *apix, *apix2, *aleft, *asup, *bmax;
  604. int tlabel[MAXBLOB+1];
  605. // Génére une image binaire 0/1
  606. // seuillage(seuil);
  607. dadd = (unsigned char *) (data);
  608. badd0 = (unsigned int *) (img1->data);
  609. badd = badd0;
  610. amax = dadd + nbpix;
  611. while (dadd < amax)
  612. {
  613. *badd = *dadd;
  614. dadd++;
  615. badd++;
  616. }
  617. for (i = 0; i < MAXBLOB; i++)
  618. {
  619. tblob[i].bind = 0;
  620. tblob[i].used = 0;
  621. tblob[i].size = 0;
  622. tblob[i].first = 0;
  623. }
  624. for (i = 0; i < MAXBLOB+1; i++)
  625. {
  626. tlabel[i] = 0;
  627. }
  628. lastblob = 0;
  629. nblob = 0;
  630. // Point en haut à gauche
  631. apix = badd0;
  632. if (*apix != 0)
  633. {
  634. lastblob++;
  635. nblob++;
  636. *apix = lastblob;
  637. if (lastblob > MAXBLOB)
  638. {
  639. return -1;
  640. }
  641. tblob[lastblob].bind = lastblob;
  642. tblob[lastblob].used = 1;
  643. tblob[lastblob].size = 1;
  644. tblob[lastblob].first = apix;
  645. }
  646. // Première colonne
  647. for (i=1; i<dimh; i++)
  648. {
  649. aleft = apix++;
  650. if (*apix != 0)
  651. {
  652. if (*aleft == 0)
  653. {
  654. lastblob++;
  655. nblob++;
  656. *apix = lastblob;
  657. if (lastblob > MAXBLOB)
  658. {
  659. return -1;
  660. }
  661. tblob[lastblob].bind = lastblob;
  662. tblob[lastblob].used = 1;
  663. tblob[lastblob].size = 1;
  664. tblob[lastblob].first = apix;
  665. }
  666. else
  667. {
  668. *apix = *aleft;
  669. tblob[*apix].size++;
  670. }
  671. }
  672. }
  673. asup = apix - dimh;
  674. // Colonne 1 à dimv
  675. for (i = 1; i < dimv; i++)
  676. {
  677. aleft = apix++;
  678. asup++;
  679. // Première colonne
  680. if (*apix != 0)
  681. {
  682. if (*asup == 0)
  683. {
  684. lastblob++;
  685. nblob++;
  686. *apix = lastblob;
  687. if (lastblob > MAXBLOB)
  688. {
  689. return -1;
  690. }
  691. tblob[lastblob].bind = lastblob;
  692. tblob[lastblob].used = 1;
  693. tblob[lastblob].size = 1;
  694. tblob[lastblob].first = apix;
  695. }
  696. else
  697. {
  698. *apix = *asup;
  699. tblob[*apix].size++;
  700. }
  701. }
  702. // Colonne 1 à dimh
  703. for (ic = 1 ;ic < dimh ; ic++)
  704. {
  705. aleft = apix++;
  706. asup++;
  707. if (*apix != 0)
  708. {
  709. if (*aleft == 0)
  710. { // case left == 0
  711. if (*asup == 0)
  712. {
  713. lastblob++; nblob++;
  714. *apix = lastblob;
  715. if (lastblob > MAXBLOB)
  716. {
  717. return -1;
  718. }
  719. tblob[lastblob].bind = lastblob;
  720. tblob[lastblob].used = 1;
  721. tblob[lastblob].size = 1;
  722. tblob[lastblob].first = apix;
  723. }
  724. else
  725. {
  726. *apix = *asup;
  727. tblob[*apix].size++;
  728. }
  729. }
  730. else
  731. { // case left != 0
  732. *apix = *aleft;
  733. tblob[*apix].size++;
  734. if ((*asup != 0) && (*asup != *aleft))
  735. { // fusion
  736. nblob--;
  737. vsup = *asup;
  738. vleft = *aleft;
  739. if (tblob[vleft].size < tblob[vsup].size)
  740. {
  741. tblob[vsup].size += tblob[vleft].size;
  742. tblob[vleft].used = 0;
  743. apix2 = tblob[vleft].first;
  744. while (apix2 <= apix)
  745. {
  746. if (*apix2 == (unsigned int) vleft) *apix2 = (int) vsup;
  747. apix2++;
  748. }
  749. }
  750. else
  751. {
  752. tblob[vleft].size += tblob[vsup].size;
  753. tblob[vsup].used = 0;
  754. apix2 = tblob[vsup].first;
  755. while (apix2 <= apix)
  756. {
  757. if (*apix2 == (unsigned int) vsup) *apix2 = vleft;
  758. apix2++;
  759. }
  760. }
  761. }
  762. }
  763. }
  764. }
  765. }
  766. // Tri des blobs par taille
  767. qsort((char *)tblob, lastblob + 1, sizeof(blob), blob_ord2);
  768. if (nblob > MAXBLOB)
  769. {
  770. return -1;
  771. }
  772. j = 0;
  773. for (i = 0; i <= lastblob; i++)
  774. {
  775. if (tblob[i].used == 1)
  776. {
  777. tlabel[tblob[i].bind] = j++;
  778. }
  779. }
  780. // recoloriage (en tenant compte des blobs utilisés)
  781. badd = badd0;
  782. bmax = badd + nbpix;
  783. while (badd < bmax)
  784. {
  785. if ((*badd != 0) && (*badd < MAXBLOB))
  786. {
  787. *badd = 1 + tlabel[*badd];
  788. }
  789. badd++;
  790. }
  791. return (nblob);
  792. }
  793. // Renvoie la surface du blob d'indice nblob
  794. // L'image des blobs est en int
  795. long img::GetBlobSize(int nblob)
  796. {
  797. unsigned int *dadd, *amax;
  798. long sblob;
  799. sblob = 0;
  800. dadd = (unsigned int *) data;
  801. amax = dadd + nbpix;
  802. while (dadd < amax)
  803. {
  804. if (*dadd == (unsigned int) nblob)
  805. {
  806. sblob++;
  807. }
  808. dadd++;
  809. }
  810. return (sblob);
  811. }
  812. void img::SaveImgAsRaw()
  813. {
  814. std::ofstream ofs( "C:\\Img.raw", std::ios_base::out | std::ios_base::binary );
  815. if ( ofs.good() )
  816. {
  817. ofs.write( (char*) data, nbpix );
  818. ofs.close();
  819. }
  820. }