-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathexample.c
141 lines (111 loc) · 3.11 KB
/
example.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/**
* A simple usgae demo for CGDL.
*
* @blackball
*/
#include "mat.h"
#include "cgdl.h"
#include <stdio.h>
#include <stdlib.h>
#if defined (NO_PUTS)
#define PUTS(s)
#else
#define PUTS(s) puts(s)
#endif
static void
_print_labels(const int *labels, int n) {
int i = 0;
for (; i < n; ++i) {
printf("%d ", labels[i]);
}
printf("\n");
}
static void
save_labels(const char *name, const int *labels, int n) {
FILE *f = fopen(name, "w");
int i = 0;
for (; i < n; ++i) {
fprintf(f, "%d\n", labels[i]);
}
fclose(f);
}
static void
demo(const char *dmname, const char *labelname) {
/* target cluster number */
const int T = 5;
int ret = 0;
int *labels = NULL;
struct cgdl_t *gdl = NULL;
struct mat_t *m = 0;
PUTS("Loading distance matrix...");
m = mat_load(dmname);
if (m == NULL) {
/* load distance mat failed! */
return ;
}
gdl = cgdl_new(4, 1);
if (gdl == NULL) {
return ;
}
/* get weight matrix and initial clusters */
PUTS("Initializing GDL...");
ret = cgdl_init(gdl, m);
if (ret != 0) {
goto _DOOR;
}
PUTS("Clustering...");
while ( cgdl_num(gdl) > T ) {
double aff = cgdl_merge(gdl);
printf("The affinity of merged clusters is: %lf, %d\n", aff, cgdl_num(gdl));
}
PUTS("Finished!");
labels = malloc(sizeof(labels[0]) * m->rows);
if (labels == NULL) {
goto _DOOR;
}
/* get the class labels */
cgdl_labels(gdl, labels);
PUTS("Save labels...");
save_labels(labelname, labels, m->rows);
/* Then you get the labels, do whatever you what next */
//_print_labels(labels, m->cols);
_DOOR:
if (m) {
mat_free(&m);
}
if (gdl) {
cgdl_free(&gdl);
}
if (labels) {
free(labels);
}
}
/* I simply draw some clusters in a black background image
* and use the foreground coordinates (x, y) as features. And use
* Euclidean distance to calculate the distance matrix. Then perform
* *GDL* on the distance matrix, and draw the clusters using different
* colors in a same size image.
*
* @NOTE You may need to tune the *GDL* paramemters in the demo(...) function
* to get a good results.
*/
#define USE_IMAGE
#if defined(USE_IMAGE)
#include "utils.h"
#endif
int
main(int argc, char *argv[]) {
const char *imgname = "./data/clusters.bmp";
const char *dmname = "./data/dm.txt";
const char *posname = "./data/positions.txt";
const char *lname = "./data/labels.txt";
#if defined(USE_IMAGE)
PUTS("Prepareing the distance matrix...");
extract_dm(imgname, dmname, posname);
#endif
demo(dmname, lname);
#if defined(USE_IMAGE)
show_result_in_image(imgname, posname, lname);
#endif
return 0;
}