Skip to content

Commit

Permalink
modified ccv_sample_down so that you can have some offset
Browse files Browse the repository at this point in the history
  • Loading branch information
liuliu committed Oct 10, 2010
1 parent d1f4e36 commit 1f2854c
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 79 deletions.
2 changes: 1 addition & 1 deletion bin/bbfcreate.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ int main(int argc, char** argv)
}
fclose(bgf);
ccv_bbf_param_t params;
params.pos_crit = 0.995;
params.pos_crit = 0.9975;
params.neg_crit = 0.50;
params.balance_k = 1.0;
params.layer = 24;
Expand Down
4 changes: 2 additions & 2 deletions lib/ccv.h
Original file line number Diff line number Diff line change
Expand Up @@ -483,8 +483,8 @@ enum {
};

void ccv_resample(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int btype, int rows, int cols, int type);
void ccv_sample_down(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type);
void ccv_sample_up(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type);
void ccv_sample_down(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, int off_x, int off_y);
void ccv_sample_up(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, int off_x, int off_y);

enum {
CCV_FLIP_X = 0x01,
Expand Down
46 changes: 30 additions & 16 deletions lib/ccv_basic.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,40 +453,50 @@ void ccv_resample(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int btype, int
}

/* the following code is adopted from OpenCV cvPyrDown */
void ccv_sample_down(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type)
void ccv_sample_down(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, int off_x, int off_y)
{
uint64_t sig = (a->sig == 0) ? 0 : ccv_matrix_generate_signature("ccv_sample_down", 15, a->sig, 0);
assert(off_x >= 0 && off_y >= 0);
char identifier[64];
memset(identifier, 0, 64);
snprintf(identifier, 64, "ccv_sample_down(%d,%d)", off_x, off_y);
uint64_t sig = (a->sig == 0) ? 0 : ccv_matrix_generate_signature(identifier, 64, a->sig, 0);
type = (type == 0) ? CCV_GET_DATA_TYPE(a->type) | CCV_GET_CHANNEL(a->type) : CCV_GET_DATA_TYPE(type) | CCV_GET_CHANNEL(a->type);
ccv_dense_matrix_t* db = *b = ccv_dense_matrix_renew(*b, a->rows / 2, a->cols / 2, CCV_ALL_DATA_TYPE | CCV_GET_CHANNEL(a->type), type, sig);
ccv_cache_return(db, );
int ch = ccv_clamp(CCV_GET_CHANNEL_NUM(a->type), 1, 4);
int cols0 = db->cols - 2 + (a->cols - db->cols * 2);
int dy, sy = -2, dx, k;
int cols0 = db->cols - 1 - off_x;
int dy, sy = -2 + off_y, sx = off_x * ch, dx, k;
int* tab = (int*)alloca((a->cols + off_x + 2) * ch * sizeof(int));
for (dx = 0; dx < a->cols + off_x + 2; dx++)
for (k = 0; k < ch; k++)
tab[dx * ch + k] = ((dx >= a->cols) ? a->cols * 2 - 1 - dx : dx) * ch + k;
unsigned char* buf = (unsigned char*)alloca(5 * db->cols * ch * ccv_max(CCV_GET_DATA_TYPE_SIZE(db->type), sizeof(int)));
int bufstep = db->cols * ch * ccv_max(CCV_GET_DATA_TYPE_SIZE(db->type), sizeof(int));
unsigned char* b_ptr = db->data.ptr;
#define for_block(__for_get_a, __for_get, __for_set, __for_set_b) \
for (dy = 0; dy < db->rows; dy++) \
{ \
for(; sy <= dy * 2 + 2; sy++) \
for(; sy <= dy * 2 + 2 + off_y; sy++) \
{ \
unsigned char* row = buf + ((sy + 2) % 5) * bufstep; \
unsigned char* row = buf + ((sy + off_y * 4 + 2) % 5) * bufstep; \
int _sy = (sy < 0) ? 1 - sy : (sy >= a->rows) ? a->rows * 2 - 1 - sy : sy; \
unsigned char* a_ptr = a->data.ptr + a->step * _sy; \
for (k = 0; k < ch; k++) \
__for_set(row, k, __for_get_a(a_ptr, k, 0) * 10 + __for_get_a(a_ptr, ch + k, 0) * 5 + __for_get_a(a_ptr, 2 * ch + k, 0), 0); \
__for_set(row, k, __for_get_a(a_ptr, sx + k, 0) * 10 + __for_get_a(a_ptr, ch + sx + k, 0) * 5 + __for_get_a(a_ptr, 2 * ch + sx + k, 0), 0); \
for(dx = ch; dx < cols0 * ch; dx += ch) \
for (k = 0; k < ch; k++) \
__for_set(row, dx + k, __for_get_a(a_ptr, dx * 2 + k, 0) * 6 + (__for_get_a(a_ptr, dx * 2 + k - ch, 0) + __for_get_a(a_ptr, dx * 2 + k + ch, 0)) * 4 + __for_get_a(a_ptr, dx * 2 + k - ch * 2, 0) + __for_get_a(a_ptr, dx * 2 + k + ch * 2, 0), 0); \
if (a->cols - db->cols * 2 == 0) \
__for_set(row, dx + k, __for_get_a(a_ptr, dx * 2 + sx + k, 0) * 6 + (__for_get_a(a_ptr, dx * 2 + sx + k - ch, 0) + __for_get_a(a_ptr, dx * 2 + sx + k + ch, 0)) * 4 + __for_get_a(a_ptr, dx * 2 + sx + k - ch * 2, 0) + __for_get_a(a_ptr, dx * 2 + sx + k + ch * 2, 0), 0); \
if (off_x > 0) \
for (dx = cols0 * ch; dx < db->cols * ch; dx += ch) \
for (k = 0; k < ch; k++) \
__for_set(row, dx + k, __for_get_a(a_ptr, tab[dx * 2 + sx + k], 0) * 6 + (__for_get_a(a_ptr, tab[dx * 2 + sx + k - ch], 0) + __for_get_a(a_ptr, tab[dx * 2 + sx + k + ch], 0)) * 4 + __for_get_a(a_ptr, tab[dx * 2 + sx + k - ch * 2], 0) + __for_get_a(a_ptr, tab[dx * 2 + sx + k + ch * 2], 0), 0); \
else \
for (k = 0; k < ch; k++) \
__for_set(row, (db->cols - 2) * ch + k, __for_get_a(a_ptr, (db->cols - 2) * 2 * ch + k, 0) * 6 + __for_get_a(a_ptr, (db->cols - 2) * 2 * ch - ch + k, 0) * 4 + __for_get_a(a_ptr, (db->cols - 2) * 2 * ch + ch + k, 0) * 5 + __for_get_a(a_ptr, (db->cols - 2) * 2 * ch - 2 * ch + k, 0), 0); \
for (k = 0; k < ch; k++) \
__for_set(row, (db->cols - 1) * ch + k, __for_get_a(a_ptr, a->cols * ch - ch + k, 0) * 10 + __for_get_a(a_ptr, (a->cols - 2) * ch + k, 0) * 5 + __for_get_a(a_ptr, (a->cols - 3) * ch + k, 0), 0); \
__for_set(row, (db->cols - 1) * ch + k, __for_get_a(a_ptr, a->cols * ch + sx - ch + k, 0) * 10 + __for_get_a(a_ptr, (a->cols - 2) * ch + sx + k, 0) * 5 + __for_get_a(a_ptr, (a->cols - 3) * ch + sx + k, 0), 0); \
} \
unsigned char* rows[5]; \
for(k = 0; k < 5; k++) \
rows[k] = buf + ((dy * 2 - 2 + k + 2) % 5) * bufstep; \
rows[k] = buf + ((dy * 2 + k) % 5) * bufstep; \
for(dx = 0; dx < db->cols * ch; dx++) \
__for_set_b(b_ptr, dx, (__for_get(rows[2], dx, 0) * 6 + (__for_get(rows[1], dx, 0) + __for_get(rows[3], dx, 0)) * 4 + __for_get(rows[0], dx, 0) + __for_get(rows[4], dx, 0)) / 256, 0); \
b_ptr += db->step; \
Expand All @@ -496,16 +506,20 @@ void ccv_sample_down(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type)
#undef for_block
}

void ccv_sample_up(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type)
void ccv_sample_up(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, int off_x, int off_y)
{
uint64_t sig = (a->sig == 0) ? 0 : ccv_matrix_generate_signature("ccv_sample_up", 15, a->sig, 0);
assert(off_x >= 0 && off_y >= 0);
char identifier[64];
memset(identifier, 0, 64);
snprintf(identifier, 64, "ccv_sample_up(%d,%d)", off_x, off_y);
uint64_t sig = (a->sig == 0) ? 0 : ccv_matrix_generate_signature(identifier, 64, a->sig, 0);
type = (type == 0) ? CCV_GET_DATA_TYPE(a->type) | CCV_GET_CHANNEL(a->type) : CCV_GET_DATA_TYPE(type) | CCV_GET_CHANNEL(a->type);
ccv_dense_matrix_t* db = *b = ccv_dense_matrix_renew(*b, a->rows * 2, a->cols * 2, CCV_ALL_DATA_TYPE | CCV_GET_CHANNEL(a->type), type, sig);
ccv_cache_return(db, );
int ch = ccv_clamp(CCV_GET_CHANNEL_NUM(a->type), 1, 4);
unsigned char* buf = (unsigned char*)alloca(3 * db->cols * ch * ccv_max(CCV_GET_DATA_TYPE_SIZE(db->type), sizeof(int)));
int bufstep = db->cols * ch * ccv_max(CCV_GET_DATA_TYPE_SIZE(db->type), sizeof(int));
int y, x, sy = -1, k;
int y, x, sy = -1 + off_y, k;
unsigned char* b_ptr = db->data.ptr;
#define for_block(__for_get_a, __for_get, __for_set, __for_set_b) \
for (y = 0; y < a->rows; y++) \
Expand Down
120 changes: 64 additions & 56 deletions lib/ccv_bbf.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,9 @@ static int __ccv_prepare_background_data(ccv_bbf_classifier_cascade_t* cascade,
ccv_resample(temp, &imgs0, 0, imgsz.height, imgsz.width, CCV_INTER_AREA);
assert(imgs0->step == steps[0]);
ccv_matrix_free(temp);
ccv_sample_down(imgs0, &imgs1, 0);
ccv_sample_down(imgs0, &imgs1, 0, 0, 0);
assert(imgs1->step == steps[1]);
ccv_sample_down(imgs1, &imgs2, 0);
ccv_sample_down(imgs1, &imgs2, 0, 0, 0);
assert(imgs2->step == steps[2]);

negdata[negtotal] = (unsigned char*)malloc(isizs0 + isizs1 + isizs2);
Expand Down Expand Up @@ -252,8 +252,8 @@ static void __ccv_prepare_positive_data(ccv_dense_matrix_t** posimg, unsigned ch
ccv_dense_matrix_t* imgs1 = 0;
ccv_dense_matrix_t* imgs2 = 0;
assert((imgs0->type & CCV_C1) && (imgs0->type & CCV_8U) && imgs0->rows == size.height && imgs0->cols == size.width);
ccv_sample_down(imgs0, &imgs1, 0);
ccv_sample_down(imgs1, &imgs2, 0);
ccv_sample_down(imgs0, &imgs1, 0, 0, 0);
ccv_sample_down(imgs1, &imgs2, 0, 0, 0);
int isizs0 = imgs0->rows * imgs0->step;
int isizs1 = imgs1->rows * imgs1->step;
int isizs2 = imgs2->rows * imgs2->step;
Expand Down Expand Up @@ -1173,26 +1173,23 @@ ccv_array_t* ccv_bbf_detect_objects(ccv_dense_matrix_t* a, ccv_bbf_classifier_ca
int hr = a->rows / min_size.height;
int wr = a->cols / min_size.width;
int scale_upto = (int)(log((double)ccv_min(hr, wr)) / log(sqrt(2.)));
ccv_dense_matrix_t** pyr = (ccv_dense_matrix_t**)alloca((scale_upto + 4) * sizeof(ccv_dense_matrix_t*));
ccv_dense_matrix_t** pyr = (ccv_dense_matrix_t**)alloca((scale_upto + 4) * 4 * sizeof(ccv_dense_matrix_t*));
memset(pyr, 0, (scale_upto + 4) * 4 * sizeof(ccv_dense_matrix_t*));
if (min_size.height != _cascade[0]->size.height || min_size.width != _cascade[0]->size.width)
{
pyr[0] = 0;
ccv_resample(a, &pyr[0], 0, a->rows * _cascade[0]->size.height / min_size.height, a->cols * _cascade[0]->size.width / min_size.width, CCV_INTER_AREA);
} else
else
pyr[0] = a;
double sqrt_2 = sqrt(2.);
pyr[1] = 0;
ccv_resample(pyr[0], &pyr[1], 0, (int)(pyr[0]->rows / sqrt_2), (int)(pyr[0]->cols / sqrt_2), CCV_INTER_AREA);
int i, j, k, t, x, y;
for (i = 2; i < scale_upto + 4; i += 2)
{
pyr[i] = 0;
ccv_sample_down(pyr[i - 2], &pyr[i], 0);
}
for ( i = 3; i < scale_upto + 4; i += 2 )
pyr[4] = 0;
ccv_resample(pyr[0], &pyr[4], 0, (int)(pyr[0]->rows / sqrt_2), (int)(pyr[0]->cols / sqrt_2), CCV_INTER_AREA);
int i, j, k, t, x, y, q;
for (i = 2; i < scale_upto + 4; i++)
ccv_sample_down(pyr[i * 4 - 8], &pyr[i * 4], 0, 0, 0);
for (i = 4; i < scale_upto + 4; i++)
{
pyr[i] = 0;
ccv_sample_down(pyr[i - 2], &pyr[i], 0);
ccv_sample_down(pyr[i * 4 - 8], &pyr[i * 4 + 1], 0, 1, 0);
ccv_sample_down(pyr[i * 4 - 8], &pyr[i * 4 + 2], 0, 0, 1);
ccv_sample_down(pyr[i * 4 - 8], &pyr[i * 4 + 3], 0, 1, 1);
}
ccv_array_t* idx_seq;
ccv_array_t* seq = ccv_array_new(64, sizeof(ccv_bbf_comp_t));
Expand All @@ -1207,49 +1204,54 @@ ccv_array_t* ccv_bbf_detect_objects(ccv_dense_matrix_t* a, ccv_bbf_classifier_ca
ccv_array_clear(seq);
for (i = 0; i < scale_upto; i++)
{
int i_rows = pyr[i + 4]->rows - (cascade->size.height >> 2);
int steps[] = { pyr[i]->step, pyr[i + 2]->step, pyr[i + 4]->step };
int i_cols = pyr[i + 4]->cols - (cascade->size.width >> 2);
int paddings[] = { pyr[i]->step * 4 - i_cols * 4,
pyr[i + 2]->step * 2 - i_cols * 2,
pyr[i + 4]->step - i_cols };
unsigned char* u8[] = { pyr[i]->data.ptr, pyr[i + 2]->data.ptr, pyr[i + 4]->data.ptr };
for (y = 0; y < i_rows; y++)
int dx[] = {0, 1, 0, 1};
int dy[] = {0, 0, 1, 1};
for (q = 0; q < 4; q++)
{
for (x = 0; x < i_cols; x++)
int i_rows = pyr[i * 4 + 16]->rows - (cascade->size.height >> 2);
int steps[] = { pyr[i * 4]->step, pyr[i * 4 + 8]->step, pyr[i * 4 + 16]->step };
int i_cols = pyr[i * 4 + 16]->cols - (cascade->size.width >> 2);
int paddings[] = { pyr[i * 4]->step * 4 - i_cols * 4,
pyr[i * 4 + 8]->step * 2 - i_cols * 2,
pyr[i * 4 + 16]->step - i_cols };
unsigned char* u8[] = { pyr[i * 4]->data.ptr + dx[q] * 2 + dy[q] * pyr[i * 4]->step * 2, pyr[i * 4 + 8]->data.ptr + dx[q] + dy[q] * pyr[i * 4 + 8]->step, pyr[i * 4 + 16 + q]->data.ptr };
for (y = 0; y < i_rows; y++)
{
float sum;
int flag = 1;
ccv_bbf_stage_classifier_t* classifier = cascade->stage_classifier;
for (j = 0; j < cascade->count; ++j, ++classifier)
for (x = 0; x < i_cols; x++)
{
sum = 0;
float* alpha = classifier->alpha;
ccv_bbf_feature_t* feature = classifier->feature;
for (k = 0; k < classifier->count; ++k, alpha += 2, ++feature)
sum += alpha[__ccv_run_bbf_feature(feature, steps, u8)];
if (sum < classifier->threshold)
float sum;
int flag = 1;
ccv_bbf_stage_classifier_t* classifier = cascade->stage_classifier;
for (j = 0; j < cascade->count; ++j, ++classifier)
{
flag = 0;
break;
sum = 0;
float* alpha = classifier->alpha;
ccv_bbf_feature_t* feature = classifier->feature;
for (k = 0; k < classifier->count; ++k, alpha += 2, ++feature)
sum += alpha[__ccv_run_bbf_feature(feature, steps, u8)];
if (sum < classifier->threshold)
{
flag = 0;
break;
}
}
if (flag)
{
ccv_bbf_comp_t comp;
comp.rect = ccv_rect((int)((x * 4 + dx[q] * 2) * scale_x), (int)((y * 4 + dy[q] * 2) * scale_y), (int)(cascade->size.width * scale_x), (int)(cascade->size.height * scale_y));
comp.id = t;
comp.neighbors = 1;
comp.confidence = sum;
ccv_array_push(seq, &comp);
}
u8[0] += 4;
u8[1] += 2;
u8[2] += 1;
}
if (flag)
{
ccv_bbf_comp_t comp;
comp.rect = ccv_rect((int)(x * 4 * scale_x), (int)(y * 4 * scale_y), (int)(cascade->size.width * scale_x), (int)(cascade->size.height * scale_y));
comp.id = t;
comp.neighbors = 1;
comp.confidence = sum;
ccv_array_push(seq, &comp);
}
u8[0] += 4;
u8[1] += 2;
u8[2] += 1;
u8[0] += paddings[0];
u8[1] += paddings[1];
u8[2] += paddings[2];
}
u8[0] += paddings[0];
u8[1] += paddings[1];
u8[2] += paddings[2];
}
scale_x *= sqrt_2;
scale_y *= sqrt_2;
Expand Down Expand Up @@ -1381,7 +1383,13 @@ ccv_array_t* ccv_bbf_detect_objects(ccv_dense_matrix_t* a, ccv_bbf_classifier_ca
}

for (i = 1; i < scale_upto + 4; i++)
ccv_matrix_free(pyr[i]);
ccv_matrix_free(pyr[i * 4]);
for (i = 4; i < scale_upto + 4; i++)
{
ccv_matrix_free(pyr[i * 4 + 1]);
ccv_matrix_free(pyr[i * 4 + 2]);
ccv_matrix_free(pyr[i * 4 + 3]);
}
if (min_size.height != _cascade[0]->size.height || min_size.width != _cascade[0]->size.width)
ccv_matrix_free(pyr[0]);

Expand Down
4 changes: 2 additions & 2 deletions lib/ccv_sift.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ void ccv_sift(ccv_dense_matrix_t* a, ccv_array_t** _keypoints, ccv_dense_matrix_
double dsigma0 = sigma0 * sigmak * sqrt(1.0 - 1.0 / (sigmak * sigmak));
if (params.up2x)
{
ccv_sample_up(a, &g[-(params.nlevels + 1)], 0);
ccv_sample_up(a, &g[-(params.nlevels + 1)], 0, 0, 0);
/* since there is a gaussian filter in sample_up function already,
* the default sigma for upsampled image is sqrt(2) */
double sd = sqrt(sigma0 * sigma0 - 2.0);
Expand Down Expand Up @@ -202,7 +202,7 @@ void ccv_sift(ccv_dense_matrix_t* a, ccv_array_t** _keypoints, ccv_dense_matrix_
ccv_matrix_free(g[params.nlevels]);
for (i = 1; i < params.noctaves; i++)
{
ccv_sample_down(g[(i - 1) * (params.nlevels + 1)], &g[i * (params.nlevels + 1)], 0);
ccv_sample_down(g[(i - 1) * (params.nlevels + 1)], &g[i * (params.nlevels + 1)], 0, 0, 0);
if (i - 1 > 0)
ccv_matrix_free(g[(i - 1) * (params.nlevels + 1)]);
sd = sqrt(sigma0 * sigma0 - 0.25);
Expand Down
2 changes: 1 addition & 1 deletion test/sample_down_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ int main(int argc, char** argv)
ccv_unserialize(argv[1], &image, CCV_SERIAL_ANY_FILE);
ccv_dense_matrix_t* x = 0;
unsigned int elapsed_time = get_current_time();
ccv_sample_down(image, &x, 0);
ccv_sample_down(image, &x, 0, 200, 150);
printf("elpased time : %d\n", get_current_time() - elapsed_time);
int len;
ccv_serialize(x, argv[2], &len, CCV_SERIAL_JPEG_FILE, 0);
Expand Down
2 changes: 1 addition & 1 deletion test/sample_up_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ int main(int argc, char** argv)
ccv_unserialize(argv[1], &image, CCV_SERIAL_ANY_FILE);
ccv_dense_matrix_t* x = 0;
unsigned int elapsed_time = get_current_time();
ccv_sample_up(image, &x, 0);
ccv_sample_up(image, &x, 0, 0, 0);
printf("elpased time : %d\n", get_current_time() - elapsed_time);
int len;
ccv_serialize(x, argv[2], &len, CCV_SERIAL_JPEG_FILE, 0);
Expand Down

0 comments on commit 1f2854c

Please sign in to comment.