img.cpp 17 KB

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