void cos_ccv_merge(ccv_dense_matrix_t* mat[], ccv_dense_matrix_t** output, int rows, int cols, int x, int y) { ccv_dense_matrix_t* merged = 0; merged = ccv_dense_matrix_new(rows, cols, mat[0]->type, 0, 0); unsigned int i; /* may not sufficient for extremely large pictures */ int slice_rows = mat[0]->rows; int slice_step= mat[0]->step; int slice_num = x * y; unsigned int pixel_num = slice_rows * slice_step; #pragma omp parallel for for (i = 0; i < slice_num; i++) { int x_offset = i % x; int y_offset = i / x; int j, mrow, mcol; for (j = 0; j < pixel_num; j++) { mrow = j / slice_step; mcol = j - slice_step * mrow; merged->data.u8[(y_offset * slice_rows + mrow) * merged->step + x_offset * slice_step + mcol] = mat[i]->data.u8[mrow * slice_step + mcol]; } } *output = merged; #ifdef DEBUG ccv_dense_matrix_t *visualized_merged = 0; ccv_visualize(merged, (ccv_matrix_t **)&visualized_merged, merged->type); ccv_write(test, "canny_final_output.jpeg", 0, CCV_IO_JPEG_FILE, 0); #endif return; }
static int _ccv_read_raw(ccv_dense_matrix_t** x, void* data, int type, int rows, int cols, int scanline) { assert(rows > 0 && cols > 0 && scanline > 0); if (type & CCV_IO_NO_COPY) { // there is no conversion that we can apply if it is NO_COPY mode // NO_COPY mode generate an "unreusable" matrix, which requires you to // manually release its data block (which is, in fact the same data // block you passed in) int ctype = CCV_8U | CCV_C1; switch (type & 0xFF) { case CCV_IO_RGB_RAW: case CCV_IO_BGR_RAW: ctype = CCV_8U | CCV_C3; break; case CCV_IO_RGBA_RAW: case CCV_IO_ARGB_RAW: case CCV_IO_BGRA_RAW: case CCV_IO_ABGR_RAW: ctype = CCV_8U | CCV_C4; break; case CCV_IO_GRAY_RAW: default: /* default one */ break; } *x = ccv_dense_matrix_new(rows, cols, ctype | CCV_NO_DATA_ALLOC, data, 0); (*x)->step = scanline; } else { switch (type & 0xFF) { case CCV_IO_RGB_RAW: _ccv_read_rgb_raw(x, data, type, rows, cols, scanline); break; case CCV_IO_RGBA_RAW: _ccv_read_rgba_raw(x, data, type, rows, cols, scanline); break; case CCV_IO_ARGB_RAW: _ccv_read_argb_raw(x, data, type, rows, cols, scanline); break; case CCV_IO_BGR_RAW: _ccv_read_bgr_raw(x, data, type, rows, cols, scanline); break; case CCV_IO_BGRA_RAW: _ccv_read_bgra_raw(x, data, type, rows, cols, scanline); break; case CCV_IO_ABGR_RAW: _ccv_read_abgr_raw(x, data, type, rows, cols, scanline); break; case CCV_IO_GRAY_RAW: _ccv_read_gray_raw(x, data, type, rows, cols, scanline); break; } } if (*x != 0) ccv_make_matrix_immutable(*x); return CCV_IO_FINAL; }
static void _ccv_read_binary_fd(FILE* in, ccv_dense_matrix_t** x, int type) { fseek(in, 8, SEEK_SET); fread(&type, 1, 4, in); int rows, cols; fread(&rows, 1, 4, in); fread(&cols, 1, 4, in); *x = ccv_dense_matrix_new(rows, cols, type, 0, 0); fread((*x)->data.u8, 1, (*x)->step * (*x)->rows, in); }
int main(int argc, char **argv) { ccv_dense_matrix_t* a = ccv_dense_matrix_new(3, 2, CCV_64F | CCV_C1, 0, 0); a->data.f64[0] = 0.11; a->data.f64[1] = 0.12; a->data.f64[2] = 0.13; a->data.f64[3] = 0.21; a->data.f64[4] = 0.22; a->data.f64[5] = 0.23; ccv_dense_matrix_t* b = ccv_dense_matrix_new(3, 2, CCV_64F | CCV_C1, 0, 0); b->data.f64[0] = 1011; b->data.f64[1] = 1012; b->data.f64[2] = 1021; b->data.f64[3] = 1022; b->data.f64[4] = 1031; b->data.f64[5] = 1032; ccv_dense_matrix_t* y = 0; ccv_gemm(a, b, 1, 0, 0, CCV_A_TRANSPOSE, (ccv_matrix_t**)&y, 0); ccv_matrix_free(a); ccv_matrix_free(b); ccv_matrix_free(y); }
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) { if (x != 0) { assert(x->rows == rows && x->cols == cols && (CCV_GET_DATA_TYPE(x->type) & types) && (CCV_GET_CHANNEL(x->type) == CCV_GET_CHANNEL(types))); prefer_type = CCV_GET_DATA_TYPE(x->type) | CCV_GET_CHANNEL(x->type); } if (sig != 0) sig = ccv_cache_generate_signature((const char*)&prefer_type, sizeof(int), sig, CCV_EOF_SIGN); if (x == 0) { x = ccv_dense_matrix_new(rows, cols, prefer_type, 0, sig); } else { x->sig = sig; } return x; }
for (i = 0; i < 1; i++) rf += 100 * (x_vec[i + 1] - x_vec[i] * x_vec[i]) * (x_vec[i + 1] - x_vec[i] * x_vec[i]) + (1 - x_vec[i]) * (1 - x_vec[i]); *f = rf; double* df_vec = df->data.f64; ccv_zero(df); df_vec[0] = df_vec[1] = 0; for (i = 0; i < 1; i++) df_vec[i] = -400 * x_vec[i] * (x_vec[i+1] - x_vec[i] * x_vec[i]) - 2 * (1 - x_vec[i]); for (i = 1; i < 2; i++) df_vec[i] += 200 * (x_vec[i] - x_vec[i - 1] * x_vec[i - 1]); return 0; } TEST_CASE("minimize rosenbrock") { ccv_dense_matrix_t* x = ccv_dense_matrix_new(1, 2, CCV_64F | CCV_C1, 0, 0); ccv_zero(x); int steps = 0; ccv_minimize_param_t params; params.interp = 0.1; params.extrap = 3.0; params.max_iter = 20; params.ratio = 10.0; params.sig = 0.1; params.rho = 0.05; ccv_minimize(x, 25, 1.0, rosenbrock, params, &steps); double dx[2] = { 1, 1 }; REQUIRE_ARRAY_EQ_WITH_TOLERANCE(double, x->data.f64, dx, 2, 1e-6, "the global minimal should be at (1.0, 1.0)"); ccv_matrix_free(x); }
void ccv_hog(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int b_type, int sbin, int size) { assert(a->rows >= size && a->cols >= size && (4 + sbin * 3) <= CCV_MAX_CHANNEL); int rows = a->rows / size; int cols = a->cols / size; b_type = (CCV_GET_DATA_TYPE(b_type) == CCV_64F) ? CCV_64F | (4 + sbin * 3) : CCV_32F | (4 + sbin * 3); ccv_declare_derived_signature(sig, a->sig != 0, ccv_sign_with_format(64, "ccv_hog(%d,%d)", sbin, size), a->sig, CCV_EOF_SIGN); ccv_dense_matrix_t* db = *b = ccv_dense_matrix_renew(*b, rows, cols, CCV_64F | CCV_32F | (4 + sbin * 3), b_type, sig); ccv_object_return_if_cached(, db); ccv_dense_matrix_t* ag = 0; ccv_dense_matrix_t* mg = 0; ccv_gradient(a, &ag, 0, &mg, 0, 1, 1); float* agp = ag->data.f32; float* mgp = mg->data.f32; int i, j, k, ch = CCV_GET_CHANNEL(a->type); ccv_dense_matrix_t* cn = ccv_dense_matrix_new(rows, cols, CCV_GET_DATA_TYPE(db->type) | (sbin * 2), 0, 0); ccv_dense_matrix_t* ca = ccv_dense_matrix_new(rows, cols, CCV_GET_DATA_TYPE(db->type) | CCV_C1, 0, 0); ccv_zero(cn); // normalize sbin direction-sensitive and sbin * 2 insensitive over 4 normalization factor // accumulating them over sbin * 2 + sbin + 4 channels // TNA - truncation - normalization - accumulation #define TNA(_for_type, idx, a, b, c, d) \ { \ _for_type norm = 1.0 / sqrt(cap[a] + cap[b] + cap[c] + cap[d] + 1e-4); \ for (k = 0; k < sbin * 2; k++) \ { \ _for_type v = 0.5 * ccv_min(cnp[k] * norm, 0.2); \ dbp[4 + sbin + k] += v; \ dbp[idx] += v; \ } \ dbp[idx] *= 0.2357; \ for (k = 0; k < sbin; k++) \ { \ _for_type v = 0.5 * ccv_min((cnp[k] + cnp[k + sbin]) * norm, 0.2); \ dbp[4 + k] += v; \ } \ } #define for_block(_, _for_type) \ _for_type* cnp = (_for_type*)ccv_get_dense_matrix_cell(cn, 0, 0, 0); \ for (i = 0; i < rows * size; i++) \ { \ for (j = 0; j < cols * size; j++) \ { \ _for_type agv = agp[j * ch]; \ _for_type mgv = mgp[j * ch]; \ for (k = 1; k < ch; k++) \ if (mgp[j * ch + k] > mgv) \ { \ mgv = mgp[j * ch + k]; \ agv = agp[j * ch + k]; \ } \ _for_type agr0 = (ccv_clamp(agv, 0, 359.99) / 360.0) * (sbin * 2); \ int ag0 = (int)agr0; \ int ag1 = (ag0 + 1 < sbin * 2) ? ag0 + 1 : 0; \ agr0 = agr0 - ag0; \ _for_type agr1 = 1.0 - agr0; \ 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)floor(yp); \ assert(iyp < rows); \ int ixp = (int)floor(xp); \ assert(ixp < cols); \ _for_type vy0 = yp - iyp; \ _for_type vx0 = xp - ixp; \ _for_type vy1 = 1.0 - vy0; \ _for_type vx1 = 1.0 - vx0; \ if (ixp >= 0 && iyp >= 0) \ { \ cnp[iyp * cn->cols * sbin * 2 + ixp * sbin * 2 + ag0] += agr1 * vx1 * vy1 * mgv; \ cnp[iyp * cn->cols * sbin * 2 + ixp * sbin * 2 + ag1] += agr0 * vx1 * vy1 * mgv; \ } \ if (ixp + 1 < cn->cols && iyp >= 0) \ { \ cnp[iyp * cn->cols * sbin * 2 + (ixp + 1) * sbin * 2 + ag0] += agr1 * vx0 * vy1 * mgv; \ cnp[iyp * cn->cols * sbin * 2 + (ixp + 1) * sbin * 2 + ag1] += agr0 * vx0 * vy1 * mgv; \ } \ if (ixp >= 0 && iyp + 1 < cn->rows) \ { \ cnp[(iyp + 1) * cn->cols * sbin * 2 + ixp * sbin * 2 + ag0] += agr1 * vx1 * vy0 * mgv; \ cnp[(iyp + 1) * cn->cols * sbin * 2 + ixp * sbin * 2 + ag1] += agr0 * vx1 * vy0 * mgv; \ } \ if (ixp + 1 < cn->cols && iyp + 1 < cn->rows) \ { \ cnp[(iyp + 1) * cn->cols * sbin * 2 + (ixp + 1) * sbin * 2 + ag0] += agr1 * vx0 * vy0 * mgv; \ cnp[(iyp + 1) * cn->cols * sbin * 2 + (ixp + 1) * sbin * 2 + ag1] += agr0 * vx0 * vy0 * mgv; \ } \ } \ agp += a->cols * ch; \ mgp += a->cols * ch; \ } \ ccv_matrix_free(ag); \ ccv_matrix_free(mg); \ cnp = (_for_type*)ccv_get_dense_matrix_cell(cn, 0, 0, 0); \ _for_type* cap = (_for_type*)ccv_get_dense_matrix_cell(ca, 0, 0, 0); \ for (i = 0; i < rows; i++) \ { \ for (j = 0; j < cols; j++) \ { \ *cap = 0; \ for (k = 0; k < sbin; k++) \ *cap += (cnp[k] + cnp[k + sbin]) * (cnp[k] + cnp[k + sbin]); \ cnp += 2 * sbin; \ cap++; \ } \ } \ cnp = (_for_type*)ccv_get_dense_matrix_cell(cn, 0, 0, 0); \ cap = (_for_type*)ccv_get_dense_matrix_cell(ca, 0, 0, 0); \ ccv_zero(db); \ _for_type* dbp = (_for_type*)ccv_get_dense_matrix_cell(db, 0, 0, 0); \ TNA(_for_type, 0, 1, cols + 1, cols, 0); \ TNA(_for_type, 1, 1, 1, 0, 0); \ TNA(_for_type, 2, 0, cols, cols, 0); \ TNA(_for_type, 3, 0, 0, 0, 0); \ cnp += 2 * sbin; \ dbp += 3 * sbin + 4; \ cap++; \ for (j = 1; j < cols - 1; j++) \ { \ TNA(_for_type, 0, 1, cols + 1, cols, 0); \ TNA(_for_type, 1, 1, 1, 0, 0); \ TNA(_for_type, 2, -1, cols - 1, cols, 0); \ TNA(_for_type, 3, -1, -1, 0, 0); \ cnp += 2 * sbin; \ dbp += 3 * sbin + 4; \ cap++; \ } \ TNA(_for_type, 0, 0, cols, cols, 0); \ TNA(_for_type, 1, 0, 0, 0, 0); \ TNA(_for_type, 2, -1, cols - 1, cols, 0); \ TNA(_for_type, 3, -1, -1, 0, 0); \ cnp += 2 * sbin; \ dbp += 3 * sbin + 4; \ cap++; \ for (i = 1; i < rows - 1; i++) \ { \ TNA(_for_type, 0, 1, cols + 1, cols, 0); \ TNA(_for_type, 1, 1, -cols + 1, -cols, 0); \ TNA(_for_type, 2, 0, cols, cols, 0); \ TNA(_for_type, 3, 0, -cols, -cols, 0); \ cnp += 2 * sbin; \ dbp += 3 * sbin + 4; \ cap++; \ for (j = 1; j < cols - 1; j++) \ { \ TNA(_for_type, 0, 1, cols + 1, cols, 0); \ TNA(_for_type, 1, 1, -cols + 1, -cols, 0); \ TNA(_for_type, 2, -1, cols - 1, cols, 0); \ TNA(_for_type, 3, -1, -cols - 1, -cols, 0); \ cnp += 2 * sbin; \ dbp += 3 * sbin + 4; \ cap++; \ } \ TNA(_for_type, 0, 0, cols, cols, 0); \ TNA(_for_type, 1, 0, -cols, -cols, 0); \ TNA(_for_type, 2, -1, cols - 1, cols, 0); \ TNA(_for_type, 3, -1, -cols - 1, -cols, 0); \ cnp += 2 * sbin; \ dbp += 3 * sbin + 4; \ cap++; \ } \ TNA(_for_type, 0, 1, 1, 0, 0); \ TNA(_for_type, 1, 1, -cols + 1, -cols, 0); \ TNA(_for_type, 2, 0, 0, 0, 0); \ TNA(_for_type, 3, 0, -cols, -cols, 0); \ cnp += 2 * sbin; \ dbp += 3 * sbin + 4; \ cap++; \ for (j = 1; j < cols - 1; j++) \ { \ TNA(_for_type, 0, 1, 1, 0, 0); \ TNA(_for_type, 1, 1, -cols + 1, -cols, 0); \ TNA(_for_type, 2, -1, -1, 0, 0); \ TNA(_for_type, 3, -1, -cols - 1, -cols, 0); \ cnp += 2 * sbin; \ dbp += 3 * sbin + 4; \ cap++; \ } \ TNA(_for_type, 0, 0, 0, 0, 0); \ TNA(_for_type, 1, 0, -cols, -cols, 0); \ TNA(_for_type, 2, -1, -1, 0, 0); \ TNA(_for_type, 3, -1, -cols - 1, -cols, 0); ccv_matrix_typeof(db->type, for_block); #undef for_block #undef TNA ccv_matrix_free(cn); ccv_matrix_free(ca); }
#include "ccv.h" #include "case.h" TEST_CASE("matrix multiplication") { ccv_dense_matrix_t* a = ccv_dense_matrix_new(3, 2, CCV_64F | CCV_C1, 0, 0); a->data.f64[0] = 0.11; a->data.f64[1] = 0.12; a->data.f64[2] = 0.13; a->data.f64[3] = 0.21; a->data.f64[4] = 0.22; a->data.f64[5] = 0.23; ccv_dense_matrix_t* b = ccv_dense_matrix_new(3, 2, CCV_64F | CCV_C1, 0, 0); b->data.f64[0] = 1011; b->data.f64[1] = 1012; b->data.f64[2] = 1021; b->data.f64[3] = 1022; b->data.f64[4] = 1031; b->data.f64[5] = 1032; ccv_dense_matrix_t* y = 0; ccv_gemm(a, b, 1, 0, 0, CCV_A_TRANSPOSE, (ccv_matrix_t**)&y, 0); double hy[4] = {470.760000, 471.220000, 572.860000, 573.420000}; REQUIRE_ARRAY_EQ_WITH_TOLERANCE(double, hy, y->data.f64, 4, 1e-6, "2x3, 3x2 matrix multiplication failure"); ccv_matrix_free(a); ccv_matrix_free(b); ccv_matrix_free(y); } TEST_CASE("vector sum") { ccv_dense_matrix_t* a = ccv_dense_matrix_new(3, 2, CCV_64F | CCV_C1, 0, 0);