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

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