Skip to content

Commit

Permalink
bugfix to ccv_sample_up
Browse files Browse the repository at this point in the history
previous implementation was taken from OpenCV, and it deals with
imperfect upsampling, for w*h image, it upsamples to (2w-1)x(2h-1).
In that case, the Gaussian weight should be G(0.0) G(1.0), G(0.5) G(0.5)
For perfect upsampling, i.e. wxh => 2wx2h, the actual Gaussian weight
should be G(0.25) G(1.25), G(0.25) G(0.75)
  • Loading branch information
liuliu committed Apr 16, 2012
1 parent bd4ffda commit 12700e8
Show file tree
Hide file tree
Showing 11 changed files with 561 additions and 41 deletions.
4 changes: 2 additions & 2 deletions bin/makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
CC = clang
LDFLAGS = -L"../lib" -lccv -pthread -ljpeg -lpng -lfftw3f -lfftw3 -lz -lgsl -lblas -lm # -lgomp
LDFLAGS = -L"../lib" -lccv -pthread -ljpeg -lpng -lfftw3f -lfftw3 -lz -lgsl -lblas -llinear -lm # -lgomp
CFLAGS = -O3 -msse2 -Wall -I"../lib"

TARGETS = bbffmt siftmatch bbfcreate bbfdetect swtdetect swtcreate dpmdetect convert
TARGETS = bbffmt siftmatch bbfcreate bbfdetect swtcreate swtdetect dpmcreate dpmdetect convert

all: libccv.a $(TARGETS)

Expand Down
23 changes: 19 additions & 4 deletions lib/ccv.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ typedef struct {
ccv_dense_matrix_t* ccv_dense_matrix_renew(ccv_dense_matrix_t* x, int rows, int cols, int types, int prefer_type, uint64_t sig);
ccv_dense_matrix_t* ccv_dense_matrix_new(int rows, int cols, int type, void* data, uint64_t sig);
ccv_dense_matrix_t ccv_dense_matrix(int rows, int cols, int type, void* data, uint64_t sig);
void ccv_make_matrix_mutable(ccv_matrix_t* mat);
void ccv_make_matrix_immutable(ccv_matrix_t* mat);
ccv_sparse_matrix_t* ccv_sparse_matrix_new(int rows, int cols, int type, int major, uint64_t sig);
void ccv_matrix_free_immediately(ccv_matrix_t* mat);
void ccv_matrix_free(ccv_matrix_t* mat);
Expand Down Expand Up @@ -300,11 +302,16 @@ enum {
CCV_PADDING_MIRROR = 0x04,
};

enum {
CCV_SIGNED = 0x00,
CCV_UNSIGNED = 0x01,
};

double ccv_norm(ccv_matrix_t* mat, int type);
double ccv_normalize(ccv_matrix_t* a, ccv_matrix_t** b, int btype, int flag);
void ccv_sat(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, int padding_pattern);
double ccv_dot(ccv_matrix_t* a, ccv_matrix_t* b);
double ccv_sum(ccv_matrix_t* mat);
double ccv_sum(ccv_matrix_t* mat, int flag);
void ccv_multiply(ccv_matrix_t* a, ccv_matrix_t* b, ccv_matrix_t** c, int type);
void ccv_substract(ccv_matrix_t* a, ccv_matrix_t* b, ccv_matrix_t** c, int type);

Expand Down Expand Up @@ -581,7 +588,7 @@ typedef struct {
int count;
ccv_dpm_part_classifier_t root;
ccv_dpm_part_classifier_t* part;
double beta;
float beta;
} ccv_dpm_root_classifier_t;

typedef struct {
Expand All @@ -593,19 +600,27 @@ typedef struct {
int interval;
int min_neighbors;
int flags;
double threshold;
float threshold;
} ccv_dpm_param_t;

typedef struct {
int components;
int parts;
int grayscale;
int symmetric;
int min_area; // 3000
int max_area; // 5000
ccv_dpm_param_t detector;
} ccv_dpm_new_param_t;

enum {
CCV_DPM_NO_NESTED = 0x10000000,
};

void ccv_dpm_classifier_lsvm_new(ccv_dense_matrix_t** posimgs, int posnum, char** bgfiles, int bgnum, int negnum, const char* dir, ccv_dpm_new_param_t params);
void ccv_dpm_mixture_model_new(char** posfiles, ccv_rect_t* bboxes, int posnum, char** bgfiles, int bgnum, int negnum, const char* dir, ccv_dpm_new_param_t params);
ccv_array_t* ccv_dpm_detect_objects(ccv_dense_matrix_t* a, ccv_dpm_mixture_model_t** model, int count, ccv_dpm_param_t params);
ccv_dpm_mixture_model_t* ccv_load_dpm_mixture_model(const char* directory);
void ccv_dpm_mixture_model_free(ccv_dpm_mixture_model_t* model);

/* this is open source implementation of object detection algorithm: brightness binary feature
* it is an extension/modification of original HAAR-like feature with Adaboost, featured faster
Expand Down
25 changes: 19 additions & 6 deletions lib/ccv_algebra.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,18 +131,31 @@ void ccv_sat(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, int paddin
}
}

double ccv_sum(ccv_matrix_t* mat)
double ccv_sum(ccv_matrix_t* mat, int flag)
{
ccv_dense_matrix_t* dmt = ccv_get_dense_matrix(mat);
double sum = 0;
unsigned char* m_ptr = dmt->data.u8;
int i, j;
int i, j, ch = CCV_GET_CHANNEL(dmt->type);
#define for_block(_, _for_get) \
for (i = 0; i < dmt->rows; i++) \
switch (flag) \
{ \
for (j = 0; j < dmt->cols; j++) \
sum += _for_get(m_ptr, j, 0); \
m_ptr += dmt->step; \
case CCV_UNSIGNED: \
for (i = 0; i < dmt->rows; i++) \
{ \
for (j = 0; j < dmt->cols * ch; j++) \
sum += fabs(_for_get(m_ptr, j, 0)); \
m_ptr += dmt->step; \
} \
break; \
case CCV_SIGNED: \
default: \
for (i = 0; i < dmt->rows; i++) \
{ \
for (j = 0; j < dmt->cols * ch; j++) \
sum += _for_get(m_ptr, j, 0); \
m_ptr += dmt->step; \
} \
}
ccv_matrix_getter(dmt->type, for_block);
#undef for_block
Expand Down
30 changes: 18 additions & 12 deletions lib/ccv_basic.c
Original file line number Diff line number Diff line change
Expand Up @@ -340,9 +340,9 @@ void ccv_hog(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int b_type, int sbin
mgv = mgv / 255.0; \
_for_type yp = ((_for_type)i + 0.5) / (_for_type)size - 0.5; \
_for_type xp = ((_for_type)j + 0.5) / (_for_type)size - 0.5; \
int iyp = (int)yp; \
int iyp = (int)floor(yp); \
assert(iyp < rows); \
int ixp = (int)xp; \
int ixp = (int)floor(xp); \
assert(ixp < cols); \
_for_type vy0 = yp - iyp; \
_for_type vx0 = xp - ixp; \
Expand Down Expand Up @@ -946,15 +946,21 @@ 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 + sx, 0) * 6 + _for_get_a(a_ptr, k + sx + ch, 0) * 2, 0); \
_for_set(row, k + ch, (_for_get_a(a_ptr, k + sx, 0) + _for_get_a(a_ptr, k + sx + ch, 0)) * 4, 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); \
} \
/* 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 (k = 0; k < ch; k++) \
{ \
_for_set(row, x * 2 + k, _for_get_a(a_ptr, x + sx - ch + k, 0) + _for_get_a(a_ptr, x + sx + k, 0) * 6 + _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 + k, 0) + _for_get_a(a_ptr, x + sx + ch + k, 0)) * 4, 0); \
_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); \
} \
} \
x_block(_for_get_a, _for_set, _for_get, _for_set_b); \
Expand All @@ -964,8 +970,8 @@ 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) + _for_get(rows[1], x, 0) * 2 + _for_get(rows[2], x, 0)) / 32, 0); \
_for_set_b(b_ptr + db->step, x, (_for_get(rows[1], x, 0) + _for_get(rows[2], x, 0)) / 16, 0); \
_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); \
} \
b_ptr += 2 * db->step; \
}
Expand All @@ -977,17 +983,17 @@ void ccv_sample_up(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, int
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) + _for_get_a(a_ptr, tab[x + sx + k], 0) * 6 + _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 + k], 0) + _for_get_a(a_ptr, tab[x + sx + ch + k], 0)) * 4, 0); \
_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); \
}
ccv_matrix_getter_a(a->type, ccv_matrix_setter_getter, 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) + _for_get_a(a_ptr, (a->cols - 1) * ch + k, 0) * 7, 0); \
_for_set(row, (a->cols - 1) * 2 * ch + ch + k, _for_get_a(a_ptr, (a->cols - 1) * ch + k, 0) * 4, 0); \
_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);
#undef x_block
Expand Down
Loading

0 comments on commit 12700e8

Please sign in to comment.