Skip to content

Commit

Permalink
correcting Gaussian weight & unit test
Browse files Browse the repository at this point in the history
I got it wrong the first time, variance for upsampling should always be
0.5
  • Loading branch information
liuliu committed Apr 17, 2012
1 parent 12700e8 commit cae6a61
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 24 deletions.
86 changes: 65 additions & 21 deletions lib/ccv_basic.c
Original file line number Diff line number Diff line change
Expand Up @@ -939,28 +939,31 @@ void ccv_sample_up(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, int
{ \
for (k = 0; k < ch; k++) \
{ \
_for_set(row, k, _for_get_a(a_ptr, k, 0) * 8, 0); \
_for_set(row, k + ch, _for_get_a(a_ptr, k, 0) * 8, 0); \
_for_set(row, k, _for_get_a(a_ptr, k, 0) * (G025 + G075 + G125), 0); \
_for_set(row, k + ch, _for_get_a(a_ptr, k, 0) * (G025 + G075 + G125), 0); \
} \
continue; \
} \
for (k = 0; k < ch; k++) \
if (sx == 0) \
{ \
_for_set(row, k, _for_get_a(a_ptr, k + sx, 0) * 7 + _for_get_a(a_ptr, k + sx + ch, 0), 0); \
_for_set(row, k + ch, _for_get_a(a_ptr, k + sx, 0) * 5 + _for_get_a(a_ptr, k + sx + ch, 0) * 3, 0); \
for (k = 0; k < ch; k++) \
{ \
_for_set(row, k, _for_get_a(a_ptr, k + sx, 0) * (G025 + G075) + _for_get_a(a_ptr, k + sx + ch, 0) * G125, 0); \
_for_set(row, k + ch, _for_get_a(a_ptr, k + sx, 0) * (G125 + G025) + _for_get_a(a_ptr, k + sx + ch, 0) * G075, 0); \
} \
} \
/* some serious flaw in computing Gaussian weighting in previous version
* specially, we are doing perfect upsampling (2x) so, it concerns a grid like:
* XXYY
* XXYY
* in this case, to upsampling, the weight should be from distance 0.25 and 1.25, and 0.25 and 0.75
* previously, it was mistakingly be 0.0 1.0, 0.5 0.5 (imperfect upsampling (2x - 1)) */ \
for (x = ch; x < cols0 * ch; x += ch) \
for (x = (sx == 0) ? ch : 0; x < cols0 * ch; x += ch) \
{ \
for (k = 0; k < ch; k++) \
{ \
_for_set(row, x * 2 + k, _for_get_a(a_ptr, x + sx - ch + k, 0) * 3 + _for_get_a(a_ptr, x + sx + k, 0) * 4 + _for_get_a(a_ptr, x + sx + ch + k, 0), 0); \
_for_set(row, x * 2 + ch + k, _for_get_a(a_ptr, x + sx - ch + k, 0) + _for_get_a(a_ptr, x + sx + k, 0) * 4 + _for_get_a(a_ptr, x + sx + ch + k, 0) * 3, 0); \
_for_set(row, x * 2 + k, _for_get_a(a_ptr, x + sx - ch + k, 0) * G075 + _for_get_a(a_ptr, x + sx + k, 0) * G025 + _for_get_a(a_ptr, x + sx + ch + k, 0) * G125, 0); \
_for_set(row, x * 2 + ch + k, _for_get_a(a_ptr, x + sx - ch + k, 0) * G125 + _for_get_a(a_ptr, x + sx + k, 0) * G025 + _for_get_a(a_ptr, x + sx + ch + k, 0) * G075, 0); \
} \
} \
x_block(_for_get_a, _for_set, _for_get, _for_set_b); \
Expand All @@ -970,33 +973,74 @@ void ccv_sample_up(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, int
rows[k] = buf + ((y + k) % 3) * bufstep; \
for (x = 0; x < db->cols * ch; x++) \
{ \
_for_set_b(b_ptr, x, (_for_get(rows[0], x, 0) * 3 + _for_get(rows[1], x, 0) * 4 + _for_get(rows[2], x, 0)) / 64, 0); \
_for_set_b(b_ptr + db->step, x, (_for_get(rows[0], x, 0) + _for_get(rows[1], x, 0) * 4 + _for_get(rows[2], x, 0) * 3) / 64, 0); \
_for_set_b(b_ptr, x, (_for_get(rows[0], x, 0) * G075 + _for_get(rows[1], x, 0) * G025 + _for_get(rows[2], x, 0) * G125) / GALL, 0); \
_for_set_b(b_ptr + db->step, x, (_for_get(rows[0], x, 0) * G125 + _for_get(rows[1], x, 0) * G025 + _for_get(rows[2], x, 0) * G075) / GALL, 0); \
} \
b_ptr += 2 * db->step; \
}
int no_8u_type = (a->type & CCV_8U) ? CCV_32S : a->type;
/* unswitch if condition in manual way */
if (src_x > 0)
if ((a->type & CCV_8U) || (a->type & CCV_32S) || (a->type & CCV_64S))
{
#define G025 (23)
#define G075 (8)
#define G125 (1)
#define GALL (1024)
if (src_x > 0)
{
#define x_block(_for_get_a, _for_set, _for_get, _for_set_b) \
for (x = cols0 * ch; x < a->cols * ch; x += ch) \
for (k = 0; k < ch; k++) \
{ \
_for_set(row, x * 2 + k, _for_get_a(a_ptr, tab[x + sx - ch + k], 0) * G075 + _for_get_a(a_ptr, tab[x + sx + k], 0) * G025 + _for_get_a(a_ptr, tab[x + sx + ch + k], 0) * G125, 0); \
_for_set(row, x * 2 + ch + k, _for_get_a(a_ptr, tab[x + sx - ch + k], 0) * G125 + _for_get_a(a_ptr, tab[x + sx + k], 0) * G025 + _for_get_a(a_ptr, tab[x + sx + ch + k], 0) * G075, 0); \
}
ccv_matrix_getter_integer_only(a->type, ccv_matrix_setter_getter_integer_only, no_8u_type, ccv_matrix_setter_b, db->type, for_block);
#undef x_block
} else {
#define x_block(_for_get_a, _for_set, _for_get, _for_set_b) \
for (x = cols0 * ch; x < a->cols * ch; x += ch) \
for (k = 0; k < ch; k++) \
{ \
_for_set(row, x * 2 + k, _for_get_a(a_ptr, tab[x + sx - ch + k], 0) * 3 + _for_get_a(a_ptr, tab[x + sx + k], 0) * 4 + _for_get_a(a_ptr, tab[x + sx + ch + k], 0), 0); \
_for_set(row, x * 2 + ch + k, _for_get_a(a_ptr, tab[x + sx - ch + k], 0) + _for_get_a(a_ptr, tab[x + sx + k], 0) * 4 + _for_get_a(a_ptr, tab[x + sx + ch + k], 0) * 3, 0); \
_for_set(row, (a->cols - 1) * 2 * ch + k, _for_get_a(a_ptr, (a->cols - 2) * ch + k, 0) * G075 + _for_get_a(a_ptr, (a->cols - 1) * ch + k, 0) * (G025 + G125), 0); \
_for_set(row, (a->cols - 1) * 2 * ch + ch + k, _for_get_a(a_ptr, (a->cols - 2) * ch + k, 0) * G125 + _for_get_a(a_ptr, (a->cols - 1) * ch + k, 0) * (G025 + G075), 0); \
}
ccv_matrix_getter_a(a->type, ccv_matrix_setter_getter, no_8u_type, ccv_matrix_setter_b, db->type, for_block);
ccv_matrix_getter_integer_only(a->type, ccv_matrix_setter_getter_integer_only, no_8u_type, ccv_matrix_setter_b, db->type, for_block);
#undef x_block
}
#undef GALL
#undef G125
#undef G075
#undef G025
} else {
#define G025 (0.705385)
#define G075 (0.259496)
#define G125 (0.035119)
#define GALL (1)
if (src_x > 0)
{
#define x_block(_for_get_a, _for_set, _for_get, _for_set_b) \
for (k = 0; k < ch; k++) \
{ \
_for_set(row, (a->cols - 1) * 2 * ch + k, _for_get_a(a_ptr, (a->cols - 2) * ch + k, 0) * 3 + _for_get_a(a_ptr, (a->cols - 1) * ch + k, 0) * 5, 0); \
_for_set(row, (a->cols - 1) * 2 * ch + ch + k, _for_get_a(a_ptr, (a->cols - 2) * ch + k, 0) + _for_get_a(a_ptr, (a->cols - 1) * ch + k, 0) * 7, 0); \
}
ccv_matrix_getter_a(a->type, ccv_matrix_setter_getter, no_8u_type, ccv_matrix_setter_b, db->type, for_block);
for (x = cols0 * ch; x < a->cols * ch; x += ch) \
for (k = 0; k < ch; k++) \
{ \
_for_set(row, x * 2 + k, _for_get_a(a_ptr, tab[x + sx - ch + k], 0) * G075 + _for_get_a(a_ptr, tab[x + sx + k], 0) * G025 + _for_get_a(a_ptr, tab[x + sx + ch + k], 0) * G125, 0); \
_for_set(row, x * 2 + ch + k, _for_get_a(a_ptr, tab[x + sx - ch + k], 0) * G125 + _for_get_a(a_ptr, tab[x + sx + k], 0) * G025 + _for_get_a(a_ptr, tab[x + sx + ch + k], 0) * G075, 0); \
}
ccv_matrix_getter_float_only(a->type, ccv_matrix_setter_getter_float_only, no_8u_type, ccv_matrix_setter_b, db->type, for_block);
#undef x_block
} else {
#define x_block(_for_get_a, _for_set, _for_get, _for_set_b) \
for (k = 0; k < ch; k++) \
{ \
_for_set(row, (a->cols - 1) * 2 * ch + k, _for_get_a(a_ptr, (a->cols - 2) * ch + k, 0) * G075 + _for_get_a(a_ptr, (a->cols - 1) * ch + k, 0) * (G025 + G125), 0); \
_for_set(row, (a->cols - 1) * 2 * ch + ch + k, _for_get_a(a_ptr, (a->cols - 2) * ch + k, 0) * G125 + _for_get_a(a_ptr, (a->cols - 1) * ch + k, 0) * (G025 + G075), 0); \
}
ccv_matrix_getter_float_only(a->type, ccv_matrix_setter_getter_float_only, no_8u_type, ccv_matrix_setter_b, db->type, for_block);
#undef x_block
}
#undef GALL
#undef G125
#undef G075
#undef G025
}
#undef for_block
}
Expand Down
4 changes: 2 additions & 2 deletions lib/ccv_dpm.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,9 +399,9 @@ void ccv_dpm_mixture_model_new(char** posfiles, ccv_rect_t* bboxes, int posnum,
continue;
if (l > n * 2 || n > l * 2)
continue;
//if (params.symmetric)
if (params.symmetric)
{
//} else {
} else {
for (y = 0; y < w->rows - l + 1; y++)
for (x = 0; x < w->cols - n + 1; x++)
{
Expand Down
35 changes: 35 additions & 0 deletions lib/ccv_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
#define _ccv_get_64s_value(ptr, i, factor) (((int64_t*)(ptr))[(i)] << factor)
#define _ccv_get_64f_value(ptr, i, factor) ((double*)(ptr))[(i)]
#define _ccv_get_8u_value(ptr, i, factor) (((unsigned char*)(ptr))[(i)] << factor)

#define ccv_matrix_getter(type, block, ...) { switch (CCV_GET_DATA_TYPE(type)) { \
case CCV_32S: { block(__VA_ARGS__, _ccv_get_32s_value); break; } \
case CCV_32F: { block(__VA_ARGS__, _ccv_get_32f_value); break; } \
Expand All @@ -128,6 +129,17 @@
case CCV_64F: { block(__VA_ARGS__, _ccv_get_64f_value); break; } \
default: { block(__VA_ARGS__, _ccv_get_8u_value); } } }

#define ccv_matrix_getter_integer_only(type, block, ...) { switch (CCV_GET_DATA_TYPE(type)) { \
case CCV_32S: { block(__VA_ARGS__, _ccv_get_32s_value); break; } \
case CCV_64S: { block(__VA_ARGS__, _ccv_get_64s_value); break; } \
case CCV_8U: { block(__VA_ARGS__, _ccv_get_8u_value); break; } \
default: { assert((type & CCV_32S) || (type & CCV_64S) || (type & CCV_8U)); } } }

#define ccv_matrix_getter_float_only(type, block, ...) { switch (CCV_GET_DATA_TYPE(type)) { \
case CCV_32F: { block(__VA_ARGS__, _ccv_get_32f_value); break; } \
case CCV_64F: { block(__VA_ARGS__, _ccv_get_64f_value); break; } \
default: { assert((type & CCV_32F) || (type & CCV_64F)); } } }

#define ccv_matrix_typeof(type, block, ...) { switch (CCV_GET_DATA_TYPE(type)) { \
case CCV_32S: { block(__VA_ARGS__, int); break; } \
case CCV_32F: { block(__VA_ARGS__, float); break; } \
Expand All @@ -154,6 +166,7 @@
#define _ccv_set_64s_value(ptr, i, value, factor) (((int64_t*)(ptr))[(i)] = (int64_t)(value) >> factor)
#define _ccv_set_64f_value(ptr, i, value, factor) (((double*)(ptr))[(i)] = (double)(value))
#define _ccv_set_8u_value(ptr, i, value, factor) (((unsigned char*)(ptr))[(i)] = ccv_clamp((int)(value) >> factor, 0, 255))

#define ccv_matrix_setter(type, block, ...) { switch (CCV_GET_DATA_TYPE(type)) { \
case CCV_32S: { block(__VA_ARGS__, _ccv_set_32s_value); break; } \
case CCV_32F: { block(__VA_ARGS__, _ccv_set_32f_value); break; } \
Expand All @@ -175,6 +188,17 @@
case CCV_64F: { block(__VA_ARGS__, _ccv_set_64f_value); break; } \
default: { block(__VA_ARGS__, _ccv_set_8u_value); } } }

#define ccv_matrix_setter_integer_only(type, block, ...) { switch (CCV_GET_DATA_TYPE(type)) { \
case CCV_32S: { block(__VA_ARGS__, _ccv_set_32s_value); break; } \
case CCV_64S: { block(__VA_ARGS__, _ccv_set_64s_value); break; } \
case CCV_8U: { block(__VA_ARGS__, _ccv_set_8u_value); break; } \
default: { assert((type & CCV_32S) || (type & CCV_64S) || (type & CCV_8U)); } } }

#define ccv_matrix_setter_float_only(type, block, ...) { switch (CCV_GET_DATA_TYPE(type)) { \
case CCV_32F: { block(__VA_ARGS__, _ccv_set_32f_value); break; } \
case CCV_64F: { block(__VA_ARGS__, _ccv_set_64f_value); break; } \
default: { assert((type & CCV_32F) || (type & CCV_64F)); } } }

#define ccv_matrix_setter_getter(type, block, ...) { switch (CCV_GET_DATA_TYPE(type)) { \
case CCV_32S: { block(__VA_ARGS__, _ccv_set_32s_value, _ccv_get_32s_value); break; } \
case CCV_32F: { block(__VA_ARGS__, _ccv_set_32f_value, _ccv_get_32f_value); break; } \
Expand All @@ -196,6 +220,17 @@
case CCV_64F: { block(__VA_ARGS__, _ccv_set_64f_value, _ccv_get_64f_value); break; } \
default: { block(__VA_ARGS__, _ccv_set_8u_value, _ccv_get_8u_value); } } }

#define ccv_matrix_setter_getter_integer_only(type, block, ...) { switch (CCV_GET_DATA_TYPE(type)) { \
case CCV_32S: { block(__VA_ARGS__, _ccv_set_32s_value, _ccv_get_32s_value); break; } \
case CCV_64S: { block(__VA_ARGS__, _ccv_set_64s_value, _ccv_get_64s_value); break; } \
case CCV_8U: { block(__VA_ARGS__, _ccv_set_8u_value, _ccv_get_8u_value); break; } \
default: { assert((type & CCV_32S) || (type & CCV_64S) || (type & CCV_8U)); } } }

#define ccv_matrix_setter_getter_float_only(type, block, ...) { switch (CCV_GET_DATA_TYPE(type)) { \
case CCV_32F: { block(__VA_ARGS__, _ccv_set_32f_value, _ccv_get_32f_value); break; } \
case CCV_64F: { block(__VA_ARGS__, _ccv_set_64f_value, _ccv_get_64f_value); break; } \
default: { assert((type & CCV_32F) || (type & CCV_64F)); } } }

#define ccv_matrix_typeof_getter(type, block, ...) { switch (CCV_GET_DATA_TYPE(type)) { \
case CCV_32S: { block(__VA_ARGS__, int, _ccv_get_32s_value); break; } \
case CCV_32F: { block(__VA_ARGS__, float, _ccv_get_32f_value); break; } \
Expand Down
2 changes: 1 addition & 1 deletion test/algebra.tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ TEST_CASE("vector sum")
a->data.f64[3] = 0.21;
a->data.f64[4] = 0.22;
a->data.f64[5] = 0.23;
double sum = ccv_sum(a);
double sum = ccv_sum(a, CCV_SIGNED);
ccv_matrix_free(a);
REQUIRE_EQ_WITH_TOLERANCE(sum, 1.02, 1e-6, "3x2 vector sum failure");
}
Expand Down
Binary file modified test/data/chessbox.sample_up.bin
Binary file not shown.

0 comments on commit cae6a61

Please sign in to comment.