Skip to content

Commit

Permalink
fixes to ccv_basic.c so that ccv_dpm.c can run
Browse files Browse the repository at this point in the history
ccv_dpm.c now runs with root classifier. ccv_basic.c used to have
some problems with the new ccv_hog, this should be fixed. Also,
ccv_matrix_renew now asserts the invalid output matrix rather than
silently free one and allocate a new one (previous behavior is very
dangerous, could result double free or worse). ccv_sobel, ccv_gradient
now supports multi-channel, this may have slight performance impact, but
should give better result for ccv_dpm.c.
  • Loading branch information
liuliu committed Apr 1, 2012
1 parent 4c5b3bb commit dea0b18
Show file tree
Hide file tree
Showing 12 changed files with 330 additions and 186 deletions.
1 change: 1 addition & 0 deletions bin/bbfdetect.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ int main(int argc, char** argv)
file[len] = '\0';
image = 0;
ccv_read(file, &image, CCV_IO_GRAY | CCV_IO_ANY_FILE);
assert(image != 0);
ccv_bbf_param_t params = { .interval = 5, .min_neighbors = 2, .flags = 0, .size = ccv_size(24, 24) };
ccv_array_t* seq = ccv_bbf_detect_objects(image, &cascade, 1, params);
for (i = 0; i < seq->rnum; i++)
Expand Down
23 changes: 14 additions & 9 deletions bin/dpmdetect.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,26 @@ int main(int argc, char** argv)
int i;
ccv_enable_default_cache();
ccv_dense_matrix_t* image = 0;
ccv_read(argv[1], &image, CCV_IO_GRAY | CCV_IO_ANY_FILE);
ccv_dpm_root_classifier_t* root_classifier = ccv_load_dpm_root_classifier(argv[2]);
ccv_read(argv[1], &image, CCV_IO_ANY_FILE);
ccv_dpm_mixture_model_t* model = ccv_load_dpm_mixture_model(argv[2]);
if (image != 0)
{
unsigned int elapsed_time = get_current_time();
ccv_dpm_param_t params = { .interval = 5, .min_neighbors = 2, .flags = 0, .size = ccv_size(root_classifier->root.size.width * 8, root_classifier->root.size.height * 8) };
ccv_array_t* seq = ccv_dpm_detect_objects(image, &root_classifier, 1, params);
ccv_dpm_param_t params = { .interval = 5, .min_neighbors = 2, .flags = 0 };
ccv_array_t* seq = ccv_dpm_detect_objects(image, &model, 1, params);
elapsed_time = get_current_time() - elapsed_time;
for (i = 0; i < seq->rnum; i++)
if (seq)
{
ccv_comp_t* comp = (ccv_comp_t*)ccv_array_get(seq, i);
printf("%d %d %d %d %f\n", comp->rect.x, comp->rect.y, comp->rect.width, comp->rect.height, comp->confidence);
for (i = 0; i < seq->rnum; i++)
{
ccv_comp_t* comp = (ccv_comp_t*)ccv_array_get(seq, i);
printf("%d %d %d %d %f\n", comp->rect.x, comp->rect.y, comp->rect.width, comp->rect.height, comp->confidence);
}
printf("total : %d in time %dms\n", seq->rnum, elapsed_time);
ccv_array_free(seq);
} else {
printf("elapsed time %dms\n", elapsed_time);
}
printf("total : %d in time %dms\n", seq->rnum, elapsed_time);
ccv_array_free(seq);
ccv_matrix_free(image);
}
ccv_drain_cache();
Expand Down
2 changes: 1 addition & 1 deletion bin/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ CC = clang
LDFLAGS = -L"../lib" -lccv -pthread -ljpeg -lpng -lfftw3 -lz -lgsl -lblas -lm # -lgomp # -lOpenCL -L"/opt/ati-stream-sdk/lib/x86_64"
CXXFLAGS = -O3 -msse2 -Wall -I"../lib" # -fopenmp -D USE_OPENMP # -D USE_OPENCL

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

all: libccv.a $(TARGETS)

Expand Down
45 changes: 27 additions & 18 deletions lib/ccv.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@ enum {
CCV_MATRIX_CSC = 0x080000,
};

#define CCV_GARBAGE (0x80000000) // matrix is in cache (not used by any functions)
#define CCV_REUSABLE (0x40000000) // matrix can be recycled
#define CCV_UNMANAGED (0x20000000) // matrix is allocated by user, therefore, cannot be freed by ccv_matrix_free/ccv_matrix_free_immediately
enum {
CCV_GARBAGE = 0x80000000, // matrix is in cache (not used by any functions)
CCV_REUSABLE = 0x40000000, // matrix can be recycled
CCV_UNMANAGED = 0x20000000, // matrix is allocated by user, therefore, cannot be freed by ccv_matrix_free/ccv_matrix_free_immediately
};

typedef union {
unsigned char* u8;
Expand Down Expand Up @@ -133,9 +135,10 @@ extern int _ccv_get_sparse_prime[];

typedef void ccv_matrix_t;

/* the explicit cache mechanism */
/* the explicit cache mechanism ccv_cache.c */
/* the new cache is radix tree based, but has a strict memory usage upper bound
* so that you don't have to explicitly call ccv_drain_cache() every time */

typedef void(*ccv_cache_index_free_f)(void*);

typedef union {
Expand All @@ -161,6 +164,7 @@ typedef struct {
} ccv_cache_t;

/* I made it as generic as possible */

void ccv_cache_init(ccv_cache_t* cache, ccv_cache_index_free_f ffree, size_t up);
void* ccv_cache_get(ccv_cache_t* cache, uint64_t sign);
int ccv_cache_put(ccv_cache_t* cache, uint64_t sign, void* x, uint32_t size);
Expand Down Expand Up @@ -195,7 +199,7 @@ typedef struct {
#define ccv_min(a, b) (((a) < (b)) ? (a) : (b))
#define ccv_max(a, b) (((a) > (b)) ? (a) : (b))

/* matrix operations */
/* matrix memory operations ccv_memory.c */
#define ccv_compute_dense_matrix_size(rows, cols, type) (sizeof(ccv_dense_matrix_t) + (((cols) * CCV_GET_DATA_TYPE_SIZE(type) * CCV_GET_CHANNEL(type) + 3) & -4) * (rows))
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);
Expand All @@ -204,12 +208,6 @@ ccv_sparse_matrix_t* ccv_sparse_matrix_new(int rows, int cols, int type, int maj
void ccv_matrix_free_immediately(ccv_matrix_t* mat);
void ccv_matrix_free(ccv_matrix_t* mat);

/* with the help of the above macros, there is rare that you need to use ccv_matrix_generate_signature
* directly. Here is how you can use above macro to generate signature from function input parameters:
* ccv_declare_matrix_signature(sig,
* ccv_sign_with_format(64, "function_name(%f,%f,%f)", a_parameter, b_parameter, c_parameter),
* da->sig, 0);
* However, there is one gotcha, you cannot separate line as above. */
uint64_t ccv_matrix_generate_signature(const char* msg, int len, uint64_t sig_start, ...);

#define CCV_DEFAULT_CACHE_SIZE (1024 * 1024 * 64)
Expand Down Expand Up @@ -248,6 +246,7 @@ void ccv_enable_cache(size_t size);
default: ((unsigned char*)(ptr))[(i)] = ccv_clamp((int)(value) >> factor, 0, 255); }

/* basic io */

enum {
CCV_IO_GRAY = 0x100,
CCV_IO_COLOR = 0x300,
Expand All @@ -273,7 +272,8 @@ enum {
int ccv_read(const char* in, ccv_dense_matrix_t** x, int type);
int ccv_write(ccv_dense_matrix_t* mat, char* out, int* len, int type, void* conf);

/* basic algebra algorithm */
/* basic algebra algorithms ccv_algebra.c */

double ccv_trace(ccv_matrix_t* mat);

enum {
Expand All @@ -296,8 +296,6 @@ 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);
void ccv_zero(ccv_matrix_t* mat);
void ccv_shift(ccv_matrix_t* a, ccv_matrix_t** b, int type, int lr, int rr);
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 All @@ -309,19 +307,25 @@ enum {

void ccv_gemm(ccv_matrix_t* a, ccv_matrix_t* b, double alpha, ccv_matrix_t* c, double beta, int transpose, ccv_matrix_t** d, int type);

/* matrix build blocks */
/* matrix build blocks / utility functions ccv_util.c */

ccv_dense_matrix_t* ccv_get_dense_matrix(ccv_matrix_t* mat);
ccv_sparse_matrix_t* ccv_get_sparse_matrix(ccv_matrix_t* mat);
ccv_dense_vector_t* ccv_get_sparse_matrix_vector(ccv_sparse_matrix_t* mat, int index);
ccv_matrix_cell_t ccv_get_sparse_matrix_cell(ccv_sparse_matrix_t* mat, int row, int col);
void ccv_set_sparse_matrix_cell(ccv_sparse_matrix_t* mat, int row, int col, void* data);
void ccv_compress_sparse_matrix(ccv_sparse_matrix_t* mat, ccv_compressed_sparse_matrix_t** csm);
void ccv_decompress_sparse_matrix(ccv_compressed_sparse_matrix_t* csm, ccv_sparse_matrix_t** smt);

void ccv_move(ccv_matrix_t* a, ccv_matrix_t** b, int btype, int y, int x);
int ccv_matrix_eq(ccv_matrix_t* a, ccv_matrix_t* b);
void ccv_slice(ccv_matrix_t* a, ccv_matrix_t** b, int type, int y, int x, int rows, int cols);
void ccv_visualize(ccv_matrix_t* a, ccv_dense_matrix_t** b, int type);
void ccv_flatten(ccv_matrix_t* a, ccv_matrix_t** b, int type, int flag);
void ccv_zero(ccv_matrix_t* mat);
void ccv_shift(ccv_matrix_t* a, ccv_matrix_t** b, int type, int lr, int rr);

/* basic data structures */
/* basic data structures ccv_util.c */

typedef struct {
int width;
Expand Down Expand Up @@ -395,13 +399,15 @@ void ccv_contour_free(ccv_contour_t* contour);
/* range: exclusive, return value: inclusive (i.e., threshold = 5, 0~5 is background, 6~range-1 is foreground */
int ccv_otsu(ccv_dense_matrix_t* a, double* outvar, int range);

/* numerical algorithms */
/* numerical algorithms ccv_numeric.c */

/* clarification about algebra and numerical algorithms:
* when using the word "algebra", I assume the operation is well established in Mathematic sense
* and can be calculated with a straight-forward, finite sequence of operation. The "numerical"
* in other word, refer to a class of algorithm that can only approximate/or iteratively found the
* solution. Thus, "invert" would be classified as numerical because of the sense that in some case,
* it can only be "approximate" (in least-square sense), so to "solve". */

void ccv_invert(ccv_matrix_t* a, ccv_matrix_t** b, int type);
void ccv_solve(ccv_matrix_t* a, ccv_matrix_t* b, ccv_matrix_t** d, int type);
void ccv_eigen(ccv_matrix_t* a, ccv_matrix_t* b, ccv_matrix_t** d, int type);
Expand All @@ -423,11 +429,13 @@ typedef double(*ccv_filter_kernel_f)(double x, double y, void*);
void ccv_filter_kernel(ccv_dense_matrix_t* x, ccv_filter_kernel_f func, void* data);

/* modern numerical algorithms */

void ccv_distance_transform(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, double dx, double dy, double dxx, double dyy, int flag);
void ccv_sparse_coding(ccv_matrix_t* x, int k, ccv_matrix_t** A, int typeA, ccv_matrix_t** y, int typey);
void ccv_compressive_sensing_reconstruct(ccv_matrix_t* a, ccv_matrix_t* x, ccv_matrix_t** y, int type);

/* basic computer vision algorithms / or build blocks */
/* basic computer vision algorithms / or build blocks ccv_basic.c */

void ccv_sobel(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, int dx, int dy);
void ccv_gradient(ccv_dense_matrix_t* a, ccv_dense_matrix_t** theta, int ttype, ccv_dense_matrix_t** m, int mtype, int dx, int dy);
void ccv_hog(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int b_type, int sbin, int size);
Expand Down Expand Up @@ -545,6 +553,7 @@ typedef struct {

typedef struct {
ccv_dense_matrix_t* w;
ccv_dense_matrix_t* feature;
double dx, dy, dxx, dyy;
int x, y, z;
} ccv_dpm_part_classifier_t;
Expand Down
6 changes: 0 additions & 6 deletions lib/ccv_algebra.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,6 @@ double ccv_sum(ccv_matrix_t* mat)
return sum;
}

void ccv_zero(ccv_matrix_t* mat)
{
ccv_dense_matrix_t* dmt = ccv_get_dense_matrix(mat);
memset(dmt->data.u8, 0, dmt->step * dmt->rows);
}

void ccv_multiply(ccv_matrix_t* a, ccv_matrix_t* b, ccv_matrix_t** c, int type)
{
ccv_dense_matrix_t* da = ccv_get_dense_matrix(a);
Expand Down
Loading

0 comments on commit dea0b18

Please sign in to comment.