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 )