source: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/vmi/src/saliency.cpp @ 2090

Revision 2090, 7.5 KB checked in by gumbau, 17 years ago (diff)
Line 
1#include <stdio.h>
2#include <stdlib.h>
3
4#include <math.h>
5
6#include "../include/saliency.h"
7#include "../include/global.h"
8#include "../include/simplify.h"
9
10#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
11
12#define MAX_NUM_TRI 450
13
14namespace VMI
15{
16double maxSal = 0.0, minSal = 0.0;
17int alpha = 30; // 30th percentile
18int lambda = /*100*/1;
19double percentile = 0.0; // percentile
20}
21
22using namespace VMI;
23
24void VMI::computeSaliency(Mesh *mesh, GLuint **histogram, GLuint numCameras) {
25        GLuint i = 0;
26        double sal;
27
28        maxSal = minSal = computeTriangleSaliency(mesh, histogram, numCameras, 0);
29
30        mesh->triangles[0].saliency = maxSal;
31
32        for (i=1; i<mesh->numTriangles; i++) {
33
34                sal = computeTriangleSaliency(mesh, histogram, numCameras, i);
35
36                if (sal > maxSal) maxSal = sal;
37                if (sal < minSal) minSal = sal;
38
39                mesh->triangles[i].saliency = sal;
40        }
41
42        printf("\nMax Sal: %f  Min Sal: %f\n", maxSal, minSal);
43
44        percentile = computePercentile(alpha, mesh->triangles, mesh->numTriangles);
45        printf("\n%dth percentile: %f\n", alpha, percentile);
46}
47
48void updateTriangleSaliency(Mesh *mesh, GLuint **histogram, GLuint numCameras, int v) {
49        int i, t;
50
51        for(i=0; i<(int)mesh->vertices[v].numTriangles; i++) {
52
53                t = mesh->vertices[v].triangles[i];
54
55                mesh->triangles[t].saliency = computeTriangleSaliency(mesh, histogram, numCameras, t);
56        }
57}
58
59double VMI::computeTriangleSaliency(Mesh *mesh, GLuint **histogram, GLuint numCameras, GLuint k) {
60     GLuint i, l, v0, v1, v2;
61    int *triangles = NULL, n = 0;
62    double sal = 0.0;
63   
64    v0 = mesh->triangles[k].indices[0];
65    v1 = mesh->triangles[k].indices[1];
66    v2 = mesh->triangles[k].indices[2];
67   
68    /* Allocating memory */
69    triangles = (int *)malloc((mesh->vertices[v0].numTriangles +
70                               mesh->vertices[v1].numTriangles +
71                               mesh->vertices[v2].numTriangles) * sizeof(int));
72
73    for(i=0; i<mesh->vertices[v0].numTriangles; i++) {
74        l = mesh->vertices[v0].triangles[i];
75       
76        if (l != k)
77            addItem(triangles, &n, l);
78    }
79   
80    for(i=0; i<mesh->vertices[v1].numTriangles; i++) {
81        l = mesh->vertices[v1].triangles[i];
82       
83        if (l != k)
84            addItem(triangles, &n, l);
85    }
86   
87    for(i=0; i<mesh->vertices[v2].numTriangles; i++) {
88        l = mesh->vertices[v2].triangles[i];
89       
90        if (l != k)
91            addItem(triangles, &n, l);
92    }
93   
94    //printItemList(triangles, n);
95   
96    for(i=0; i<(GLuint)n; i++) {
97        //printf("\n%d %d", k, triangles[i]);
98        //sal += computeJS(histogram, numCameras, k, triangles[i]);
99                sal = MAX ( sal, computeJS(histogram, numCameras, k, triangles[i]));
100    }
101    //printf("\nT%d Sal: %f\n", k, (sal / n));
102    //getchar();
103   
104    free(triangles);
105
106    return (sal /*/ n*/);
107}
108
109double VMI::computeEdgeSaliency(Mesh *mesh, Change *c, double p) {
110    int i, t;
111    double sal, edgeSal = 0.0;
112   
113    // edge saliency
114    for(i=0; i<c->numDel; i++) {
115
116        t = c->deleted[i].id;
117
118        sal = mesh->triangles[t].saliency;
119
120        //printf("\nt%d: osal: %f\n",t, mesh->triangles[t].saliency);
121
122        // weight map derived from saliency map
123        if (sal>= p) sal *= lambda;
124
125        //printf("\nt%d: nsal: %f\n",t, sal);
126
127        edgeSal += sal;
128    }
129   
130    //printf("\ne:%d sal: %f\n",c->e, edgeSal);
131
132    //getchar();
133
134    return edgeSal;
135}
136
137void VMI::saveSaliencyMap(Mesh *mesh, char* filename) {
138    FILE *fp;
139    GLuint i;
140
141
142    if((fp= fopen(filename, "wt"))== NULL) {
143        printf("Can't open file %s\n", filename);
144        exit(1);
145    }
146
147    printf("Writing file %s\n", filename);
148
149    fprintf (fp, "%d\n", mesh->numTriangles);
150    //printf("%d\n", num);
151
152    for (i=0; i<mesh->numTriangles; i++) {
153
154        fprintf(fp, "t%d %f\n",  i, mesh->triangles[i].saliency);
155
156    }
157
158    fclose(fp);
159    printf("File writen.\n");
160}
161
162void VMI::loadSaliencyMap(Mesh *mesh, char* filename) {
163    FILE *fp;
164    unsigned int i, num;
165    float s;
166
167
168    if((fp= fopen(filename, "rt"))== NULL) {
169        printf("Can't open file %s\n", filename);
170                                getchar();
171                                exit(1);
172    }
173
174    printf("Reading file %s\n", filename);
175
176    maxSal = minSal = 0.0;
177
178    // Reading number of triangles
179    fscanf (fp, "%d\n", &num);
180    //printf("%d\n", num);
181
182    while (!feof(fp)) {
183
184        fscanf(fp, "t%d %f\n",  &i, &s);
185
186        if (s > maxSal) maxSal = s;
187        if (s < minSal) minSal = s;
188
189        // Save the saliency into the triangle i
190        mesh->triangles[i].saliency = s;
191
192    }
193
194    fclose(fp);
195    printf("File read.\n");
196
197    printf("\nMax Sal: %f  Min Sal: %f\n", maxSal, minSal);
198
199    percentile = computePercentile(alpha, mesh->triangles, mesh->numTriangles);
200    printf("\n%dth percentile: %f\n", alpha, percentile);
201}
202
203void VMI::viewSaliency(Mesh *mesh, Camera *cameras, int cam) {
204    GLuint i, v1, v2, v3;
205    float r, g, b;
206   
207    // Clear color and depth buffers
208    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
209   
210    glMatrixMode(GL_MODELVIEW);
211    glLoadIdentity();
212   
213    // Camera  i
214    gluLookAt(cameras[cam].eyeX, cameras[cam].eyeY, cameras[cam].eyeZ,
215              cameras[cam].centerX, cameras[cam].centerY, cameras[cam].centerZ,
216              cameras[cam].upX, cameras[cam].upY, cameras[cam].upZ);
217   
218    // Immediate mode
219    glBegin (GL_TRIANGLES);
220    for (i=0; i<mesh->numTriangles; i++) {
221        if (mesh->triangles[i].enable == TRUE) {
222           
223            v1= mesh->triangles[i].indices[0];
224            v2= mesh->triangles[i].indices[1];
225            v3= mesh->triangles[i].indices[2];
226           
227            computeRGB(minSal, maxSal, mesh->triangles[i].saliency, &r, &g, &b);
228           
229            glColor3f(r, g, b);
230            glVertex3f(mesh->vertices[v1].x, mesh->vertices[v1].y, mesh->vertices[v1].z);
231            glVertex3f(mesh->vertices[v2].x, mesh->vertices[v2].y, mesh->vertices[v2].z);
232            glVertex3f(mesh->vertices[v3].x, mesh->vertices[v3].y, mesh->vertices[v3].z);
233        }
234    }
235    glEnd();
236}
237
238void VMI::computeRGB(double min, double max,double value,float *r,float *g,float *b)
239{
240        /* Given the maximum, the minimum value and the demanded color value returns
241         * the respective RGB color
242         */
243        if(value>max) value=max;
244        if(value<min) value=min;
245
246        if(max==min) value=1;
247        else value=(float)(value-min)/(float)(max-min);
248
249        if (value<=0.25)
250        {
251                (*r)=0;
252                (*g)=4*value;
253                (*b)=1;
254        }
255        else if (value<=0.50)
256        {
257                (*r)=0;
258                (*g)=1;
259                (*b)=2-4*value;
260        }
261        else if (value<=0.75)
262        {
263                (*r)=4*value-2;
264                (*g)=1;
265                (*b)=0;
266        }
267        else
268        {
269                (*r)=1;
270                (*g)=4-4*value;
271                (*b)=0;
272        }
273}
274
275int VMI::compare(const void *arg1, const void *arg2)
276{
277    if(*(double *)arg1 < *(double *)arg2) return -1;
278    else if(*(double *)arg1 > *(double *)arg2) return 1;
279    else return 0;
280}
281
282int VMI::isDecimal(double value) {
283    long r = round(value);
284
285    //printf ("%d\n",r);
286
287    if ((double)r != value) return TRUE;
288    else return FALSE;
289}
290
291double VMI::computePercentile(int q, Triangle *triangles, int numTriangles) {
292    double p = (numTriangles * q) / 100.0;
293    double *list = (double *)malloc(numTriangles * sizeof(double)), l, per = 0.0;
294    int i;
295   
296    //printf("%f\n",p);
297
298    // filling the list
299    for(i = 0; i < numTriangles; i++)
300        list[i] = triangles[i].saliency;
301   
302    /* Quick-Sort */
303    qsort(list, numTriangles, sizeof(list[0]), compare);
304   
305    /* showing the sorted list */
306    /*for(i = 0; i < numTriangles; i++)
307        printf("%f\n", list[i]);
308    printf("\n");*/
309
310    if (isDecimal(p) == TRUE) per = list[(int)p + 1];
311    else {
312        l = (list[(int)p + 1] - list[(int)p]) * (q /100.0);
313
314        per = list[(int)p] + l;
315    }
316
317    free(list);
318   
319    return per;
320}
Note: See TracBrowser for help on using the repository browser.