Skip to content

Commit

Permalink
a workable, more robust fft-based convolution test, next diff will
Browse files Browse the repository at this point in the history
change the way fft-convolve works
  • Loading branch information
liuliu committed Mar 20, 2012
1 parent d93906e commit 25c9c75
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 20 deletions.
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 convert distance

all: libccv.a $(TARGETS)

Expand Down
5 changes: 3 additions & 2 deletions lib/ccv.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ typedef struct {
#define INTERNAL_GARBAGE_TYPEDEF_CONCATENATE(...) INTERNAL_GARBAGE_TYPEDEF_CONCATENATE_N(__VA_ARGS__)

#define INTERNAL_EXPAND_RENEW_MATRIX_LINE_N(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,_31,_32,_33,_34,_35,_36,_37,_38,_39,_40,_41,_42,_43,_44,_45,_46,_47,_48,_49,_50,_51,_52,_53,_54,_55,_56,_57,_58,_59,_60,_61,_62,_63,...) \
(_1) && (((int*)(_1))[0] &= CCV_GARBAGE);(_2) && (((int*)(_2))[0] &= CCV_GARBAGE);(_3) && (((int*)(_3))[0] &= CCV_GARBAGE);(_4) && (((int*)(_4))[0] &= CCV_GARBAGE);(_5) && (((int*)(_5))[0] &= CCV_GARBAGE);(_6) && (((int*)(_6))[0] &= CCV_GARBAGE);(_7) && (((int*)(_7))[0] &= CCV_GARBAGE);(_8) && (((int*)(_8))[0] &= CCV_GARBAGE);(_9) && (((int*)(_9))[0] &= CCV_GARBAGE);(_10) && (((int*)(_10))[0] &= CCV_GARBAGE);(_11) && (((int*)(_11))[0] &= CCV_GARBAGE);(_12) && (((int*)(_12))[0] &= CCV_GARBAGE);(_13) && (((int*)(_13))[0] &= CCV_GARBAGE);(_14) && (((int*)(_14))[0] &= CCV_GARBAGE);(_15) && (((int*)(_15))[0] &= CCV_GARBAGE);(_16) && (((int*)(_16))[0] &= CCV_GARBAGE);(_17) && (((int*)(_17))[0] &= CCV_GARBAGE);(_18) && (((int*)(_18))[0] &= CCV_GARBAGE);(_19) && (((int*)(_19))[0] &= CCV_GARBAGE);(_20) && (((int*)(_20))[0] &= CCV_GARBAGE);(_21) && (((int*)(_21))[0] &= CCV_GARBAGE);(_22) && (((int*)(_22))[0] &= CCV_GARBAGE);(_23) && (((int*)(_23))[0] &= CCV_GARBAGE);(_24) && (((int*)(_24))[0] &= CCV_GARBAGE);(_25) && (((int*)(_25))[0] &= CCV_GARBAGE);(_26) && (((int*)(_26))[0] &= CCV_GARBAGE);(_27) && (((int*)(_27))[0] &= CCV_GARBAGE);(_28) && (((int*)(_28))[0] &= CCV_GARBAGE);(_29) && (((int*)(_29))[0] &= CCV_GARBAGE);(_30) && (((int*)(_30))[0] &= CCV_GARBAGE);(_31) && (((int*)(_31))[0] &= CCV_GARBAGE);(_32) && (((int*)(_32))[0] &= CCV_GARBAGE);(_33) && (((int*)(_33))[0] &= CCV_GARBAGE);(_34) && (((int*)(_34))[0] &= CCV_GARBAGE);(_35) && (((int*)(_35))[0] &= CCV_GARBAGE);(_36) && (((int*)(_36))[0] &= CCV_GARBAGE);(_37) && (((int*)(_37))[0] &= CCV_GARBAGE);(_38) && (((int*)(_38))[0] &= CCV_GARBAGE);(_39) && (((int*)(_39))[0] &= CCV_GARBAGE);(_40) && (((int*)(_40))[0] &= CCV_GARBAGE);(_41) && (((int*)(_41))[0] &= CCV_GARBAGE);(_42) && (((int*)(_42))[0] &= CCV_GARBAGE);(_43) && (((int*)(_43))[0] &= CCV_GARBAGE);(_44) && (((int*)(_44))[0] &= CCV_GARBAGE);(_45) && (((int*)(_45))[0] &= CCV_GARBAGE);(_46) && (((int*)(_46))[0] &= CCV_GARBAGE);(_47) && (((int*)(_47))[0] &= CCV_GARBAGE);(_48) && (((int*)(_48))[0] &= CCV_GARBAGE);(_49) && (((int*)(_49))[0] &= CCV_GARBAGE);(_50) && (((int*)(_50))[0] &= CCV_GARBAGE);(_51) && (((int*)(_51))[0] &= CCV_GARBAGE);(_52) && (((int*)(_52))[0] &= CCV_GARBAGE);(_53) && (((int*)(_53))[0] &= CCV_GARBAGE);(_54) && (((int*)(_54))[0] &= CCV_GARBAGE);(_55) && (((int*)(_55))[0] &= CCV_GARBAGE);(_56) && (((int*)(_56))[0] &= CCV_GARBAGE);(_57) && (((int*)(_57))[0] &= CCV_GARBAGE);(_58) && (((int*)(_58))[0] &= CCV_GARBAGE);(_59) && (((int*)(_59))[0] &= CCV_GARBAGE);(_60) && (((int*)(_60))[0] &= CCV_GARBAGE);(_61) && (((int*)(_61))[0] &= CCV_GARBAGE);(_62) && (((int*)(_62))[0] &= CCV_GARBAGE);(_63) && (((int*)(_63))[0] &= CCV_GARBAGE);
(void)((_1) && (((int*)(_1))[0] &= CCV_GARBAGE));(void)((_2) && (((int*)(_2))[0] &= CCV_GARBAGE));(void)((_3) && (((int*)(_3))[0] &= CCV_GARBAGE));(void)((_4) && (((int*)(_4))[0] &= CCV_GARBAGE));(void)((_5) && (((int*)(_5))[0] &= CCV_GARBAGE));(void)((_6) && (((int*)(_6))[0] &= CCV_GARBAGE));(void)((_7) && (((int*)(_7))[0] &= CCV_GARBAGE));(void)((_8) && (((int*)(_8))[0] &= CCV_GARBAGE));(void)((_9) && (((int*)(_9))[0] &= CCV_GARBAGE));(void)((_10) && (((int*)(_10))[0] &= CCV_GARBAGE));(void)((_11) && (((int*)(_11))[0] &= CCV_GARBAGE));(void)((_12) && (((int*)(_12))[0] &= CCV_GARBAGE));(void)((_13) && (((int*)(_13))[0] &= CCV_GARBAGE));(void)((_14) && (((int*)(_14))[0] &= CCV_GARBAGE));(void)((_15) && (((int*)(_15))[0] &= CCV_GARBAGE));(void)((_16) && (((int*)(_16))[0] &= CCV_GARBAGE));(void)((_17) && (((int*)(_17))[0] &= CCV_GARBAGE));(void)((_18) && (((int*)(_18))[0] &= CCV_GARBAGE));(void)((_19) && (((int*)(_19))[0] &= CCV_GARBAGE));(void)((_20) && (((int*)(_20))[0] &= CCV_GARBAGE));(void)((_21) && (((int*)(_21))[0] &= CCV_GARBAGE));(void)((_22) && (((int*)(_22))[0] &= CCV_GARBAGE));(void)((_23) && (((int*)(_23))[0] &= CCV_GARBAGE));(void)((_24) && (((int*)(_24))[0] &= CCV_GARBAGE));(void)((_25) && (((int*)(_25))[0] &= CCV_GARBAGE));(void)((_26) && (((int*)(_26))[0] &= CCV_GARBAGE));(void)((_27) && (((int*)(_27))[0] &= CCV_GARBAGE));(void)((_28) && (((int*)(_28))[0] &= CCV_GARBAGE));(void)((_29) && (((int*)(_29))[0] &= CCV_GARBAGE));(void)((_30) && (((int*)(_30))[0] &= CCV_GARBAGE));(void)((_31) && (((int*)(_31))[0] &= CCV_GARBAGE));(void)((_32) && (((int*)(_32))[0] &= CCV_GARBAGE));(void)((_33) && (((int*)(_33))[0] &= CCV_GARBAGE));(void)((_34) && (((int*)(_34))[0] &= CCV_GARBAGE));(void)((_35) && (((int*)(_35))[0] &= CCV_GARBAGE));(void)((_36) && (((int*)(_36))[0] &= CCV_GARBAGE));(void)((_37) && (((int*)(_37))[0] &= CCV_GARBAGE));(void)((_38) && (((int*)(_38))[0] &= CCV_GARBAGE));(void)((_39) && (((int*)(_39))[0] &= CCV_GARBAGE));(void)((_40) && (((int*)(_40))[0] &= CCV_GARBAGE));(void)((_41) && (((int*)(_41))[0] &= CCV_GARBAGE));(void)((_42) && (((int*)(_42))[0] &= CCV_GARBAGE));(void)((_43) && (((int*)(_43))[0] &= CCV_GARBAGE));(void)((_44) && (((int*)(_44))[0] &= CCV_GARBAGE));(void)((_45) && (((int*)(_45))[0] &= CCV_GARBAGE));(void)((_46) && (((int*)(_46))[0] &= CCV_GARBAGE));(void)((_47) && (((int*)(_47))[0] &= CCV_GARBAGE));(void)((_48) && (((int*)(_48))[0] &= CCV_GARBAGE));(void)((_49) && (((int*)(_49))[0] &= CCV_GARBAGE));(void)((_50) && (((int*)(_50))[0] &= CCV_GARBAGE));(void)((_51) && (((int*)(_51))[0] &= CCV_GARBAGE));(void)((_52) && (((int*)(_52))[0] &= CCV_GARBAGE));(void)((_53) && (((int*)(_53))[0] &= CCV_GARBAGE));(void)((_54) && (((int*)(_54))[0] &= CCV_GARBAGE));(void)((_55) && (((int*)(_55))[0] &= CCV_GARBAGE));(void)((_56) && (((int*)(_56))[0] &= CCV_GARBAGE));(void)((_57) && (((int*)(_57))[0] &= CCV_GARBAGE));(void)((_58) && (((int*)(_58))[0] &= CCV_GARBAGE));(void)((_59) && (((int*)(_59))[0] &= CCV_GARBAGE));(void)((_60) && (((int*)(_60))[0] &= CCV_GARBAGE));(void)((_61) && (((int*)(_61))[0] &= CCV_GARBAGE));(void)((_62) && (((int*)(_62))[0] &= CCV_GARBAGE));(void)((_63) && (((int*)(_63))[0] &= CCV_GARBAGE));
#define INTERNAL_EXPAND_RENEW_MATRIX_LINE(...) INTERNAL_EXPAND_RENEW_MATRIX_LINE_N(__VA_ARGS__)

#define INTERNAL_SEQ_PADDING_ZERO() 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
Expand Down Expand Up @@ -549,6 +549,7 @@ 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);

enum {
Expand Down Expand Up @@ -668,7 +669,7 @@ typedef struct {
typedef int(*ccv_minimize_f)(const ccv_dense_matrix_t* x, double* f, ccv_dense_matrix_t* df, void*);
void ccv_minimize(ccv_dense_matrix_t* x, int length, double red, ccv_minimize_f func, ccv_minimize_param_t params, void* data);

void ccv_filter(ccv_matrix_t* a, ccv_matrix_t* b, ccv_matrix_t** d, int type);
void ccv_filter(ccv_dense_matrix_t* a, ccv_dense_matrix_t* b, ccv_dense_matrix_t** d, int type);
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);

Expand Down
29 changes: 29 additions & 0 deletions lib/ccv_algebra.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,35 @@ void ccv_zero(ccv_matrix_t* mat)
memset(dmt->data.ptr, 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);
ccv_dense_matrix_t* db = ccv_get_dense_matrix(b);
assert(da->rows == db->rows && da->cols == db->cols && CCV_GET_DATA_TYPE(da->type) == CCV_GET_DATA_TYPE(db->type) && CCV_GET_CHANNEL(da->type) == CCV_GET_CHANNEL(db->type));
ccv_declare_matrix_signature(sig, da->sig != 0 && db->sig != 0, ccv_sign_with_literal("ccv_multiply"), da->sig, db->sig, 0);
int no_8u_type = (da->type & CCV_8U) ? CCV_32S : da->type;
type = (type == 0) ? CCV_GET_DATA_TYPE(no_8u_type) | CCV_GET_CHANNEL(da->type) : CCV_GET_DATA_TYPE(type) | CCV_GET_CHANNEL(da->type);
ccv_dense_matrix_t* dc = *c = ccv_dense_matrix_renew(*c, da->rows, da->cols, CCV_ALL_DATA_TYPE | CCV_GET_CHANNEL(da->type), type, sig);
ccv_matrix_return_if_cached(, dc);
int i, j;
unsigned char* aptr = da->data.ptr;
unsigned char* bptr = db->data.ptr;
unsigned char* cptr = dc->data.ptr;
#define for_block(_for_get, _for_set) \
for (i = 0; i < da->rows; i++) \
{ \
for (j = 0; j < da->cols; j++) \
{ \
_for_set(cptr, j, _for_get(aptr, j, 0) * _for_get(bptr, j, 0), 0); \
} \
aptr += da->step; \
bptr += db->step; \
cptr += dc->step; \
}
ccv_matrix_getter(da->type, ccv_matrix_setter, dc->type, for_block);
#undef for_block
}

void ccv_substract(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
20 changes: 9 additions & 11 deletions lib/ccv_numeric.c
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ static void _ccv_filter_fftw(ccv_dense_matrix_t* a, ccv_dense_matrix_t* b, ccv_d
{
int y = (i + rows_bc) % rows;
for (j = 0; j < b->cols; j++)
for (k = 0; i < ch; k++)
for (k = 0; k < ch; k++)
fftw_b[y * cols_2c * ch + ((j + cols_bc) % cols) * ch + k] = ccv_get_dense_matrix_cell_value(b, i, j, k);
}
}
Expand Down Expand Up @@ -657,13 +657,11 @@ void _ccv_filter_direct_8u(ccv_dense_matrix_t* a, ccv_dense_matrix_t* b, ccv_den
ccv_matrix_free(pa);
}

void ccv_filter(ccv_matrix_t* a, ccv_matrix_t* b, ccv_matrix_t** d, int type)
void ccv_filter(ccv_dense_matrix_t* a, ccv_dense_matrix_t* b, ccv_dense_matrix_t** d, int type)
{
ccv_dense_matrix_t* da = ccv_get_dense_matrix(a);
ccv_dense_matrix_t* db = ccv_get_dense_matrix(b);
uint64_t sig = (da->sig == 0 || db->sig == 0) ? 0 : ccv_matrix_generate_signature("ccv_filter", 10, da->sig, db->sig, 0);
type = (type == 0) ? CCV_GET_DATA_TYPE(da->type) | CCV_GET_CHANNEL(da->type) : CCV_GET_DATA_TYPE(type) | CCV_GET_CHANNEL(da->type);
ccv_dense_matrix_t* dd = *d = ccv_dense_matrix_renew(*d, da->rows, da->cols, CCV_ALL_DATA_TYPE | CCV_GET_CHANNEL(da->type), type, sig);
ccv_declare_matrix_signature(sig, a->sig != 0 && b->sig != 0, ccv_sign_with_literal("ccv_filter"), a->sig, b->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* dd = *d = ccv_dense_matrix_renew(*d, a->rows, a->cols, CCV_ALL_DATA_TYPE | CCV_GET_CHANNEL(a->type), type, sig);
ccv_matrix_return_if_cached(, dd);

/* 15 is the constant to indicate the high cost of FFT (even with O(nlog(m)) for
Expand All @@ -674,14 +672,14 @@ void ccv_filter(ccv_matrix_t* a, ccv_matrix_t* b, ccv_matrix_t** d, int type)
* to do FFT for the whole image. The image can be divided to n/m part, and
* the FFT itself is O(mlog(m)), so, the convolution process has time complexity
* of O(nlog(m)) */
if ((db->rows * db->cols < (log((double)(db->rows * db->cols)) + 1) * 15) && (da->type & CCV_8U))
if ((b->rows * b->cols < (log((double)(b->rows * b->cols)) + 1) * 15) && (a->type & CCV_8U))
{
_ccv_filter_direct_8u(da, db, dd);
_ccv_filter_direct_8u(a, b, dd);
} else {
#ifdef HAVE_FFTW3
_ccv_filter_fftw(da, db, dd);
_ccv_filter_fftw(a, b, dd);
#else
_ccv_filter_kissfft(da, db, dd);
_ccv_filter_kissfft(a, b, dd);
#endif
}
}
Expand Down
13 changes: 7 additions & 6 deletions lib/io/_ccv_io_libpng.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,20 @@ static void _ccv_read_png_fd(FILE* in, ccv_dense_matrix_t** x, int type)
{
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
png_infop info_ptr = png_create_info_struct(png_ptr);
png_infop end_info = png_create_info_struct(png_ptr);
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
png_destroy_read_struct(&png_ptr, &info_ptr, 0);
return;
}
png_init_io(png_ptr, in);
png_read_info(png_ptr, info_ptr);
png_uint_32 width, height;
int bit_depth, color_type;
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0);

ccv_dense_matrix_t* im = *x;
if (im == 0)
*x = im = ccv_dense_matrix_new((int) height, (int) width, (type) ? type : CCV_8U | ((color_type == PNG_COLOR_TYPE_GRAY) ? CCV_C1 : CCV_C3), 0, 0);
*x = im = ccv_dense_matrix_new((int) height, (int) width, (type) ? type : CCV_8U | (((color_type & PNG_COLOR_MASK_COLOR) == PNG_COLOR_TYPE_GRAY) ? CCV_C1 : CCV_C3), 0, 0);

png_set_strip_alpha(png_ptr);
if (color_type == PNG_COLOR_TYPE_PALETTE)
Expand All @@ -28,14 +27,16 @@ static void _ccv_read_png_fd(FILE* in, ccv_dense_matrix_t** x, int type)
else if (CCV_GET_CHANNEL(im->type) == CCV_C1)
png_set_rgb_to_gray(png_ptr, 1, -1, -1);

png_read_update_info(png_ptr, info_ptr);

unsigned char** row_vectors = (unsigned char**)alloca(im->rows * sizeof(unsigned char*));
int i;
for (i = 0; i < im->rows; i++)
row_vectors[i] = im->data.ptr + i * im->step;
png_read_image(png_ptr, row_vectors);
png_read_end(png_ptr, end_info);
png_read_end(png_ptr, 0);

png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
png_destroy_read_struct(&png_ptr, &info_ptr, 0);
}

static void _ccv_write_png_fd(ccv_dense_matrix_t* mat, FILE* fd, void* conf)
Expand Down

0 comments on commit 25c9c75

Please sign in to comment.