-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy patherrorfunc.c
88 lines (66 loc) · 1.82 KB
/
errorfunc.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
#include "errorfunc.h"
#include "model.h"
#include <GL/gl.h>
static float floorWeight = 0.0;
static float angleWeight = 0.0;
//static int count = 0;
float error_function(float p[], IplImage *image) {
IplImage *buffer = cvCreateImage(cvGetSize(image), 8, 1);
float sd, fe, ae;
// char fn[100];
project(buffer, p);
sd = symmetric_difference(image, buffer);
if (floorWeight > 0)
fe = model_get_floor_error();
else
fe = 0.0;
if (angleWeight > 0)
ae = angle_error(p);
else
ae = 0.0;
/*
sprintf(fn, "out/%d.model", count);
model_to_file(fn);
sprintf(fn, "out/%d.png", count++);
cvSaveImage(fn, buffer);
*/
cvReleaseImage(&buffer);
return sd + floorWeight*fe + angleWeight*ae;
}
// now angle and segment length error
float angle_error(float *p) {
int i, j;
float error = 0.0;
for (i = 0; i < MODEL_ANGLES + MODEL_SEGMENT_LENGTHS; i++)
if (i < MODEL_ANGLES)
j = model_angle_to_constraint(i);
else
j = i - MODEL_ANGLES + MODEL_CONSTRAINTS;
if (p[i] < model_get_min(j))
error += pow(1.0 + fabs(model_get_min(j) - p[i]), 8.0);
else if (p[i] > model_get_max(j))
error += pow(1.0 + fabs(p[i] - model_get_max(j)), 8.0);
return error;
}
float symmetric_difference(IplImage *img1, IplImage *img2) {
IplImage *error = cvCreateImage(cvGetSize(img1), 8, 1);
CvMoments m;
float mass;
cvXor(img1, img2, error, NULL);
cvMoments(error, &m, 1);
mass = cvGetSpatialMoment(&m, 0, 0);
cvReleaseImage(&error);
return mass;
}
void project(IplImage *img, float *p) {
model_set_vector(p + 1);
model_draw_from_vector();
glReadPixels(0, 0, img->width, img->height, GL_LUMINANCE,
GL_UNSIGNED_BYTE, img->imageData);
}
void error_func_set_floor_weight(float w) {
floorWeight = w;
}
void error_func_set_angle_weight(float w) {
angleWeight = w;
}