Image-CCV
view release on metacpan or search on metacpan
ccv-src/lib/ccv_classic.c view on Meta::CPAN
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
}
int ccv_otsu(ccv_dense_matrix_t* a, double* outvar, int range)
{
assert((a->type & CCV_32S) || (a->type & CCV_8U));
int* histogram = (int*)alloca(range * sizeof(int));
memset(histogram, 0, sizeof(int) * range);
int i, j;
unsigned char* a_ptr = a->data.u8;
#define for_block(_, _for_get) \
for (i = 0; i < a->rows; i++) \
{ \
for (j = 0; j < a->cols; j++) \
histogram[ccv_clamp((int)_for_get(a_ptr, j, 0), 0, range - 1)]++; \
a_ptr += a->step; \
}
ccv_matrix_getter(a->type, for_block);
#undef for_block
double sum = 0, sumB = 0;
for (i = 0; i < range; i++)
sum += i * histogram[i];
int wB = 0, wF = 0, total = a->rows * a->cols;
double maxVar = 0;
int threshold = 0;
for (i = 0; i < range; i++)
{
wB += histogram[i];
if (wB == 0)
continue;
wF = total - wB;
if (wF == 0)
break;
sumB += i * histogram[i];
double mB = sumB / wB;
double mF = (sum - sumB) / wF;
double var = wB * wF * (mB - mF) * (mB - mF);
if (var > maxVar)
{
maxVar = var;
threshold = i;
}
}
if (outvar != 0)
*outvar = maxVar / total / total;
return threshold;
}
#define LK_MAX_ITER (30)
#define LK_EPSILON (0.01)
/* this code is a rewrite from OpenCV's legendary Lucas-Kanade optical flow implementation */
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)
{
assert(a && b && a->rows == b->rows && a->cols == b->cols);
assert(CCV_GET_CHANNEL(a->type) == CCV_GET_CHANNEL(b->type) && CCV_GET_DATA_TYPE(a->type) == CCV_GET_DATA_TYPE(b->type));
assert(CCV_GET_CHANNEL(a->type) == 1);
assert(CCV_GET_DATA_TYPE(a->type) == CCV_8U);
assert(point_a->rnum > 0);
level = ccv_clamp(level + 1, 1, (int)(log((double)ccv_min(a->rows, a->cols) / ccv_max(win_size.width * 2, win_size.height * 2)) / log(2.0) + 0.5));
ccv_declare_derived_signature(sig, a->sig != 0 && b->sig != 0 && point_a->sig != 0, ccv_sign_with_format(128, "ccv_optical_flow_lucas_kanade(%d,%d,%d,%la)", win_size.width, win_size.height, level, min_eigen), a->sig, b->sig, point_a->sig, CCV_EOF_SI...
ccv_array_t* seq = *point_b = ccv_array_new(sizeof(ccv_decimal_point_with_status_t), point_a->rnum, sig);
ccv_object_return_if_cached(, seq);
seq->rnum = point_a->rnum;
ccv_dense_matrix_t** pyr_a = (ccv_dense_matrix_t**)alloca(sizeof(ccv_dense_matrix_t*) * level);
ccv_dense_matrix_t** pyr_a_dx = (ccv_dense_matrix_t**)alloca(sizeof(ccv_dense_matrix_t*) * level);
ccv_dense_matrix_t** pyr_a_dy = (ccv_dense_matrix_t**)alloca(sizeof(ccv_dense_matrix_t*) * level);
ccv_dense_matrix_t** pyr_b = (ccv_dense_matrix_t**)alloca(sizeof(ccv_dense_matrix_t*) * level);
int i, j, t, x, y;
/* generating image pyramid */
pyr_a[0] = a;
pyr_a_dx[0] = pyr_a_dy[0] = 0;
ccv_sobel(pyr_a[0], &pyr_a_dx[0], 0, 3, 0);
ccv_sobel(pyr_a[0], &pyr_a_dy[0], 0, 0, 3);
pyr_b[0] = b;
for (i = 1; i < level; i++)
{
pyr_a[i] = pyr_a_dx[i] = pyr_a_dy[i] = pyr_b[i] = 0;
ccv_sample_down(pyr_a[i - 1], &pyr_a[i], 0, 0, 0);
ccv_sobel(pyr_a[i], &pyr_a_dx[i], 0, 3, 0);
ccv_sobel(pyr_a[i], &pyr_a_dy[i], 0, 0, 3);
ccv_sample_down(pyr_b[i - 1], &pyr_b[i], 0, 0, 0);
}
int* wi = (int*)alloca(sizeof(int) * win_size.width * win_size.height);
int* widx = (int*)alloca(sizeof(int) * win_size.width * win_size.height);
int* widy = (int*)alloca(sizeof(int) * win_size.width * win_size.height);
ccv_decimal_point_t half_win = ccv_decimal_point((win_size.width - 1) * 0.5f, (win_size.height - 1) * 0.5f);
const int W_BITS14 = 14, W_BITS7 = 7, W_BITS9 = 9;
const float FLT_SCALE = 1.0f / (1 << 25);
// clean up status to 1
for (i = 0; i < point_a->rnum; i++)
{
ccv_decimal_point_with_status_t* point_with_status = (ccv_decimal_point_with_status_t*)ccv_array_get(seq, i);
point_with_status->status = 1;
}
int prev_rows, prev_cols;
for (t = level - 1; t >= 0; t--)
{
ccv_dense_matrix_t* a = pyr_a[t];
ccv_dense_matrix_t* adx = pyr_a_dx[t];
ccv_dense_matrix_t* ady = pyr_a_dy[t];
assert(CCV_GET_DATA_TYPE(adx->type) == CCV_32S);
assert(CCV_GET_DATA_TYPE(ady->type) == CCV_32S);
ccv_dense_matrix_t* b = pyr_b[t];
for (i = 0; i < point_a->rnum; i++)
{
ccv_decimal_point_t prev_point = *(ccv_decimal_point_t*)ccv_array_get(point_a, i);
ccv_decimal_point_with_status_t* point_with_status = (ccv_decimal_point_with_status_t*)ccv_array_get(seq, i);
prev_point.x = prev_point.x / (float)(1 << t);
prev_point.y = prev_point.y / (float)(1 << t);
ccv_decimal_point_t next_point;
if (t == level - 1)
( run in 3.864 seconds using v1.01-cache-2.11-cpan-ad66724bd6a )