void ccv_slice(ccv_matrix_t* a, ccv_matrix_t** b, int btype, int y, int x, int rows, int cols) { int type = *(int*)a; if (type & CCV_MATRIX_DENSE) { ccv_dense_matrix_t* da = ccv_get_dense_matrix(a); ccv_declare_derived_signature(sig, da->sig != 0, ccv_sign_with_format(128, "ccv_slice(%d,%d,%d,%d)", y, x, rows, cols), da->sig, CCV_EOF_SIGN); btype = (btype == 0) ? CCV_GET_DATA_TYPE(da->type) | CCV_GET_CHANNEL(da->type) : CCV_GET_DATA_TYPE(btype) | CCV_GET_CHANNEL(da->type); ccv_dense_matrix_t* db = *b = ccv_dense_matrix_renew(*b, rows, cols, CCV_ALL_DATA_TYPE | CCV_GET_CHANNEL(da->type), btype, sig); ccv_object_return_if_cached(, db); int i, j, ch = CCV_GET_CHANNEL(da->type); int dx = 0, dy = 0; if (!(y >= 0 && y + rows <= da->rows && x >= 0 && x + cols <= da->cols)) { ccv_zero(db); if (y < 0) { rows += y; dy = -y; y = 0; } if (y + rows > da->rows) rows = da->rows - y; if (x < 0) { cols += x; dx = -x; x = 0; } if (x + cols > da->cols) cols = da->cols - x; } unsigned char* a_ptr = da->data.u8 + x * ch * CCV_GET_DATA_TYPE_SIZE(da->type) + y * da->step; unsigned char* b_ptr = db->data.u8 + dx * ch * CCV_GET_DATA_TYPE_SIZE(db->type) + dy * db->step; #define for_block(_for_set, _for_get) \ for (i = 0; i < rows; i++) \ { \ for (j = 0; j < cols * ch; j++) \ { \ _for_set(b_ptr, j, _for_get(a_ptr, j, 0), 0); \ } \ a_ptr += da->step; \ b_ptr += db->step; \ } ccv_matrix_setter(db->type, ccv_matrix_getter, da->type, for_block); #undef for_block } else if (type & CCV_MATRIX_SPARSE) {
int rosenbrock(const ccv_dense_matrix_t* x, double* f, ccv_dense_matrix_t* df, void* data) { int* steps = (int*)data; (*steps)++; int i; double rf = 0; double* x_vec = x->data.f64; 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; }
void ccv_close_outline(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type) { assert((CCV_GET_CHANNEL(a->type) == CCV_C1) && ((a->type & CCV_8U) || (a->type & CCV_32S) || (a->type & CCV_64S))); ccv_declare_derived_signature(sig, a->sig != 0, ccv_sign_with_literal("ccv_close_outline"), a->sig, CCV_EOF_SIGN); type = ((type == 0) || (type & CCV_32F) || (type & CCV_64F)) ? CCV_GET_DATA_TYPE(a->type) | CCV_C1 : CCV_GET_DATA_TYPE(type) | CCV_C1; ccv_dense_matrix_t* db = *b = ccv_dense_matrix_renew(*b, a->rows, a->cols, CCV_C1 | CCV_ALL_DATA_TYPE, type, sig); ccv_object_return_if_cached(, db); int i, j; unsigned char* a_ptr = a->data.u8; unsigned char* b_ptr = db->data.u8; ccv_zero(db); #define for_block(_for_get, _for_set_b, _for_get_b) \ for (i = 0; i < a->rows - 1; i++) \ { \ for (j = 0; j < a->cols - 1; j++) \ { \ if (!_for_get_b(b_ptr, j, 0)) \ _for_set_b(b_ptr, j, _for_get(a_ptr, j, 0), 0); \ if (_for_get(a_ptr, j, 0) && _for_get(a_ptr + a->step, j + 1, 0)) \ { \ _for_set_b(b_ptr + a->step, j, 1, 0); \ _for_set_b(b_ptr, j + 1, 1, 0); \ } \ if (_for_get(a_ptr + a->step, j, 0) && _for_get(a_ptr, j + 1, 0)) \ { \ _for_set_b(b_ptr, j, 1, 0); \ _for_set_b(b_ptr + a->step, j + 1, 1, 0); \ } \ } \ if (!_for_get_b(b_ptr, a->cols - 1, 0)) \ _for_set_b(b_ptr, a->cols - 1, _for_get(a_ptr, a->cols - 1, 0), 0); \ a_ptr += a->step; \ b_ptr += db->step; \ } \ for (j = 0; j < a->cols; j++) \ { \ if (!_for_get_b(b_ptr, j, 0)) \ _for_set_b(b_ptr, j, _for_get(a_ptr, j, 0), 0); \ } ccv_matrix_getter_integer_only(a->type, ccv_matrix_setter_getter_integer_only, db->type, for_block); #undef for_block }
void ccv_decimal_slice(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, float y, float x, int rows, int cols) { ccv_declare_derived_signature(sig, a->sig != 0, ccv_sign_with_format(64, "ccv_decimal_slice(%a,%a,%d,%d)", y, x, rows, cols), a->sig, CCV_EOF_SIGN); 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, rows, cols, CCV_ALL_DATA_TYPE | CCV_GET_CHANNEL(a->type), type, sig); ccv_object_return_if_cached(, db); int i, j, ch = CCV_GET_CHANNEL(a->type); int ix = (int)x, iy = (int)y; float xd = x - ix, yd = y - iy; float w00 = (1 - xd) * (1 - yd); float w01 = xd * (1 - yd); float w10 = (1 - xd) * yd; float w11 = xd * yd; int dx = 0, dy = 0; int rows_1 = 0, cols_1 = 0; // it is going to be hard to deal with border efficiently, since this is used for tld, will ignore border for now if (!(iy >= 0 && iy + rows < a->rows && ix >= 0 && ix + cols < a->cols)) { ccv_zero(db); if (iy < 0) { rows += iy; dy = -iy; iy = 0; } if (iy + rows >= a->rows) { rows = a->rows - iy - 1; if (iy + rows > a->rows) rows_1 = 1; // we need to do our best to padding the last row } if (ix < 0) { cols += ix; dx = -ix; ix = 0; } if (x + cols >= a->cols) { cols = a->cols - ix - 1; if (x + cols > a->cols) cols_1 = 1; // we need to do our best to padding the last col } } unsigned char* a_ptr = (unsigned char*)ccv_get_dense_matrix_cell(a, iy, ix, 0); unsigned char* b_ptr = (unsigned char*)ccv_get_dense_matrix_cell(db, dy, dx, 0); #define for_block(_for_set, _for_get) \ for (i = 0; i < rows; i++) \ { \ for (j = 0; j < cols * ch; j++) \ { \ _for_set(b_ptr, j, (_for_get(a_ptr, j, 0) * G00 + _for_get(a_ptr, j + ch, 0) * G01 + _for_get(a_ptr + a->step, j, 0) * G10 + _for_get(a_ptr + a->step, j + ch, 0) * G11) / GALL, 0); \ } \ if (cols_1) \ _for_set(b_ptr, j, (_for_get(a_ptr, j, 0) * (G00 + G01) + _for_get(a_ptr + a->step, j, 0) * G10 + _for_get(a_ptr + a->step, j + ch, 0) * G11) / GALL, 0); \ a_ptr += a->step; \ b_ptr += db->step; \ } \ if (rows_1) \ { \ for (j = 0; j < cols * ch; j++) \ { \ _for_set(b_ptr, j, (_for_get(a_ptr, j, 0) * (G00 + G10) + _for_get(a_ptr, j + ch, 0) * (G01 + G11)) / GALL, 0); \ } \ if (cols_1) \ _for_set(b_ptr, j, _for_get(a_ptr, j, 0), 0); \ } /* unswitch in the manual way so that we can use integer interpolation */ if ((a->type & CCV_8U) || (a->type & CCV_32S) || (a->type & CCV_64S)) { const int W_BITS14 = 14; int iw00 = (int)(w00 * (1 << W_BITS14) + 0.5); int iw01 = (int)(w01 * (1 << W_BITS14) + 0.5); int iw10 = (int)(w10 * (1 << W_BITS14) + 0.5); int iw11 = (1 << W_BITS14) - iw00 - iw01 - iw10; #define G00 (iw00) #define G01 (iw01) #define G10 (iw10) #define G11 (iw11) #define GCOM (1 << (W_BITS14 - 1)) #define GALL (1 << (W_BITS14)) ccv_matrix_setter(db->type, ccv_matrix_getter_integer_only, a->type, for_block); #undef G00 #undef G01 #undef G10 #undef G11 #undef GCOM #undef GALL } else { #define G00 (w00) #define G01 (w01) #define G10 (w10) #define G11 (w11) #define GCOM (0) #define GALL (1) ccv_matrix_setter(db->type, ccv_matrix_getter_float_only, a->type, for_block); #undef G00 #undef G01 #undef G10 #undef G11 #undef GCOM #undef GALL } #undef for_block }
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); }