ccv.h
Go to the documentation of this file.
00001 /**********************************************************
00002  * C-based/Cached/Core Computer Vision Library
00003  * Liu Liu, 2010-02-01
00004  **********************************************************/
00005 
00006 #ifndef GUARD_ccv_h
00007 #define GUARD_ccv_h
00008 
00009 #include <unistd.h>
00010 #include <stdint.h>
00011 #include <stdio.h>
00012 #include <stdlib.h>
00013 #include <stdarg.h>
00014 #include <string.h>
00015 #include <float.h>
00016 #include <math.h>
00017 #ifdef HAVE_SSE2
00018 #include <xmmintrin.h>
00019 #endif
00020 #include <assert.h>
00021 #include <alloca.h>
00022 
00023 #define CCV_PI (3.141592653589793)
00024 #define ccmalloc malloc
00025 #define ccrealloc realloc
00026 #define ccfree free
00027 
00028 enum {
00029         CCV_8U  = 0x0100,
00030         CCV_32S = 0x0200,
00031         CCV_32F = 0x0400,
00032         CCV_64S = 0x0800,
00033         CCV_64F = 0x1000,
00034 };
00035 
00036 enum {
00037         CCV_C1 = 0x01,
00038         CCV_C2 = 0x02,
00039         CCV_C3 = 0x03,
00040         CCV_C4 = 0x04,
00041 };
00042 
00043 static const int _ccv_get_data_type_size[] = { -1, 1, 4, -1, 4, -1, -1, -1, 8, -1, -1, -1, -1, -1, -1, -1, 8 };
00044 
00045 #define CCV_GET_DATA_TYPE(x) ((x) & 0xFF00)
00046 #define CCV_GET_DATA_TYPE_SIZE(x) _ccv_get_data_type_size[CCV_GET_DATA_TYPE(x) >> 8]
00047 #define CCV_MAX_CHANNEL (0xFF)
00048 #define CCV_GET_CHANNEL(x) ((x) & 0xFF)
00049 #define CCV_ALL_DATA_TYPE (CCV_8U | CCV_32S | CCV_32F | CCV_64S | CCV_64F)
00050 
00051 enum {
00052         CCV_MATRIX_DENSE  = 0x010000,
00053         CCV_MATRIX_SPARSE = 0x020000,
00054         CCV_MATRIX_CSR    = 0x040000,
00055         CCV_MATRIX_CSC    = 0x080000,
00056 };
00057 
00058 enum {
00059         CCV_GARBAGE       = 0x80000000, // matrix is in cache (not used by any functions)
00060         CCV_REUSABLE      = 0x40000000, // matrix can be recycled
00061         CCV_UNMANAGED     = 0x20000000, // matrix is allocated by user, therefore, cannot be freed by ccv_matrix_free/ccv_matrix_free_immediately
00062         CCV_NO_DATA_ALLOC = 0x10000000, // matrix is allocated as header only, but with no data section, therefore, you have to free the data section separately
00063 };
00064 
00065 typedef union {
00066         unsigned char* u8;
00067         int* i32;
00068         float* f32;
00069         int64_t* i64;
00070         double* f64;
00071 } ccv_matrix_cell_t;
00072 
00073 typedef struct {
00074         int type;
00075         uint64_t sig;
00076         int refcount;
00077         int rows;
00078         int cols;
00079         int step;
00080         union {
00081                 unsigned char u8;
00082                 int i32;
00083                 float f32;
00084                 int64_t i64;
00085                 double f64;
00086                 void* p;
00087         } tag;
00088         ccv_matrix_cell_t data;
00089 } ccv_dense_matrix_t;
00090 
00091 enum {
00092         CCV_SPARSE_VECTOR = 0x00100000,
00093         CCV_DENSE_VECTOR  = 0x00200000,
00094 };
00095 
00096 typedef struct ccv_dense_vector_t {
00097         int step;
00098         int length;
00099         int index;
00100         int prime;
00101         int load_factor;
00102         ccv_matrix_cell_t data;
00103         int* indice;
00104         struct ccv_dense_vector_t* next;
00105 } ccv_dense_vector_t;
00106 
00107 enum {
00108         CCV_SPARSE_ROW_MAJOR = 0x00,
00109         CCV_SPARSE_COL_MAJOR = 0x01,
00110 };
00111 
00112 typedef struct {
00113         int type;
00114         uint64_t sig;
00115         int refcount;
00116         int rows;
00117         int cols;
00118         int major;
00119         int prime;
00120         int load_factor;
00121         union {
00122                 unsigned char chr;
00123                 int i;
00124                 float fl;
00125                 int64_t l;
00126                 double db;
00127         } tag;
00128         ccv_dense_vector_t* vector;
00129 } ccv_sparse_matrix_t;
00130 
00131 extern int _ccv_get_sparse_prime[];
00132 #define CCV_GET_SPARSE_PRIME(x) _ccv_get_sparse_prime[(x)]
00133 
00134 typedef void ccv_matrix_t;
00135 
00136 /* the explicit cache mechanism ccv_cache.c */
00137 /* the new cache is radix tree based, but has a strict memory usage upper bound
00138  * so that you don't have to explicitly call ccv_drain_cache() every time */
00139 
00140 typedef void(*ccv_cache_index_free_f)(void*);
00141 
00142 typedef union {
00143         struct {
00144                 uint64_t bitmap;
00145                 uint64_t set;
00146                 uint64_t age;
00147         } branch;
00148         struct {
00149                 uint64_t sign;
00150                 uint64_t off;
00151                 uint64_t type;
00152         } terminal;
00153 } ccv_cache_index_t;
00154 
00155 typedef struct {
00156         ccv_cache_index_t origin;
00157         uint32_t rnum;
00158         uint32_t age;
00159         size_t up;
00160         size_t size;
00161         ccv_cache_index_free_f ffree[16];
00162 } ccv_cache_t;
00163 
00164 /* I made it as generic as possible */
00165 
00166 void ccv_cache_init(ccv_cache_t* cache, size_t up, int cache_types, ccv_cache_index_free_f ffree, ...);
00167 void* ccv_cache_get(ccv_cache_t* cache, uint64_t sign, uint8_t* type);
00168 int ccv_cache_put(ccv_cache_t* cache, uint64_t sign, void* x, uint32_t size, uint8_t type);
00169 void* ccv_cache_out(ccv_cache_t* cache, uint64_t sign, uint8_t* type);
00170 int ccv_cache_delete(ccv_cache_t* cache, uint64_t sign);
00171 void ccv_cache_cleanup(ccv_cache_t* cache);
00172 void ccv_cache_close(ccv_cache_t* cache);
00173 
00174 /* deprecated methods, often these implemented in another way and no longer suitable for newer computer architecture */
00175 /* 0 */
00176 
00177 typedef struct {
00178         int type;
00179         uint64_t sig;
00180         int refcount;
00181         int rows;
00182         int cols;
00183         int nnz;
00184         union {
00185                 unsigned char chr;
00186                 int i;
00187                 float fl;
00188                 int64_t l;
00189                 double db;
00190         } tag;
00191         int* index;
00192         int* offset;
00193         ccv_matrix_cell_t data;
00194 } ccv_compressed_sparse_matrix_t;
00195 
00196 #define ccv_clamp(x, a, b) (((x) < (a)) ? (a) : (((x) > (b)) ? (b) : (x)))
00197 #define ccv_min(a, b) (((a) < (b)) ? (a) : (b))
00198 #define ccv_max(a, b) (((a) > (b)) ? (a) : (b))
00199 
00200 /* matrix memory operations ccv_memory.c */
00201 #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))
00202 ccv_dense_matrix_t* __attribute__((warn_unused_result)) ccv_dense_matrix_renew(ccv_dense_matrix_t* x, int rows, int cols, int types, int prefer_type, uint64_t sig);
00203 ccv_dense_matrix_t* __attribute__((warn_unused_result)) ccv_dense_matrix_new(int rows, int cols, int type, void* data, uint64_t sig);
00204 ccv_dense_matrix_t ccv_dense_matrix(int rows, int cols, int type, void* data, uint64_t sig);
00205 void ccv_make_matrix_mutable(ccv_matrix_t* mat);
00206 void ccv_make_matrix_immutable(ccv_matrix_t* mat);
00207 ccv_sparse_matrix_t* __attribute__((warn_unused_result)) ccv_sparse_matrix_new(int rows, int cols, int type, int major, uint64_t sig);
00208 void ccv_matrix_free_immediately(ccv_matrix_t* mat);
00209 void ccv_matrix_free(ccv_matrix_t* mat);
00210 
00211 uint64_t ccv_cache_generate_signature(const char* msg, int len, uint64_t sig_start, ...);
00212 
00213 #define CCV_DEFAULT_CACHE_SIZE (1024 * 1024 * 64)
00214 
00215 void ccv_drain_cache(void);
00216 void ccv_disable_cache(void);
00217 void ccv_enable_default_cache(void);
00218 void ccv_enable_cache(size_t size);
00219 
00220 #define ccv_get_dense_matrix_cell_by(type, x, row, col, ch) \
00221         (((type) & CCV_32S) ? (void*)((x)->data.i32 + ((row) * (x)->cols + (col)) * CCV_GET_CHANNEL(type) + (ch)) : \
00222         (((type) & CCV_32F) ? (void*)((x)->data.f32+ ((row) * (x)->cols + (col)) * CCV_GET_CHANNEL(type) + (ch)) : \
00223         (((type) & CCV_64S) ? (void*)((x)->data.i64+ ((row) * (x)->cols + (col)) * CCV_GET_CHANNEL(type) + (ch)) : \
00224         (((type) & CCV_64F) ? (void*)((x)->data.f64 + ((row) * (x)->cols + (col)) * CCV_GET_CHANNEL(type) + (ch)) : \
00225         (void*)((x)->data.u8 + (row) * (x)->step + (col) * CCV_GET_CHANNEL(type) + (ch))))))
00226 
00227 #define ccv_get_dense_matrix_cell(x, row, col, ch) ccv_get_dense_matrix_cell_by((x)->type, x, row, col, ch)
00228 
00229 /* this is for simplicity in code, I am sick of x->data.f64[i * x->cols + j] stuff, this is clearer, and compiler
00230  * can optimize away the if structures */
00231 #define ccv_get_dense_matrix_cell_value_by(type, x, row, col, ch) \
00232         (((type) & CCV_32S) ? (x)->data.i32[((row) * (x)->cols + (col)) * CCV_GET_CHANNEL(type) + (ch)] : \
00233         (((type) & CCV_32F) ? (x)->data.f32[((row) * (x)->cols + (col)) * CCV_GET_CHANNEL(type) + (ch)] : \
00234         (((type) & CCV_64S) ? (x)->data.i64[((row) * (x)->cols + (col)) * CCV_GET_CHANNEL(type) + (ch)] : \
00235         (((type) & CCV_64F) ? (x)->data.f64[((row) * (x)->cols + (col)) * CCV_GET_CHANNEL(type) + (ch)] : \
00236         (x)->data.u8[(row) * (x)->step + (col) * CCV_GET_CHANNEL(type) + (ch)]))))
00237 
00238 #define ccv_get_dense_matrix_cell_value(x, row, col, ch) ccv_get_dense_matrix_cell_value_by((x)->type, x, row, col, ch)
00239 
00240 #define ccv_get_value(type, ptr, i) \
00241         (((type) & CCV_32S) ? ((int*)(ptr))[(i)] : \
00242         (((type) & CCV_32F) ? ((float*)(ptr))[(i)] : \
00243         (((type) & CCV_64S) ? ((int64_t*)(ptr))[(i)] : \
00244         (((type) & CCV_64F) ? ((double*)(ptr))[(i)] : \
00245         ((unsigned char*)(ptr))[(i)]))))
00246 
00247 #define ccv_set_value(type, ptr, i, value, factor) switch (CCV_GET_DATA_TYPE((type))) { \
00248         case CCV_32S: ((int*)(ptr))[(i)] = (int)(value) >> factor; break; \
00249         case CCV_32F: ((float*)(ptr))[(i)] = (float)value; break; \
00250         case CCV_64S: ((int64_t*)(ptr))[(i)] = (int64_t)(value) >> factor; break; \
00251         case CCV_64F: ((double*)(ptr))[(i)] = (double)value; break; \
00252         default: ((unsigned char*)(ptr))[(i)] = ccv_clamp((int)(value) >> factor, 0, 255); }
00253 
00254 /* basic io ccv_io.c */
00255 
00256 enum {
00257         // modifier for converting to gray-scale
00258         CCV_IO_GRAY      = 0x100,
00259         // modifier for converting to color
00260         CCV_IO_RGB_COLOR = 0x300,
00261 };
00262 
00263 enum {
00264         // modifier for not copy the data over when read raw in-memory data
00265         CCV_IO_NO_COPY = 0x10000,
00266 };
00267 
00268 enum {
00269         // read self-describe in-memory data
00270         CCV_IO_ANY_STREAM     = 0x010,
00271         CCV_IO_BMP_STREAM     = 0x011,
00272         CCV_IO_JPEG_STREAM    = 0x012,
00273         CCV_IO_PNG_STREAM     = 0x013,
00274         CCV_IO_PLAIN_STREAM   = 0x014,
00275         CCV_IO_DEFLATE_STREAM = 0x015,
00276         // read self-describe on-disk data
00277         CCV_IO_ANY_FILE       = 0x020,
00278         CCV_IO_BMP_FILE       = 0x021,
00279         CCV_IO_JPEG_FILE      = 0x022,
00280         CCV_IO_PNG_FILE       = 0x023,
00281         CCV_IO_BINARY_FILE    = 0x024,
00282         // read not-self-describe in-memory data (a.k.a. raw data)
00283         // you need to specify rows, cols, or scanline for these data
00284         CCV_IO_ANY_RAW        = 0x040,
00285         CCV_IO_RGB_RAW        = 0x041,
00286         CCV_IO_RGBA_RAW       = 0x042,
00287         CCV_IO_ARGB_RAW       = 0x043,
00288         CCV_IO_BGR_RAW        = 0x044,
00289         CCV_IO_BGRA_RAW       = 0x045,
00290         CCV_IO_ABGR_RAW       = 0x046,
00291         CCV_IO_GRAY_RAW       = 0x047,
00292 };
00293 
00294 enum {
00295         CCV_IO_FINAL = 0x00,
00296         CCV_IO_CONTINUE,
00297         CCV_IO_ERROR,
00298         CCV_IO_ATTEMPTED,
00299         CCV_IO_UNKNOWN,
00300 };
00301 
00302 int ccv_read_impl(const void* in, ccv_dense_matrix_t** x, int type, int rows, int cols, int scanline);
00303 #define ccv_read_n(in, x, type, rows, cols, scanline, ...) \
00304         ccv_read_impl(in, x, type, rows, cols, scanline)
00305 #define ccv_read(in, x, type, ...) \
00306         ccv_read_n(in, x, type, ##__VA_ARGS__, 0, 0, 0)
00307 // this is a way to implement function-signature based dispatch, you can call either
00308 // ccv_read(in, x, type) or ccv_read(in, x, type, rows, cols, scanline)
00309 // notice that you can implement this with va_* functions, but that is not type-safe
00310 int ccv_write(ccv_dense_matrix_t* mat, char* out, int* len, int type, void* conf);
00311 
00312 /* basic algebra algorithms ccv_algebra.c */
00313 
00314 double ccv_trace(ccv_matrix_t* mat);
00315 
00316 enum {
00317         CCV_L1_NORM  = 0x01, // |dx| + |dy|
00318         CCV_L2_NORM  = 0x02, // sqrt(dx^2 + dy^2)
00319         CCV_GSEDT    = 0x04, // Generalized Squared Euclidean Distance Transform:
00320                                                  // a * dx + b * dy + c * dx^2 + d * dy^2, when combined with CCV_L1_NORM:
00321                                                  // a * |dx| + b * |dy| + c * dx^2 + d * dy^2
00322         CCV_NEGATIVE = 0x08, // negative distance computation (from positive (min) to negative (max))
00323         CCV_POSITIVE = 0x00, // positive distance computation (the default)
00324 };
00325 
00326 enum {
00327         CCV_NO_PADDING = 0x00,
00328         CCV_PADDING_ZERO = 0x01,
00329         CCV_PADDING_EXTEND = 0x02,
00330         CCV_PADDING_MIRROR = 0x04,
00331 };
00332 
00333 enum {
00334         CCV_SIGNED = 0x00,
00335         CCV_UNSIGNED = 0x01,
00336 };
00337 
00338 double ccv_norm(ccv_matrix_t* mat, int type);
00339 double ccv_normalize(ccv_matrix_t* a, ccv_matrix_t** b, int btype, int flag);
00340 void ccv_sat(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, int padding_pattern);
00341 double ccv_dot(ccv_matrix_t* a, ccv_matrix_t* b);
00342 double ccv_sum(ccv_matrix_t* mat, int flag);
00343 double ccv_variance(ccv_matrix_t* mat);
00344 void ccv_multiply(ccv_matrix_t* a, ccv_matrix_t* b, ccv_matrix_t** c, int type);
00345 void ccv_subtract(ccv_matrix_t* a, ccv_matrix_t* b, ccv_matrix_t** c, int type);
00346 
00347 enum {
00348         CCV_A_TRANSPOSE = 0x01,
00349         CCV_B_TRANSPOSE = 0X02,
00350         CCV_C_TRANSPOSE = 0X04,
00351 };
00352 
00353 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);
00354 
00355 /* matrix build blocks / utility functions ccv_util.c */
00356 
00357 ccv_dense_matrix_t* ccv_get_dense_matrix(ccv_matrix_t* mat);
00358 ccv_sparse_matrix_t* ccv_get_sparse_matrix(ccv_matrix_t* mat);
00359 ccv_dense_vector_t* ccv_get_sparse_matrix_vector(ccv_sparse_matrix_t* mat, int index);
00360 ccv_matrix_cell_t ccv_get_sparse_matrix_cell(ccv_sparse_matrix_t* mat, int row, int col);
00361 void ccv_set_sparse_matrix_cell(ccv_sparse_matrix_t* mat, int row, int col, void* data);
00362 void ccv_compress_sparse_matrix(ccv_sparse_matrix_t* mat, ccv_compressed_sparse_matrix_t** csm);
00363 void ccv_decompress_sparse_matrix(ccv_compressed_sparse_matrix_t* csm, ccv_sparse_matrix_t** smt);
00364 
00365 void ccv_move(ccv_matrix_t* a, ccv_matrix_t** b, int btype, int y, int x);
00366 int ccv_matrix_eq(ccv_matrix_t* a, ccv_matrix_t* b);
00367 void ccv_slice(ccv_matrix_t* a, ccv_matrix_t** b, int type, int y, int x, int rows, int cols);
00368 void ccv_visualize(ccv_matrix_t* a, ccv_dense_matrix_t** b, int type);
00369 void ccv_flatten(ccv_matrix_t* a, ccv_matrix_t** b, int type, int flag);
00370 void ccv_zero(ccv_matrix_t* mat);
00371 void ccv_shift(ccv_matrix_t* a, ccv_matrix_t** b, int type, int lr, int rr);
00372 int ccv_any_nan(ccv_matrix_t *a);
00373 
00374 /* basic data structures ccv_util.c */
00375 
00376 typedef struct {
00377         int width;
00378         int height;
00379 } ccv_size_t;
00380 
00381 inline static ccv_size_t ccv_size(int width, int height)
00382 {
00383         ccv_size_t size;
00384         size.width = width;
00385         size.height = height;
00386         return size;
00387 }
00388 
00389 inline static int ccv_size_is_zero(ccv_size_t size)
00390 {
00391         return size.width == 0 && size.height == 0;
00392 }
00393 
00394 typedef struct {
00395         int x;
00396         int y;
00397         int width;
00398         int height;
00399 } ccv_rect_t;
00400 
00401 inline static ccv_rect_t ccv_rect(int x, int y, int width, int height)
00402 {
00403         ccv_rect_t rect;
00404         rect.x = x;
00405         rect.y = y;
00406         rect.width = width;
00407         rect.height = height;
00408         return rect;
00409 }
00410 
00411 inline static int ccv_rect_is_zero(ccv_rect_t rect)
00412 {
00413         return rect.x == 0 && rect.y == 0 && rect.width == 0 && rect.height == 0;
00414 }
00415 
00416 typedef struct {
00417         int type;
00418         uint64_t sig;
00419         int refcount;
00420         int rnum;
00421         int size;
00422         int rsize;
00423         void* data;
00424 } ccv_array_t;
00425 
00426 ccv_array_t* __attribute__((warn_unused_result)) ccv_array_new(int rsize, int rnum, uint64_t sig);
00427 void ccv_array_push(ccv_array_t* array, void* r);
00428 typedef int(*ccv_array_group_f)(const void*, const void*, void*);
00429 int ccv_array_group(ccv_array_t* array, ccv_array_t** index, ccv_array_group_f gfunc, void* data);
00430 void ccv_make_array_immutable(ccv_array_t* array);
00431 void ccv_make_array_mutable(ccv_array_t* array);
00432 void ccv_array_zero(ccv_array_t* array);
00433 void ccv_array_clear(ccv_array_t* array);
00434 void ccv_array_free_immediately(ccv_array_t* array);
00435 void ccv_array_free(ccv_array_t* array);
00436 
00437 #define ccv_array_get(a, i) (((char*)((a)->data)) + (a)->rsize * (i))
00438 
00439 typedef struct {
00440         int x, y;
00441 } ccv_point_t;
00442 
00443 inline static ccv_point_t ccv_point(int x, int y)
00444 {
00445         ccv_point_t point;
00446         point.x = x;
00447         point.y = y;
00448         return point;
00449 }
00450 
00451 typedef struct {
00452         float x, y;
00453 } ccv_decimal_point_t;
00454 
00455 inline static ccv_decimal_point_t ccv_decimal_point(float x, float y)
00456 {
00457         ccv_decimal_point_t point;
00458         point.x = x;
00459         point.y = y;
00460         return point;
00461 }
00462 
00463 typedef struct {
00464         ccv_rect_t rect;
00465         int size;
00466         ccv_array_t* set;
00467         long m10, m01, m11, m20, m02;
00468 } ccv_contour_t;
00469 
00470 ccv_contour_t* ccv_contour_new(int set);
00471 void ccv_contour_push(ccv_contour_t* contour, ccv_point_t point);
00472 void ccv_contour_free(ccv_contour_t* contour);
00473 
00474 /* numerical algorithms ccv_numeric.c */
00475 
00476 /* clarification about algebra and numerical algorithms:
00477  * when using the word "algebra", I assume the operation is well established in Mathematic sense
00478  * and can be calculated with a straight-forward, finite sequence of operation. The "numerical"
00479  * in other word, refer to a class of algorithm that can only approximate/or iteratively found the
00480  * solution. Thus, "invert" would be classified as numerical because of the sense that in some case,
00481  * it can only be "approximate" (in least-square sense), so to "solve". */
00482 
00483 void ccv_invert(ccv_matrix_t* a, ccv_matrix_t** b, int type);
00484 void ccv_solve(ccv_matrix_t* a, ccv_matrix_t* b, ccv_matrix_t** d, int type);
00485 void ccv_eigen(ccv_matrix_t* a, ccv_matrix_t* b, ccv_matrix_t** d, int type);
00486 
00487 typedef struct {
00488         double interp;
00489         double extrap;
00490         int max_iter;
00491         double ratio;
00492         double rho;
00493         double sig;
00494 } ccv_minimize_param_t;
00495 
00496 typedef int(*ccv_minimize_f)(const ccv_dense_matrix_t* x, double* f, ccv_dense_matrix_t* df, void*);
00497 void ccv_minimize(ccv_dense_matrix_t* x, int length, double red, ccv_minimize_f func, ccv_minimize_param_t params, void* data);
00498 
00499 void ccv_filter(ccv_dense_matrix_t* a, ccv_dense_matrix_t* b, ccv_dense_matrix_t** d, int type, int padding_pattern);
00500 typedef double(*ccv_filter_kernel_f)(double x, double y, void*);
00501 void ccv_filter_kernel(ccv_dense_matrix_t* x, ccv_filter_kernel_f func, void* data);
00502 
00503 /* modern numerical algorithms */
00504 
00505 void ccv_distance_transform(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, ccv_dense_matrix_t** x, int x_type, ccv_dense_matrix_t** y, int y_type, double dx, double dy, double dxx, double dyy, int flag);
00506 void ccv_sparse_coding(ccv_matrix_t* x, int k, ccv_matrix_t** A, int typeA, ccv_matrix_t** y, int typey);
00507 void ccv_compressive_sensing_reconstruct(ccv_matrix_t* a, ccv_matrix_t* x, ccv_matrix_t** y, int type);
00508 
00509 /* basic computer vision algorithms / or build blocks ccv_basic.c */
00510 
00511 void ccv_sobel(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, int dx, int dy);
00512 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);
00513 
00514 enum {
00515         CCV_FLIP_X = 0x01,
00516         CCV_FLIP_Y = 0x02,
00517 };
00518 
00519 void ccv_flip(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int btype, int type);
00520 void ccv_blur(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, double sigma);
00521 
00522 enum {
00523         CCV_RGB_TO_YUV = 0x01,
00524 };
00525 
00526 void ccv_color_transform(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, int flag);
00527 
00528 /* resample algorithms ccv_resample.c */
00529 
00530 enum {
00531         CCV_INTER_AREA    = 0x01,
00532         CCV_INTER_LINEAR  = 0X02,
00533         CCV_INTER_CUBIC   = 0X04,
00534         CCV_INTER_LANCZOS = 0X08,
00535 };
00536 
00537 void ccv_resample(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int btype, int rows, int cols, int type);
00538 void ccv_sample_down(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, int src_x, int src_y);
00539 void ccv_sample_up(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, int src_x, int src_y);
00540 
00541 /* transformation algorithms ccv_transform.c */
00542 
00543 void ccv_decimal_slice(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, float y, float x, int rows, int cols);
00544 ccv_decimal_point_t ccv_perspective_transform_apply(ccv_decimal_point_t point, ccv_size_t size, float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22);
00545 void ccv_perspective_transform(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22);
00546 
00547 /* classic computer vision algorithms ccv_classic.c */
00548 
00549 void ccv_hog(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int b_type, int sbin, int size);
00550 void ccv_canny(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, int size, double low_thresh, double high_thresh);
00551 void ccv_close_outline(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type);
00552 /* range: exclusive, return value: inclusive (i.e., threshold = 5, 0~5 is background, 6~range-1 is foreground */
00553 int ccv_otsu(ccv_dense_matrix_t* a, double* outvar, int range);
00554 
00555 typedef struct {
00556         ccv_decimal_point_t point;
00557         uint8_t status;
00558 } ccv_decimal_point_with_status_t;
00559 
00560 void ccv_optical_flow_lucas_kanade(ccv_dense_matrix_t* a, ccv_dense_matrix_t* b, ccv_array_t* point_a, ccv_array_t** point_b, ccv_size_t win_size, int level, double min_eigen);
00561 
00562 /* modern computer vision algorithms */
00563 /* SIFT, DAISY, SWT, MSER, DPM, BBF, SGF, SSD, FAST */
00564 
00565 /* daisy related methods */
00566 typedef struct {
00567         double radius;
00568         int rad_q_no;
00569         int th_q_no;
00570         int hist_th_q_no;
00571         float normalize_threshold;
00572         int normalize_method;
00573 } ccv_daisy_param_t;
00574 
00575 enum {
00576         CCV_DAISY_NORMAL_PARTIAL = 0x01,
00577         CCV_DAISY_NORMAL_FULL    = 0x02,
00578         CCV_DAISY_NORMAL_SIFT    = 0x03,
00579 };
00580 
00581 void ccv_daisy(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, ccv_daisy_param_t params);
00582 
00583 /* sift related methods */
00584 typedef struct {
00585         float x, y;
00586         int octave;
00587         int level;
00588         union {
00589                 struct {
00590                         double a, b;
00591                         double c, d;
00592                 } affine;
00593                 struct {
00594                         double scale;
00595                         double angle;
00596                 } regular;
00597         };
00598 } ccv_keypoint_t;
00599 
00600 typedef struct {
00601         int up2x;
00602         int noctaves;
00603         int nlevels;
00604         float edge_threshold;
00605         float peak_threshold;
00606         float norm_threshold;
00607 } ccv_sift_param_t;
00608 
00609 extern const ccv_sift_param_t ccv_sift_default_params;
00610 
00611 void ccv_sift(ccv_dense_matrix_t* a, ccv_array_t** keypoints, ccv_dense_matrix_t** desc, int type, ccv_sift_param_t params);
00612 
00613 /* mser related method */
00614 
00615 typedef struct {
00616         /* parameters for MSER */
00617         int delta;
00618         int min_area; /* default: 60 */
00619         int direction; /* default: 0, 0 for both, -1 for bright to dark, 1 for dark to bright */
00620         int max_area;
00621         double max_variance;
00622         double min_diversity;
00623         int range; /* from 0 to range, inclusive */
00624         /* parameters for MSCR */
00625         double area_threshold; /* default: 1.01 */
00626         double min_margin; /* default: 0.003 */
00627         int max_evolution;
00628         double edge_blur_sigma; /* default: 1.0 */
00629 } ccv_mser_param_t;
00630 
00631 typedef struct {
00632         ccv_rect_t rect;
00633         int size;
00634         long m10, m01, m11, m20, m02;
00635         ccv_point_t keypoint;
00636 } ccv_mser_keypoint_t;
00637 
00638 enum {
00639         CCV_BRIGHT_TO_DARK = -1,
00640         CCV_DARK_TO_BRIGHT = 1,
00641 };
00642 
00643 ccv_array_t* __attribute__((warn_unused_result)) ccv_mser(ccv_dense_matrix_t* a, ccv_dense_matrix_t* h, ccv_dense_matrix_t** b, int type, ccv_mser_param_t params);
00644 
00645 /* swt related method: stroke width transform is relatively new, typically used in text detection */
00646 typedef struct {
00647         int interval; // for scale invariant option
00648         int min_neighbors; // minimal neighbors to make a detection valid, this is for scale-invariant version
00649         int scale_invariant; // enable scale invariant swt (to scale to different sizes and then combine the results)
00650         int direction;
00651         double same_word_thresh[2]; // overlapping more than 0.1 of the bigger one (0), and 0.9 of the smaller one (1)
00652         /* canny parameters */
00653         int size;
00654         int low_thresh;
00655         int high_thresh;
00656         /* geometry filtering parameters */
00657         int max_height;
00658         int min_height;
00659         int min_area;
00660         int letter_occlude_thresh;
00661         double aspect_ratio;
00662         double std_ratio;
00663         /* grouping parameters */
00664         double thickness_ratio;
00665         double height_ratio;
00666         int intensity_thresh;
00667         double distance_ratio;
00668         double intersect_ratio;
00669         double elongate_ratio;
00670         int letter_thresh;
00671         /* break textline into words */
00672         int breakdown;
00673         double breakdown_ratio;
00674 } ccv_swt_param_t;
00675 
00676 extern const ccv_swt_param_t ccv_swt_default_params;
00677 
00678 void ccv_swt(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, ccv_swt_param_t params);
00679 ccv_array_t* __attribute__((warn_unused_result)) ccv_swt_detect_words(ccv_dense_matrix_t* a, ccv_swt_param_t params);
00680 
00681 /* I'd like to include Deformable Part Models as a general object detection method in here
00682  * The difference between BBF and DPM:
00683  * ~ BBF is for rigid object detection: banners, box, faces etc.
00684  * ~ DPM is more generalized, can detect people, car, bike (larger inner-class difference) etc.
00685  * ~ BBF is blazing fast (few milliseconds), DPM is relatively slow (around 1 seconds or so) */
00686 
00687 #define CCV_DPM_PART_MAX (10)
00688 
00689 typedef struct {
00690         ccv_rect_t rect;
00691         int neighbors;
00692         int id;
00693         float confidence;
00694 } ccv_comp_t;
00695 
00696 typedef struct {
00697         ccv_rect_t rect;
00698         int neighbors;
00699         int id;
00700         float confidence;
00701         int pnum;
00702         ccv_comp_t part[CCV_DPM_PART_MAX];
00703 } ccv_root_comp_t;
00704 
00705 typedef struct {
00706         ccv_dense_matrix_t* w;
00707         double dx, dy, dxx, dyy;
00708         int x, y, z;
00709         int counterpart;
00710         float alpha[6];
00711 } ccv_dpm_part_classifier_t;
00712 
00713 typedef struct {
00714         int count;
00715         ccv_dpm_part_classifier_t root;
00716         ccv_dpm_part_classifier_t* part;
00717         float alpha[3], beta;
00718 } ccv_dpm_root_classifier_t;
00719 
00720 typedef struct {
00721         int count;
00722         ccv_dpm_root_classifier_t* root;
00723 } ccv_dpm_mixture_model_t;
00724 
00725 typedef struct {
00726         int interval;
00727         int min_neighbors;
00728         int flags;
00729         float threshold;
00730 } ccv_dpm_param_t;
00731 
00732 typedef struct {
00733         int components;
00734         int parts;
00735         int grayscale;
00736         int symmetric;
00737         int min_area; // 3000
00738         int max_area; // 5000
00739         int iterations;
00740         int data_minings;
00741         int root_relabels;
00742         int relabels;
00743         int discard_estimating_constant; // 1
00744         int negative_cache_size; // 1000
00745         double include_overlap; // 0.7
00746         double alpha;
00747         double alpha_ratio; // 0.85
00748         double balance; // 1.5
00749         double C;
00750         double percentile_breakdown; // 0.05
00751         ccv_dpm_param_t detector;
00752 } ccv_dpm_new_param_t;
00753 
00754 enum {
00755         CCV_DPM_NO_NESTED = 0x10000000,
00756 };
00757 
00758 extern const ccv_dpm_param_t ccv_dpm_default_params;
00759 
00760 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);
00761 ccv_array_t* __attribute__((warn_unused_result)) ccv_dpm_detect_objects(ccv_dense_matrix_t* a, ccv_dpm_mixture_model_t** model, int count, ccv_dpm_param_t params);
00762 ccv_dpm_mixture_model_t* __attribute__((warn_unused_result)) ccv_load_dpm_mixture_model(const char* directory);
00763 void ccv_dpm_mixture_model_free(ccv_dpm_mixture_model_t* model);
00764 
00765 /* this is open source implementation of object detection algorithm: brightness binary feature
00766  * it is an extension/modification of original HAAR-like feature with Adaboost, featured faster
00767  * computation and higher accuracy (current highest accuracy close-source face detector is based
00768  * on the same algorithm) */
00769 
00770 #define CCV_BBF_POINT_MAX (8)
00771 #define CCV_BBF_POINT_MIN (3)
00772 
00773 typedef struct {
00774         int size;
00775         int px[CCV_BBF_POINT_MAX];
00776         int py[CCV_BBF_POINT_MAX];
00777         int pz[CCV_BBF_POINT_MAX];
00778         int nx[CCV_BBF_POINT_MAX];
00779         int ny[CCV_BBF_POINT_MAX];
00780         int nz[CCV_BBF_POINT_MAX];
00781 } ccv_bbf_feature_t;
00782 
00783 typedef struct {
00784         int count;
00785         float threshold;
00786         ccv_bbf_feature_t* feature;
00787         float* alpha;
00788 } ccv_bbf_stage_classifier_t;
00789 
00790 typedef struct {
00791         int count;
00792         ccv_size_t size;
00793         ccv_bbf_stage_classifier_t* stage_classifier;
00794 } ccv_bbf_classifier_cascade_t;
00795 
00796 enum {
00797         CCV_BBF_GENETIC_OPT = 0x01,
00798         CCV_BBF_FLOAT_OPT = 0x02
00799 };
00800 
00801 typedef struct {
00802         int interval;
00803         int min_neighbors;
00804         int flags;
00805         int accurate;
00806         ccv_size_t size;
00807 } ccv_bbf_param_t;
00808 
00809 typedef struct {
00810         double pos_crit;
00811         double neg_crit;
00812         double balance_k;
00813         int layer;
00814         int feature_number;
00815         int optimizer;
00816         ccv_bbf_param_t detector;
00817 } ccv_bbf_new_param_t;
00818 
00819 enum {
00820         CCV_BBF_NO_NESTED = 0x10000000,
00821 };
00822 
00823 extern const ccv_bbf_param_t ccv_bbf_default_params;
00824 
00825 void ccv_bbf_classifier_cascade_new(ccv_dense_matrix_t** posimg, int posnum, char** bgfiles, int bgnum, int negnum, ccv_size_t size, const char* dir, ccv_bbf_new_param_t params);
00826 ccv_array_t* __attribute__((warn_unused_result)) ccv_bbf_detect_objects(ccv_dense_matrix_t* a, ccv_bbf_classifier_cascade_t** cascade, int count, ccv_bbf_param_t params);
00827 ccv_bbf_classifier_cascade_t* __attribute__((warn_unused_result)) ccv_load_bbf_classifier_cascade(const char* directory);
00828 ccv_bbf_classifier_cascade_t* __attribute__((warn_unused_result)) ccv_bbf_classifier_cascade_read_binary(char* s);
00829 int ccv_bbf_classifier_cascade_write_binary(ccv_bbf_classifier_cascade_t* cascade, char* s, int slen);
00830 void ccv_bbf_classifier_cascade_free(ccv_bbf_classifier_cascade_t* cascade);
00831 
00832 /* Ferns classifier: this is a fern implementation that specifically used for TLD
00833  * see: http://cvlab.epfl.ch/alumni/oezuysal/ferns.html for more about ferns */
00834 
00835 typedef struct {
00836         int structs;
00837         int features;
00838         int scales;
00839         int posteriors;
00840         float threshold;
00841         int cnum[2];
00842         int* rnum;
00843         float* posterior;
00844         // decided to go flat organized fern so that we can profiling different memory layout impacts the performance
00845         ccv_point_t fern[1];
00846 } ccv_ferns_t;
00847 
00848 ccv_ferns_t* __attribute__((warn_unused_result)) ccv_ferns_new(int structs, int features, int scales, ccv_size_t* sizes);
00849 void ccv_ferns_feature(ccv_ferns_t* ferns, ccv_dense_matrix_t* a, int scale, uint32_t* fern);
00850 void ccv_ferns_correct(ccv_ferns_t* ferns, uint32_t* fern, int c, int repeat);
00851 float ccv_ferns_predict(ccv_ferns_t* ferns, uint32_t* fern);
00852 void ccv_ferns_free(ccv_ferns_t* ferns);
00853 
00854 /* TLD: Track-Learn-Detection is a long-term object tracking framework, which achieved very high
00855  * tracking accuracy, this is the tracking algorithm of choice ccv implements */
00856 
00857 typedef struct {
00858         /* short-term lucas-kanade tracking parameters */
00859         ccv_size_t win_size;
00860         int level;
00861         float min_eigen;
00862         float min_forward_backward_error;
00863         /* image pyramid (different resolution) generation parameters */
00864         int interval;
00865         float shift;
00866         /* samples generation parameters */
00867         int min_win;
00868         float include_overlap;
00869         float exclude_overlap;
00870         /* fern classifier setting */
00871         int structs;
00872         int features;
00873         /* nearest neighbor thresholds */
00874         float validate_set; // 0.5 for conservative confidence
00875         float nnc_same; // the same object
00876         float nnc_thres; // highly correlated
00877         float nnc_verify; // correlated with tracking
00878         float nnc_beyond; // this is the cap of nnc_thres
00879         float nnc_collect; // modest correlated, worth to collect as negative example
00880         int bad_patches; // number of bad patches
00881         /* deformation round */
00882         int new_deform;
00883         int track_deform;
00884         float new_deform_angle;
00885         float track_deform_angle;
00886         float new_deform_scale;
00887         float track_deform_scale;
00888         float new_deform_shift;
00889         float track_deform_shift;
00890         /* top detections */
00891         int top_n;
00892         /* speed up technique, instead of running slide window at
00893          * every frame, we will rotate them, for example, slide window 1
00894          * only gets examined at frame % rotation == 1 */
00895         int rotation;
00896 } ccv_tld_param_t;
00897 
00898 extern const ccv_tld_param_t ccv_tld_default_params;
00899 
00900 typedef struct {
00901         ccv_tld_param_t params;
00902         ccv_comp_t box; // tracking comp
00903         ccv_ferns_t* ferns; // ferns classifier
00904         ccv_array_t* sv[2]; // example-based classifier
00905         ccv_size_t patch; // resized to patch for example-based classifier
00906         int found; // if the last time found a valid box
00907         int verified; // the last frame is verified, therefore, a successful tracking is verified too
00908         ccv_array_t* top; // top matches
00909         float ferns_thres; // computed dynamically from negative examples
00910         float nnc_thres; // computed dynamically from negative examples
00911         float nnc_verify_thres; // computed dynamically from negative examples
00912         double var_thres; // computed dynamically from the supplied same
00913         uint64_t frame_signature;
00914         int count;
00915         void* sfmt;
00916         void* dsfmt;
00917         uint32_t fern_buffer[1]; // fetched ferns from image, this is a buffer
00918 } ccv_tld_t;
00919 
00920 typedef struct {
00921         int perform_track;
00922         int perform_learn;
00923         int track_success;
00924         int ferns_detects;
00925         int nnc_detects;
00926         int clustered_detects;
00927         int confident_matches;
00928         int close_matches;
00929 } ccv_tld_info_t;
00930 
00931 ccv_tld_t* __attribute__((warn_unused_result)) ccv_tld_new(ccv_dense_matrix_t* a, ccv_rect_t box, ccv_tld_param_t params);
00932 ccv_comp_t ccv_tld_track_object(ccv_tld_t* tld, ccv_dense_matrix_t* a, ccv_dense_matrix_t* b, ccv_tld_info_t* info);
00933 void ccv_tld_free(ccv_tld_t* tld);
00934 
00935 /* modern machine learning algorithms */
00936 /* RBM, LLE, APCluster */
00937 
00938 #endif


text_locator
Author(s): Vojtech Novak
autogenerated on Mon Oct 6 2014 07:55:19