source: soft/giet_vm/applications/rosenfeld/src/ecc_features.c @ 823

Last change on this file since 823 was 822, checked in by meunier, 9 years ago

In rosenfeld:

  • Updated nrio0, nrio1, nrio2, nrio1f, nrio2f, nrio1x, nrbool1, nrbool2 and nralloc1 in the nrc2 lib in order to use macro-typed functions
  • Updated the simulation script to include performance evaluation with random images, and a script to generate graphs
  • Updated the clock.h to use 64-bit integers, which potentially breaks the printing on the giet
File size: 39.8 KB
Line 
1// ----------------------
2// --- ecc_features.c ---
3// ----------------------
4
5/*
6 * Copyright (c) 2012 - 2014, Lionel Lacassagne, All rights reserved
7 * University of Paris Sud, Laboratoire de Recherche en Informatique
8 */
9
10// Caracteristiques d'une region / label
11
12#include <stdio.h>
13#include <stddef.h>
14#include <stdlib.h>
15#include <malloc.h>
16#include <string.h>
17
18
19#include "nrc_os_config.h"
20#include "config.h"
21#include "nrc.h"
22
23
24#if TARGET_OS == LINUX
25    #include <sys/types.h>
26    #include <sys/stat.h>
27    #include <fcntl.h>
28    #include <unistd.h>
29#endif
30
31
32#include "ecc_features.h"
33
34#define BUFF_SIZE 1024 // for snprintf
35
36
37// -----------------------------------------------------
38void RegionStats_Init(RegionStats * Stats, uint32 nemax)
39// -----------------------------------------------------
40{
41    for (int i = 0; i < (int) nemax; i++) {
42#if PARMERGE
43        pthread_spin_init(&Stats[i].lock, PTHREAD_PROCESS_PRIVATE);
44#endif
45    }
46}
47
48
49// -------------------------------------------------------------
50void RegionStats_Constructor(RegionStats ** Stats, uint32 nemax)
51// -------------------------------------------------------------
52{
53    *Stats = RegionStats_pConstructor(nemax);
54}
55
56
57// -------------------------------------------------
58RegionStats * RegionStats_pConstructor(uint32 nemax)
59// -------------------------------------------------
60{
61    RegionStats * Stats;
62   
63    Stats = (RegionStats *) malloc((nemax) * sizeof(RegionStats));
64    if (Stats == NULL) {
65        nrerror("allocation failed in RegionStats_pConstructor");
66    }
67   
68    RegionStats_Init(Stats, nemax);
69   
70    return Stats;
71}
72
73
74// ------------------------------------------------------------
75void RegionStats_Destructor(RegionStats ** Stats, uint32 nemax)
76// ------------------------------------------------------------
77{
78    RegionStats_pDestructor(*Stats, nemax);
79}
80
81
82// ------------------------------------------------------------
83void RegionStats_pDestructor(RegionStats * Stats, uint32 nemax)
84// ------------------------------------------------------------
85{
86    //RegionStats_Clear(Stats, nemax);
87    free(Stats);
88}
89
90// ------------------------------------------------------
91void RegionStats_Clear(RegionStats * Stats, uint32 nemax)
92// ------------------------------------------------------
93{
94    for (int i = 0; i < (int) nemax; i++) {
95#if FEATURES
96        Stats[i].xmin = 65535;
97        Stats[i].xmax = 0;
98        Stats[i].ymin = 65535;
99        Stats[i].ymax = 0;
100       
101        Stats[i].S = 0;
102       
103        Stats[i].Sx = 0;
104        Stats[i].Sy = 0;
105#endif
106    }
107}
108
109#if FEATURES
110// -----------------------------------------
111void RegionStats_Clear1(RegionStats * stats)
112// -----------------------------------------
113{
114    stats->xmin = 0;
115    stats->xmax = 0;
116    stats->ymin = 0;
117    stats->ymax = 0;
118   
119    stats->S = 0;
120   
121    stats->Sx = 0;
122    stats->Sy = 0;
123}
124
125
126// -----------------------------------------
127int RegionStats_Create_File(char * filename)
128// -----------------------------------------
129{
130    int fd;
131   
132    fd = open(filename, O_CREAT | O_TRUNC);
133    if (fd < 0) {
134        printf("RegionStats_Open_File : can't create file %s\n", filename);
135        exit(1);
136    }
137    return fd;
138}
139
140
141// ---------------------------------------
142int RegionStats_Open_File(char * filename)
143// ---------------------------------------
144{
145    int fd;
146   
147    fd = open(filename, O_RDONLY);
148    if (fd < 0) {
149        printf("RegionStats_Open_File : can't open file %s\n", filename);
150        exit(1);
151    }
152    return fd;
153}
154
155
156// --------------------------------
157void RegionStats_Close_File(int fd)
158// --------------------------------
159{
160    close(fd);
161}
162
163
164#if 0 // pb : fscanf requires manipulating FILE *
165// --------------------------------
166int RegionStats_Read_Header(int fd)
167// --------------------------------
168{
169    int ne = 0;
170    fscanf(fd, "%d", &ne);
171    return ne;
172}
173#endif
174
175
176// ------------------------------------------
177void RegionStats_Write_Header(int ne, int fd)
178// ------------------------------------------
179{
180    char buff[BUFF_SIZE];
181    snprintf(buff, BUFF_SIZE, "%d\n", ne);
182    write(fd, buff, strlen(buff) + 1);
183}
184
185
186#if 0
187// --------------------------------------------------------------
188void RegionStats_Read_Stats1(int fd, int ne, RegionStats * Stats)
189// --------------------------------------------------------------
190{
191    int i;
192   
193    for (i = 1; i <= ne; i++) {
194        fscanf(fd, "%d%d%d%d%d%d%d%d\n",
195               &t,
196               &(Stats[i].xmin),
197               &(Stats[i].xmax),
198               &(Stats[i].ymin),
199               &(Stats[i].ymax),
200               &(Stats[i].S),
201               &(Stats[i].Sx),
202               &(Stats[i].Sy));
203    }
204}
205#endif
206
207
208// ---------------------------------------------------------------
209void RegionStats_Write_Stats1(RegionStats * Stats, int ne, int fd)
210// ---------------------------------------------------------------
211{
212    char buff[BUFF_SIZE];
213   
214    for (int i = 1; i <= ne; i++) {
215        snprintf(buff, BUFF_SIZE, "%4d %5d %5d %5d %5d %7d %8d %8d\n",
216                i,
217                Stats[i].xmin,
218                Stats[i].xmax,
219                Stats[i].ymin,
220                Stats[i].ymax,
221               
222                Stats[i].S,
223                Stats[i].Sx,
224                Stats[i].Sy);
225        write(fd, buff, strlen(buff) + 1);
226    }
227}
228
229
230// ---------------------------------------------------------------------------------------------------
231void RegionStats_Write_Stats1_Sparse(RegionStats * Stats, uint32 * EQ, uint32 ne0, uint32 ne1, int fd)
232// ---------------------------------------------------------------------------------------------------
233{
234    uint32 e;
235    char buff[BUFF_SIZE];
236   
237    for (e = ne0; e <= ne1; e++) {
238        if ((e == EQ[e]) && (Stats[e].S > 0)) {
239            snprintf(buff, BUFF_SIZE, "%4d %5d %5d %5d %5d %7d %8d %8d\n",
240                    e,
241                    Stats[e].xmin,
242                    Stats[e].xmax,
243                    Stats[e].ymin,
244                    Stats[e].ymax,
245                   
246                    Stats[e].S,
247                    Stats[e].Sx,
248                    Stats[e].Sy);
249            write(fd, buff, strlen(buff) + 1);
250        }
251    }
252}
253
254
255// -----------------------------------------------------------------
256void RegionStats_Write_pStats1(RegionStats ** Stats, int ne, int fd)
257// -----------------------------------------------------------------
258{
259    char buff[BUFF_SIZE];
260   
261    for (int i = 1; i <= ne; i++) {
262        snprintf(buff, BUFF_SIZE, "%4d %5d %5d %5d %5d %7d %8d %8d\n",
263                i,
264                Stats[i]->xmin,
265                Stats[i]->xmax,
266                Stats[i]->ymin,
267                Stats[i]->ymax,
268                Stats[i]->S,
269                Stats[i]->Sx,
270                Stats[i]->Sy);
271        write(fd, buff, strlen(buff) + 1);
272    }
273}
274
275
276#if 0
277// --------------------------------------------------------------------------
278void RegionStats_Load_Stats1(char * filename, int * ne, RegionStats ** Stats)
279// --------------------------------------------------------------------------
280{
281    int fd;
282   
283    fd = RegionStats_Open_File(filename);
284   
285    *ne = RegionStats_Read_Header(fd);
286   
287    RegionStats_Constructor(Stats, *ne);
288    RegionStats_Read_Stats1(fd, *ne, *Stats);
289    RegionStats_Close_File(fd);
290}
291
292
293// --------------------------------------------------------------------------
294void RegionStats_MLoad_Stats1(char * filename, int * ne, RegionStats * Stats)
295// --------------------------------------------------------------------------
296{
297    int fd;
298   
299    fd = RegionStats_Open_File(filename);
300   
301    *ne = RegionStats_Read_Header(fd);
302    RegionStats_Read_Stats1(fd, *ne, Stats);
303    RegionStats_Close_File(fd);
304}
305#endif
306
307// -----------------------------------------------------------------------
308void RegionStats_Save_Stats1(RegionStats * Stats, int ne, char * filename)
309// -----------------------------------------------------------------------
310{
311    int fd;
312   
313    fd = RegionStats_Create_File(filename);
314   
315    RegionStats_Write_Header(ne, fd);
316    RegionStats_Write_Stats1(Stats, ne, fd);
317    RegionStats_Close_File(fd);
318}
319
320
321// -------------------------------------------------------------------------
322void RegionStats_Save_pStats1(RegionStats ** Stats, int ne, char * filename)
323// -------------------------------------------------------------------------
324{
325    int fd;
326   
327    fd = RegionStats_Create_File(filename);
328   
329    RegionStats_Write_Header(ne, fd);
330    RegionStats_Write_pStats1(Stats, ne, fd);
331    RegionStats_Close_File(fd);
332}
333
334
335// ----------------------------------------------------------------------
336void RegionStats_Display_Stats1(RegionStats * Stats, int ne, char * name)
337// ----------------------------------------------------------------------
338{
339    if (name != NULL) {
340        printf("%s : %d\n", name, ne);
341    }
342    else {
343        printf("RegionStats : %d\n", ne);
344    }
345    for (int i = 1; i <= ne; i++) {
346        printf("#%3d: %4d %4d %4d %4d %6d %8d %8d\n",
347               i,
348               Stats[i].xmin,
349               Stats[i].xmax,
350               Stats[i].ymin,
351               Stats[i].ymax,
352               Stats[i].S,
353               Stats[i].Sx,
354               Stats[i].Sy);
355    }
356}
357
358
359// ------------------------------------------------------------------------
360void RegionStats_Display_pStats1(RegionStats ** Stats, int ne, char * name)
361// ------------------------------------------------------------------------
362{
363    if (name != NULL) {
364        printf("%s : %d\n", name, ne);
365    }
366    else {
367        printf("RegionStats : %d\n", ne);
368    }
369    for (int i = 1; i <= ne; i++) {
370        printf("#%3d: %4d %4d %4d %4d %6d %8d %8d\n",
371               i,
372               Stats[i]->xmin,
373               Stats[i]->xmax,
374               Stats[i]->ymin,
375               Stats[i]->ymax,
376               Stats[i]->S,
377               Stats[i]->Sx,
378               Stats[i]->Sy);
379    }
380}
381
382
383// ----------------------------------------------------------------------------------------------
384void RegionStats_SetRectangle(RegionStats * Stats, int e, int ymin, int ymax, int xmin, int xmax)
385// ----------------------------------------------------------------------------------------------
386{
387    Stats[e].ymin = ymin;
388    Stats[e].xmin = xmin;
389    Stats[e].ymax = ymax;
390    Stats[e].xmax = xmax;
391}
392
393
394// ---------------------------------------------------------
395void RegionStats_Copy1(RegionStats * src, RegionStats * dst)
396// ---------------------------------------------------------
397{
398    dst->xmin = src->xmin;
399    dst->xmax = src->xmax;
400    dst->ymin = src->ymin;
401    dst->ymax = src->ymax;
402   
403    dst->S    = src->S;
404   
405    dst->Sx   = src->Sx;
406    dst->Sy   = src->Sy;
407}
408#endif
409
410// ===============================
411// === nouvelles versions 2009 ===
412// ===============================
413
414// --------------------------------------------
415RegionStats * RegionStatsVector(int i0, int i1)
416// --------------------------------------------
417// allocate a float vector with subscript range v[i0..i1]
418{
419    RegionStats * v;
420   
421    v = (RegionStats *) malloc((size_t) ((i1 - i0 + 1 + NR_END) * sizeof(RegionStats)));
422    if (!v) {
423        nrerror("allocation failure in %s()", __func__);
424        return NULL;
425    }
426    RegionStats_Init(v, i1 - i0 + 1 + NR_END);
427    return v - i0 + NR_END;
428}
429
430
431#if TARGET_OS == GIETVM
432// -----------------------------------------------------------------
433RegionStats * remote_RegionStatsVector(int i0, int i1, int x, int y)
434// -----------------------------------------------------------------
435// allocate a float vector with subscript range v[i0..i1]
436{
437    RegionStats * v;
438   
439    v = (RegionStats *) remote_malloc((size_t) ((i1 - i0 + 1 + NR_END) * sizeof(RegionStats)), x, y);
440    if (!v) {
441        nrerror("allocation failure in %s()", __func__);
442        return NULL;
443    }
444    RegionStats_Init(v, i1 - i0 + 1 + NR_END);
445    return v - i0 + NR_END;
446}
447#endif
448
449
450// ---------------------------------------------
451RegionStats * RegionStatsVector0(int i0, int i1)
452// ---------------------------------------------
453// allocate a float vector with subscript range v[i0..i1]
454{
455    RegionStats * v;
456   
457    v = (RegionStats *) calloc((size_t) (i1 - i0 + 1 + NR_END), sizeof(RegionStats));
458    if (!v) {
459        nrerror("allocation failure in RegionStatsVector0()");
460        return NULL;
461    }
462    return v - i0 + NR_END;
463}
464
465
466// ---------------------------------------------------------
467void free_RegionStatsVector(RegionStats * v, int i0, int i1)
468// ---------------------------------------------------------
469// free a RegionStats vector allocated with vector()
470{
471    free(v + i0 - NR_END);
472}
473
474
475// -------------------------------------------------------------
476RegionStats ** RegionStatsMatrix(int i0, int i1, int j0, int j1)
477// -------------------------------------------------------------
478
479// allocate a RegionStats matrix with subscript range m[nrl..nrh][ncl..nch]
480{
481    long nrow = i1 - i0 + 1;
482    long ncol = j1 - j0 + 1;
483    RegionStats ** m;
484   
485    // allocate pointers to rows
486    m = (RegionStats **) malloc((size_t) ((nrow + NR_END) * sizeof(RegionStats *)));
487    if (!m) {
488        nrerror("allocation failure 1 in RegionStatsMatrix()");
489    }
490    m += NR_END;
491    m -= i0;
492   
493    // allocate rows and set pointers to them
494    m[i0] = (RegionStats *) malloc((size_t) ((nrow * ncol + NR_END) * sizeof(RegionStats)));
495    if (!m[i0]) {
496        nrerror("allocation failure 2 in RegionStatsMatrix()");
497    }
498    m[i0] += NR_END;
499    m[i0] -= j0;
500   
501    for (int i = i0 + 1; i <= i1; i++) {
502        m[i] = m[i - 1] + ncol;
503    }
504   
505    // return pointer to array of pointers to rows
506    return m;
507}
508
509
510// --------------------------------------------------------------
511RegionStats ** RegionStatsMatrix0(int i0, int i1, int j0, int j1)
512// --------------------------------------------------------------
513// allocate a float matrix with subscript range m[nrl..nrh][ncl..nch]
514{
515    long i;
516    long nrow = i1 - i0 + 1;
517    long ncol = j1 - j0 + 1;
518    RegionStats ** m;
519   
520    // allocate pointers to rows
521    m= (RegionStats **) malloc((size_t) ((nrow + NR_END) * sizeof(RegionStats*)));
522    if (!m) {
523        nrerror("allocation failure 1 in RegionStatsMatrix()");
524    }
525    m += NR_END;
526    m -= i0;
527   
528    // allocate rows and set pointers to them
529    m[i0] = (RegionStats *) calloc((size_t) (nrow * ncol + NR_END), sizeof(RegionStats));
530    if (!m[i0]) {
531        nrerror("allocation failure 2 in RegionStatsMatrix()");
532    }
533    m[i0] += NR_END;
534    m[i0] -= j0;
535   
536    for (i = i0 + 1; i <= i1; i++) {
537        m[i] = m[i - 1] + ncol;
538    }
539   
540    // return pointer to array of pointers to rows
541    return m;
542}
543
544
545// --------------------------------------------------------------------------
546void free_RegionStatsMatrix(RegionStats ** m, int i0, int i1, int j0, int j1)
547// --------------------------------------------------------------------------
548{
549    free(m[i0] + j0 - NR_END);
550    free(m + i0 - NR_END);
551}
552
553
554#if FEATURES
555// -----------------------------------
556void zero_RegionStats(RegionStats * x)
557// -----------------------------------
558{
559    x->xmin = 32767;
560    x->xmax = 0;
561    x->ymin = 32767;
562    x->ymax = 0;
563   
564    x->= 0;
565    x->Sx = 0;
566    x->Sy = 0;
567}
568
569
570// ---------------------------------------------------------
571void zero_RegionStatsVector(RegionStats * v, int i0, int i1)
572// ---------------------------------------------------------
573{
574    for (int i = i0; i <= i1; i++) {
575        zero_RegionStats(&v[i]);
576    }
577}
578
579
580// --------------------------------------------------------------------------
581void zero_RegionStatsMatrix(RegionStats ** m, int i0, int i1, int j0, int j1)
582// --------------------------------------------------------------------------
583{
584    for (int i = i0; i <= i1; i++) {
585        for (int j = j0; j <= j1; j++) {         
586            zero_RegionStats(&(m[i][j]));
587        }
588    }
589}
590
591
592// ---------------------------------------------------
593void display_RegionStats(RegionStats * x, char * name)
594// ---------------------------------------------------
595{
596    if (name != NULL) {
597        printf("%s : \n", name);
598    }
599 
600    printf("%4d %4d %4d %4d %6d %8d %8d\n",
601           x->xmin,
602           x->xmax,
603           x->ymin,
604           x->ymax,
605           
606           x->S,
607           x->Sx,
608           x->Sy);
609}
610
611
612// ------------------------------------------------------------------------
613void display_RegionStatsVector(RegionStats * v, int i0, int i1, char *name)
614// ------------------------------------------------------------------------
615{
616    if (name != NULL) {
617        printf("%s : [%d..%d]\n", name, i0, i1);
618    }
619    else {
620        printf("RegionStats : [%d..%d]\n", i0, i1);
621    }
622    for (int i = i0; i <= i1; i++) {
623        printf("#%3d: ", i);
624        display_RegionStats(&(v[i]), NULL);
625    }
626}
627
628
629// ------------------------------------------------------------------------------------------
630void display_RegionStatsMatrix(RegionStats ** m, int i0, int i1, int j0, int j1, char * name)
631// ------------------------------------------------------------------------------------------
632{
633   
634    if (name != NULL) {
635        printf("%s : [%d..%d][%d..%d]\n", name, i0, i1, j0, j1);
636    }
637    else {
638        printf("RegionStats : [%d..%d][%d..%d]\n", i0, i1, j0, j1);
639    }
640    for (int i = i0; i <= i1; i++) {
641        for (int j = j0; j <= j1; j++) {
642            printf("#%3d: ", i);
643            display_RegionStats(&(m[i][j]), NULL);
644        }
645    }
646}
647
648
649// ------------------------------------------------
650void save_RegionStats(RegionStats * x, char * name)
651// ------------------------------------------------
652{
653    int fd = -1;
654    char buff[BUFF_SIZE];
655   
656    if (name == NULL) {
657        return;
658    }
659    // assume name != NULL if single element
660    // assume name == NULL if vector or matrix
661    fd = RegionStats_Create_File(name);
662    if (fd <= 0) {
663        printf("*** Erreur : ouverture du fichier %s dans %s\n", name, __func__);
664    }
665    snprintf(buff, BUFF_SIZE, "%s: %4d %4d %4d %4d %6d %8d %8d\n",
666            name,
667            x->xmin,
668            x->xmax,
669            x->ymin,
670            x->ymax,
671           
672            x->S,
673            x->Sx,
674            x->Sy);
675    write(fd, buff, strlen(buff) + 1);
676   
677    if (name) {
678        RegionStats_Close_File(fd);
679    }   
680}
681
682
683// ----------------------------------------------------------------------
684void save_RegionStatsVector(RegionStats * v, int i0, int i1, char * name)
685// ----------------------------------------------------------------------
686{
687    int fd;
688    char buff[BUFF_SIZE];
689   
690    if (name == NULL) {
691        name = "RegionStatsVector";
692    }
693    fd = RegionStats_Create_File(name);
694   
695    snprintf(buff, BUFF_SIZE, "%s : [%d..%d]\n", name, i0, i1);
696    write(fd, buff, strlen(buff) + 1);
697   
698    for (int i = i0; i <= i1; i++) {
699        printf("#%3d: ", i);
700        save_RegionStats(&v[i], NULL);
701    }
702    RegionStats_Close_File(fd);
703}
704
705
706// ---------------------------------------------------------------------------------------
707void save_RegionStatsMatrix(RegionStats ** m, int i0, int i1, int j0, int j1, char * name)
708// ---------------------------------------------------------------------------------------
709{
710    int fd;
711    char buff[BUFF_SIZE];
712   
713    if (name == NULL) {
714        name = "RegionStatsMatrix";
715    }
716    fd = RegionStats_Create_File(name);
717   
718    snprintf(buff, BUFF_SIZE, "%s : [%d..%d]\n", name, i0, i1);
719    write(fd, buff, strlen(buff) + 1);
720   
721    for (int i = i0; i <= i1; i++) {
722        for (int j = j0; j <= j1; j++) {
723            snprintf(buff, BUFF_SIZE, "#%3d: ", i);
724            write(fd, buff, strlen(buff) + 1);
725            save_RegionStats(&m[i][j], NULL);
726        }
727    }
728    RegionStats_Close_File(fd);
729}
730
731
732// -------------------------------------------------------------------------------
733void RegionStats_Calc1_Features_1Pass(RegionStats * Stats, uint32 e, int i, int j)
734// -------------------------------------------------------------------------------
735{
736    // calcul sur 1 point et non sur toute l'image
737        // Rectangle
738       
739    if (i < Stats[e].ymin) {
740        Stats[e].ymin = i;
741    }
742        if (i > Stats[e].ymax) {
743        Stats[e].ymax = i;
744    }
745   
746    if (j < Stats[e].xmin) {
747        Stats[e].xmin = j;
748    }
749        if (j > Stats[e].xmax) {
750        Stats[e].xmax = j;     
751    }
752   
753        // Moment1
754        Stats[e].+= 1;
755        Stats[e].Sx += j;
756        Stats[e].Sy += i;
757       
758        return;
759}
760
761
762// --------------------------------
763// --- fonctions de 2013 ----------
764// --------------------------------
765// ---------------------------------------------------------------------------------------------
766void RegionStats_Calc_Rectangle_Moment1(uint32 ** E, int height, int width, RegionStats * Stats)
767// ---------------------------------------------------------------------------------------------
768{
769    uint32 x, y;
770    uint32 e;
771   
772    for (int i = 0; i < height; i++) {
773        for (int j = 0; j < width; j++) {
774           
775            e = E[i][j];
776            if (e) {
777                x = j;
778                y = i;
779               
780                if (i < Stats[e].ymin) {
781                    Stats[e].ymin = y;
782                }
783                if (i > Stats[e].ymax) {
784                    Stats[e].ymax = y;
785                }
786               
787                if (j < Stats[e].xmin) {
788                    Stats[e].xmin = x;
789                }
790                if (j > Stats[e].xmax) {
791                    Stats[e].xmax = x;
792                }
793               
794                Stats[e].+= 1;
795                Stats[e].Sx += x;
796                Stats[e].Sy += y;
797            }
798        }
799    }
800}
801
802
803// -------------------------------------------------------------------------------------------------------------------------------
804void RegionStats_calc_Status(RegionStats * Stats, uint32 ne, uint32 min_height, uint32 min_width, uint32 min_area, uint8 * status)
805// -------------------------------------------------------------------------------------------------------------------------------
806{
807    uint16 xmin, xmax, ymin, ymax, xsize, ysize;
808    uint32 size;
809    uint32 e;
810   
811    for (e = 1; e < ne; e++) {
812       
813        ymin = Stats[e].ymin;
814        ymax = Stats[e].ymax;
815       
816        xmin = Stats[e].xmin;
817        xmax = Stats[e].xmax;
818       
819        ysize = ymax - ymin + 1;
820        xsize = xmax - xmin + 1;
821        size = xsize * ysize;
822       
823        if ((size > min_area) && (xsize >= min_width) && (ysize >= min_height)) {
824            status[e] = 1;
825        }
826        else {
827            status[e] = 0;
828        }
829    }
830}
831
832
833// ----------------------------------------------------------------------------
834uint32 RegionStats_UpdateEQ_with_Status(uint8 * status, uint32 ne, uint32 * EQ)
835// ----------------------------------------------------------------------------
836{
837    uint32 e;
838    uint32 na = 0;
839    for (e = 1; e < ne; e++) {
840        if (status[e]) {
841            EQ[e] = ++na;
842        }
843        else {
844            EQ[e] = 0;
845        }
846    }
847    return na;
848}
849
850
851// ------------------------------------------------------------------------------
852void RegionStats_UpdateStats_with_EQ(uint32 * EQ, uint32 ne, RegionStats * Stats)
853// ------------------------------------------------------------------------------
854{
855    uint32 e, a;
856    for (e = 1; e < ne; e++) {
857        a = EQ[e];
858        if (a != e) {
859            // copy
860            RegionStats_Copy1(&Stats[e], &Stats[a]);
861        }
862        else {
863            // do nothing
864        }
865    }
866}
867
868
869// -----------------------------------------------------------------------------
870void featuresComputation(uint32 ** E, int height,int width, RegionStats * Stats)
871// -----------------------------------------------------------------------------
872{
873    //uint32 nemax = height * width /2;   
874    RegionStats_Calc_Rectangle_Moment1(E, height, width, Stats);   
875}
876
877
878// ---------------------------------------------------------------------------
879void pointFeaturesComputation( uint32 ** E, int i, int j, RegionStats * Stats)
880// ---------------------------------------------------------------------------
881{
882    uint32 x, y;
883    uint32 e;
884   
885    e = E[i][j];
886    if (e) {
887       
888        x = j;
889        y = i;
890       
891        if (i < Stats[e].ymin) {
892            Stats[e].ymin = y;
893        }
894        if (i > Stats[e].ymax) {
895            Stats[e].ymax = y;
896        }
897       
898        if (j < Stats[e].xmin) {
899            Stats[e].xmin = x;
900        }
901        if (j > Stats[e].xmax) {
902            Stats[e].xmax = x;
903        }
904       
905        Stats[e].+= 1;
906        Stats[e].Sx += x;
907        Stats[e].Sy += y;
908    }
909}
910
911
912// -----------------------------------------------------------------------------
913void lineFeaturesComputation(uint32 ** E, int i, int width, RegionStats * Stats)
914// -----------------------------------------------------------------------------
915{
916    // line RegionStats_Calc_Rectangle_Moment1
917   
918    uint32 x, y;
919    uint32 e;
920   
921    for (int j = 0; j < width; j++) {
922       
923        e = E[i][j];
924        if (e) {
925           
926            x = j;
927            y = i;
928           
929            if (i < Stats[e].ymin) {
930                Stats[e].ymin = y;
931            }
932            if (i > Stats[e].ymax) {
933                Stats[e].ymax = y;
934            }
935           
936            if (j < Stats[e].xmin) {
937                Stats[e].xmin = x;
938            }
939            if (j > Stats[e].xmax) {
940                Stats[e].xmax = x;
941            }
942           
943            Stats[e].+= 1;
944            Stats[e].Sx += x;
945            Stats[e].Sy += y;
946        }
947    }
948}
949
950
951// --------------------------------------------------------------------------------------
952void bandFeaturesComputation(uint32 ** E, int i0, int i1, int width, RegionStats * Stats)
953// --------------------------------------------------------------------------------------
954{
955    for (int i = i0; i <= i1; i++) {
956        lineFeaturesComputation(E, i, width, Stats);
957    }
958}
959
960
961// -----------------------------------------------------------------------------------
962void imageFeaturesComputation(uint32 ** E, int height, int width, RegionStats * Stats)
963// -----------------------------------------------------------------------------------
964{
965    // image RegionStats_Calc_Rectangle_Moment1
966    for (int i = 0; i < height; i++) {
967        lineFeaturesComputation(E, i, width, Stats);
968    }
969}
970
971
972// ---------------------------------------
973// --- Fonctions 2014 --------------------
974// ---------------------------------------
975
976// ---------------------------------------------------------------------------------------
977void RegionStats_Copy_Stats1_From_Index(RegionStats * Stats, int dst_index, int src_index)
978// ---------------------------------------------------------------------------------------                                 
979{
980    // R[dst] = R[src]
981    RegionStats_Copy1(&Stats[src_index], &Stats[dst_index]);
982}
983
984
985// ---------------------------------------------------------------------------------------------
986void RegionStats_Accumulate_Stats1_From_Index(RegionStats * Stats, int dst_index, int src_index)
987// ---------------------------------------------------------------------------------------------                                 
988{
989    // R[dst] += R[src]
990    Stats[dst_index].xmin = ui16min2(Stats[dst_index].xmin, Stats[src_index].xmin);
991    Stats[dst_index].xmax = ui16max2(Stats[dst_index].xmax, Stats[src_index].xmax);
992    Stats[dst_index].ymin = ui16min2(Stats[dst_index].ymin, Stats[src_index].ymin);
993    Stats[dst_index].ymax = ui16max2(Stats[dst_index].ymax, Stats[src_index].ymax);
994   
995    Stats[dst_index].+= Stats[src_index].S;
996    Stats[dst_index].Sx += Stats[src_index].Sx;
997    Stats[dst_index].Sy += Stats[src_index].Sy;   
998}
999
1000
1001// ---------------------------------------------------------------------------------------------------------------------------
1002void RegionStats_DisplayStats_Sparse(uint32 * EQ, uint32 ne0, uint32 ne1, RegionStats * Stats, char * name, int * start_index)
1003// ---------------------------------------------------------------------------------------------------------------------------
1004{
1005    // n'affiche que les racines.
1006    // ne pas utiliser apres un pack, car le test n'a plus de sens
1007    uint32 e;
1008    uint32 na; // compteur
1009   
1010    if (name) {
1011        printf(name);
1012    }
1013   
1014    //na = RegionStats_Count_Roots_Sparse(Stats, EQ, ne0, ne1);
1015    //printf("%d\n", na);
1016   
1017    for (e = ne0; e <= ne1; e++) {
1018        if (e == EQ[e] && Stats[e].S > 0) {
1019            if (start_index != NULL) {
1020                printf("%5d ", *start_index);
1021                *start_index = *start_index + 1;
1022            }
1023            else {
1024                printf("%5d ", e);
1025            }
1026            display_RegionStats(&Stats[e], NULL);
1027        }
1028    }
1029}
1030
1031
1032// -------------------------------------------------------------------------------------------------------
1033void RegionStats_DisplayStats_Range(uint32 * EQ, uint32 ne0, uint32 ne1, RegionStats * Stats, char * name)
1034// -------------------------------------------------------------------------------------------------------
1035{
1036    // affichage dense (apres un pack)
1037
1038    uint32 e;
1039   
1040    if (name) {
1041        printf(name);
1042    }
1043   
1044    for (e = ne0; e <= ne1; e++) {
1045        printf("%5d ", e);
1046        display_RegionStats(&Stats[e], NULL);
1047    }
1048}
1049
1050
1051// -----------------------------------------------------------------------------------------------------------
1052void RegionStats_Save_Stats1_Sparse(RegionStats * Stats, uint32 * EQ, uint32 ne0, uint32 ne1, char * filename)
1053// -----------------------------------------------------------------------------------------------------------
1054{
1055    int fd;
1056    uint32 na = 0;
1057   
1058    fd = RegionStats_Create_File(filename);
1059    na = RegionStats_Count_Roots_Sparse(Stats, EQ, ne0, ne1);
1060   
1061    RegionStats_Write_Header(na, fd);
1062    RegionStats_Write_Stats1_Sparse(Stats, EQ, ne0, ne1, fd);
1063    RegionStats_Close_File(fd);
1064}
1065
1066
1067// --------------------------------------------------------------------------------------------
1068uint32 RegionStats_Count_Roots_Sparse(RegionStats * Stats, uint32 * EQ, uint32 ne0, uint32 ne1)
1069// --------------------------------------------------------------------------------------------
1070{
1071    uint32 e, c = 0; // compteur
1072   
1073    for (e = ne0; e <= ne1; e++) {
1074        if ((e == EQ[e]) && (Stats[e].S > 0)) {
1075            c++;
1076        }
1077    }
1078    return c;
1079}
1080
1081
1082// -----------------------------------------------------------------------------------
1083uint32 RegionStats_Count_Roots_Sparse1(RegionStats * Stats, uint32 * EQ, uint32 nemax)
1084// -----------------------------------------------------------------------------------
1085{
1086    return RegionStats_Count_Roots_Sparse(Stats, EQ, 1, nemax);
1087}
1088
1089
1090// ---------------------------------------------------------------------------------------------
1091uint32 RegionStats_Count_Labels_Sparse(RegionStats * Stats, uint32 * EQ, uint32 ne0, uint32 ne1)
1092// ---------------------------------------------------------------------------------------------
1093{
1094    uint32 e, c = 0; // compteur
1095   
1096    for (e = ne0; e <= ne1; e++) {
1097        if (Stats[e].S > 0) {
1098            c++;
1099        }
1100    }
1101    return c;
1102}
1103
1104
1105// ------------------------------------------------------------------------------------
1106uint32 RegionStats_Count_Labels_Sparse1(RegionStats * Stats, uint32 * EQ, uint32 nemax)
1107// ------------------------------------------------------------------------------------
1108{
1109    return RegionStats_Count_Labels_Sparse(Stats, EQ, 1, nemax);
1110}
1111
1112
1113// -----------------------------------------------------------------------
1114void copy_features_ui32matrix(RegionStats * Stats, uint32 ne, uint32 ** m)
1115// -----------------------------------------------------------------------
1116{
1117    for (int i = 0; i <= (int) ne; i++) {
1118       
1119        m[i][0] = i;
1120       
1121        // 16 bits: clean but requires 2 sorts
1122        //m[i][1] = Stats[i].xmin;
1123        //m[i][2] = Stats[i].xmax;
1124        //m[i][3] = Stats[i].ymin;
1125        //m[i][4] = Stats[i].ymax;
1126       
1127        // 32 bits: dirty, but requires only 1 sort
1128        m[i][1] = (Stats[i].ymin << 16) | Stats[i].ymax;
1129        m[i][2] = (Stats[i].xmin << 16) | Stats[i].xmax;
1130
1131        // 32 bits
1132        m[i][3] = Stats[i].S;
1133        m[i][4] = Stats[i].Sx;
1134        m[i][5] = Stats[i].Sy;
1135    }
1136}
1137
1138
1139// -----------------------------------------------------------------------
1140void copy_ui32matrix_features(uint32 ** m, uint32 ne, RegionStats * Stats)
1141// -----------------------------------------------------------------------
1142{
1143    for (int i = 0; i <= (int) ne; i++) {
1144       
1145        Stats[i].xmin = m[i][2] >> 16;
1146        Stats[i].xmax = m[i][2] & 0xffff;
1147        Stats[i].ymin = m[i][1] >> 16;
1148        Stats[i].ymax = m[i][1] & 0xffff;
1149       
1150        Stats[i].= m[i][3];
1151        Stats[i].Sx = m[i][4];
1152        Stats[i].Sy = m[i][5];
1153    }
1154}
1155
1156
1157// ----------------------------------------------------------------------------
1158void sortv_ui32matrix_col(uint32 ** m, int i0, int i1, int j0, int j1, int col)
1159// ----------------------------------------------------------------------------
1160{
1161    // nrsort2 for NRC2
1162    //sortv_ui32matrix_selection_min(m, i0, i1, j0, j1,  col);
1163   
1164    long nrl = i0;
1165    long nrh = i1;
1166    long nc  = col;
1167   
1168    /*
1169     * sort an matrix of int, with the selection algorithm.
1170     * the key is in column nc
1171     * the sort is performed, by doing a purmutation on the lines,
1172     * instead of copying the lines.
1173     */
1174       
1175    uint32 x, min, pos;
1176        uint32 * ptr;
1177       
1178        for (int i = nrl; i < nrh; i++) {
1179                min = m[i][nc];
1180                pos = i;
1181                for (int j = i + 1; j <= nrh; j++) {
1182                        x = m[j][nc];
1183                        if (x < min) {
1184                                min = x;
1185                                pos = j;
1186                        }
1187                } // j
1188               
1189                // permutation des pointeurs de ligne de la matrice
1190                ptr    = m[i];
1191                m[i]   = m[pos];
1192                m[pos] = ptr;
1193        } // i
1194}
1195
1196
1197// -------------------------------------------------------------
1198void RegionStats_SortFeatures(RegionStats * Stats, uint32 nemax)
1199// -------------------------------------------------------------
1200{
1201    uint32 ** m = NULL;
1202   
1203    m = ui32matrix(0, nemax, 0, 7);
1204   
1205    copy_features_ui32matrix(Stats, nemax, m);
1206    sortv_ui32matrix_col(m, 0, nemax, 0, 5, 1);
1207    copy_ui32matrix_features(m, nemax, Stats);
1208}
1209
1210
1211// --------------------------------------------------------------------------------
1212void calc_xmin(uint32 ** restrict E, int height, int width, uint16 * restrict Xmin)
1213// --------------------------------------------------------------------------------
1214{
1215    uint32 x;
1216    uint32 e;
1217    for (int i = 0; i < height; i++) {
1218        for (int j = 0; j < width; j++) {
1219            e = E[i][j];
1220            if (e) {
1221                x = j;
1222                if (x < Xmin[e]) {
1223                    Xmin[e] = x;
1224                }
1225            }
1226        }
1227    }
1228}
1229
1230
1231// --------------------------------------------------------------------------------
1232void calc_xmax(uint32 ** restrict E, int height, int width, uint16 * restrict Xmax)
1233// --------------------------------------------------------------------------------
1234{
1235    uint32 x;
1236    uint32 e;
1237    for (int i = 0; i < height; i++) {
1238        for (int j = 0; j < width; j++) {
1239            e = E[i][j];
1240            if (e) {
1241                x = j;
1242                if (x > Xmax[e]) Xmax[e] = x;
1243            }
1244        }
1245    }
1246}
1247
1248
1249// --------------------------------------------------------------------------------
1250void calc_ymin(uint32 ** restrict E, int height, int width, uint16 * restrict Ymin)
1251// --------------------------------------------------------------------------------
1252{
1253    uint32 y;
1254    uint32 e;
1255    for (int i = 0; i < height; i++) {
1256        for (int j = 0; j < width; j++) {
1257            e = E[i][j];
1258            if (e) {
1259                y = i;
1260                if (y < Ymin[e]) {
1261                    Ymin[e] = y;
1262                }
1263            }
1264        }
1265    }
1266}
1267
1268
1269// --------------------------------------------------------------------------------
1270void calc_ymax(uint32 ** restrict E, int height, int width, uint16 * restrict Ymax)
1271// --------------------------------------------------------------------------------
1272{
1273    uint32 y;
1274    uint32 e;
1275    for (int i = 0; i < height; i++) {
1276        for (int j = 0; j < width; j++) {
1277            e = E[i][j];
1278            if (e) {
1279                y = i;
1280                if (y > Ymax[e]) {
1281                    Ymax[e] = y;
1282                }
1283            }
1284        }
1285    }
1286}
1287
1288
1289// --------------------------------------------------------------------------
1290void calc_s(uint32 ** restrict E, int height, int width, uint32 * restrict S)
1291// --------------------------------------------------------------------------
1292{
1293    uint32 e;
1294    for (int i = 0; i < height; i++) {
1295        for (int j = 0; j < width; j++) {
1296            e = E[i][j];
1297            if (e) {
1298                S[e] += 1;
1299            }
1300        }
1301    }
1302}
1303
1304
1305// ----------------------------------------------------------------------------
1306void calc_sx(uint32 ** restrict E, int height, int width, uint32 * restrict Sx)
1307// ----------------------------------------------------------------------------
1308{
1309    uint32 e;
1310    for (int i = 0; i < height; i++) {
1311        for (int j = 0; j < width; j++) {
1312            e = E[i][j];
1313            if (e) {
1314                Sx[e] += j;
1315            }
1316        }
1317    }
1318}
1319
1320
1321// ----------------------------------------------------------------------------
1322void calc_sy(uint32 ** restrict E, int height, int width, uint32 * restrict Sy)
1323// ----------------------------------------------------------------------------
1324{
1325    uint32 e;
1326    for (int i = 0; i < height; i++) {
1327        for (int j = 0; j < width; j++) {
1328            e = E[i][j];
1329            if (e) {
1330                Sy[e] += i;
1331            }
1332        }
1333    }
1334}
1335
1336
1337// --------------------------------------------------------
1338int RegionStats_Compare(RegionStats * S1, RegionStats * S2)
1339// --------------------------------------------------------
1340{
1341    //puts("----------------------------------------");
1342    //display_RegionStats(S1, "S1");
1343    //display_RegionStats(S2, "S2");
1344    if ((S1->xmin == S2->xmin) &&
1345       (S1->xmax == S2->xmax) &&
1346       (S1->ymin == S2->ymin) &&
1347       (S1->ymax == S2->ymax) &&
1348       (S1->== S2->S) &&
1349       (S1->Sx == S2->Sx) &&
1350       (S1->Sy == S2->Sy)) {
1351        return 1;
1352    }
1353    else {
1354        return 0;
1355    }
1356}
1357
1358
1359// ------------------------------------------------------------------------------
1360int RegionStatsVector_Compare(RegionStats * S1, int i0, int i1, RegionStats * S2)
1361// ------------------------------------------------------------------------------
1362{
1363    int c; // resultat de la comparaison 0 = identique, 1 = different
1364    int s = 0; // somme
1365   
1366    for (int i = i0; i <= i1; i++) {
1367        c = RegionStats_Compare(&S1[i], &S2[i]);
1368        s += c;
1369    }
1370    return s;
1371}
1372
1373
1374// --------------------------------------------------------------------------------------------
1375int RegionStatsVector_Match(RegionStats * S1, int i0, int i1, RegionStats * S2, int j0, int j1)
1376// --------------------------------------------------------------------------------------------
1377{
1378    int j, pos;
1379    int c; // resultat de la comparaison 1 = identique, 0 = different
1380    int a; // accumulateur de c
1381    int s = 0; // somme
1382    int perm = 0; // permutation de numero de features
1383    int n1 = i1 - i0 + 1;
1384    int n2 = j1 - j0 + 1;
1385   
1386    //printf("[RegionStatsVector_Match]: [%d..%d]=%d vs [%d..%d]=%d\n", i0, i1, n1, j0,j1,n2);
1387    if (n1 != n2) {
1388        printf("card(S1) = %d neq card(S2) = %d  ", n1, n2);
1389        return 1;
1390    }
1391   
1392    for (int i = i0; i <= i1; i++) {
1393        a   =  0;
1394        pos = -1;
1395       
1396        for (j = j0; j <= j1; j++) {
1397            c = RegionStats_Compare(&S1[i], &S2[j]);
1398            a = a + c;
1399            if (c) {
1400                pos = j;
1401            }
1402        }
1403        s += a;
1404       
1405        if (a > 1) {
1406            printf("erreur: il y a plusieurs fois la composante S1[%d] dans S2\n", i);
1407            for (j = j0; j <= j1; j++) {
1408                c = RegionStats_Compare(&S1[i], &S2[j]);
1409                if (c) {
1410                    printf("S2[%d] ", j);
1411                }
1412            }
1413            printf("\n");
1414            exit(1);
1415        }
1416       
1417        if (i != pos) {
1418            //printf("perm(%d,%d)", i, pos);
1419            perm++;
1420        }
1421        if (a) {
1422            //printf("S1[%d] = S2[%d]\n", i, pos);
1423        }
1424        else {
1425            //printf("S1[%d] not matched\n", i);
1426        }
1427       
1428    }
1429    //printf("%4d", n1 - s); // le nb d'erreur
1430    printf("perm = %d  ", perm);
1431    return n1 - s;
1432}
1433#endif // FEATURES
1434
1435// Local Variables:
1436// tab-width: 4
1437// c-basic-offset: 4
1438// c-file-offsets:((innamespace . 0)(inline-open . 0))
1439// indent-tabs-mode: nil
1440// End:
1441
1442// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
1443
Note: See TracBrowser for help on using the repository browser.