Esempio n. 1
0
static int _ccv_read_bbf_stage_classifier(const char* file, ccv_bbf_stage_classifier_t* classifier)
{
	FILE* r = fopen(file, "r");
	if (r == 0) return -1;
	APPROX int stat = 0;
	stat |= fscanf(r, "%d", &classifier->count);
	union { float fl; int i; } fli;
	stat |= fscanf(r, "%d", &fli.i);
	classifier->threshold = fli.fl;
	classifier->feature = (ccv_bbf_feature_t*)ccmalloc(ENDORSE(classifier->count) * sizeof(ccv_bbf_feature_t));
	classifier->alpha = (float*)DEDORSE(ccmalloc(ENDORSE(classifier->count) * 2 * sizeof(float)));
	int i, j;
	for (i = 0; i < ENDORSE(classifier->count); i++)
	{
		stat |= fscanf(r, "%d", &classifier->feature[i].size);
		for (j = 0; j < ENDORSE(classifier->feature[i].size); j++)
		{
			stat |= fscanf(r, "%d %d %d", &classifier->feature[i].px[j], &classifier->feature[i].py[j], &classifier->feature[i].pz[j]);
			stat |= fscanf(r, "%d %d %d", &classifier->feature[i].nx[j], &classifier->feature[i].ny[j], &classifier->feature[i].nz[j]);
		}
		union { float fl; int i; } flia, flib;
		stat |= fscanf(r, "%d %d", &flia.i, &flib.i);
		classifier->alpha[i * 2] = flia.fl;
		classifier->alpha[i * 2 + 1] = flib.fl;
	}
	fclose(r);
	return 0;
}
Esempio n. 2
0
ccv_dense_matrix_t* ccv_dense_matrix_new(int rows, int cols, int type, void* data, uint64_t sig)
{
	ccv_dense_matrix_t* mat;
	if (ccv_cache_opt && sig != 0 && !data && !(type & CCV_NO_DATA_ALLOC))
	{
		uint8_t type;
		mat = (ccv_dense_matrix_t*)ccv_cache_out(&ccv_cache, sig, &type);
		if (mat)
		{
			assert(type == 0);
			mat->type |= CCV_GARBAGE; // set the flag so the upper level function knows this is from recycle-bin
			mat->refcount = 1;
			return mat;
		}
	}
	if (type & CCV_NO_DATA_ALLOC)
	{
		mat = (ccv_dense_matrix_t*)ccmalloc(sizeof(ccv_dense_matrix_t));
		mat->type = (CCV_GET_CHANNEL(type) | CCV_GET_DATA_TYPE(type) | CCV_MATRIX_DENSE | CCV_NO_DATA_ALLOC) & ~CCV_GARBAGE;
		mat->data.u8 = data;
	} else {
		mat = (ccv_dense_matrix_t*)(data ? data : ccmalloc(ccv_compute_dense_matrix_size(rows, cols, type)));
		mat->type = (CCV_GET_CHANNEL(type) | CCV_GET_DATA_TYPE(type) | CCV_MATRIX_DENSE) & ~CCV_GARBAGE;
		mat->type |= data ? CCV_UNMANAGED : CCV_REUSABLE; // it still could be reusable because the signature could be derived one.
		mat->data.u8 = (unsigned char*)(mat + 1);
	}
	mat->sig = sig;
	mat->rows = rows;
	mat->cols = cols;
	mat->step = (cols * CCV_GET_DATA_TYPE_SIZE(type) * CCV_GET_CHANNEL(type) + 3) & -4;
	mat->refcount = 1;
	return mat;
}
Esempio n. 3
0
static void _ccv_dense_vector_expand(ccv_sparse_matrix_t* mat, ccv_dense_vector_t* vector)
{
	if (vector->prime == -1)
		return;
	vector->prime++;
	int new_length = CCV_GET_SPARSE_PRIME(vector->prime);
	int cell_width = CCV_GET_DATA_TYPE_SIZE(mat->type) * CCV_GET_CHANNEL(mat->type);
	int new_step = (new_length * cell_width + 3) & -4;
	ccv_matrix_cell_t new_data;
	new_data.u8 = (unsigned char*)ccmalloc(new_step + sizeof(int) * new_length);
	int* new_indice = (int*)(new_data.u8 + new_step);
	int i;
	for (i = 0; i < new_length; i++)
		new_indice[i] = -1;
	for (i = 0; i < vector->length; i++)
		if (vector->indice[i] != -1)
		{
			int index = vector->indice[i];
			int h = (index * 33) % new_length, j = 0;
			while (new_indice[(h + j * j) % new_length] != index && new_indice[(h + j * j) % new_length] != -1)
				j++;
			j = (h + j * j) % new_length;
			new_indice[j] = index;
			memcpy(new_data.u8 + j * cell_width, vector->data.u8 + i * cell_width, cell_width);
		}
	vector->length = new_length;
	ccfree(vector->data.u8);
	vector->data = new_data;
	vector->indice = new_indice;
}
Esempio n. 4
0
ccv_sparse_matrix_t* ccv_sparse_matrix_new(int rows, int cols, int type, int major, uint64_t sig)
{
	ccv_sparse_matrix_t* mat;
	mat = (ccv_sparse_matrix_t*)ccmalloc(sizeof(ccv_sparse_matrix_t));
	mat->rows = rows;
	mat->cols = cols;
	mat->type = type | CCV_MATRIX_SPARSE | ((type & CCV_DENSE_VECTOR) ? CCV_DENSE_VECTOR : CCV_SPARSE_VECTOR);
	mat->major = major;
	mat->prime_index = 1; // See ccv_util.c to know why this is 1 and why size is 2.
	mat->size = 2;
	mat->rnum = 0;
	mat->refcount = 1;
	mat->index = (ccv_sparse_matrix_index_t*)cccalloc(sizeof(ccv_sparse_matrix_index_t), mat->size);
	mat->vector = (ccv_sparse_matrix_vector_t*)ccmalloc(sizeof(ccv_sparse_matrix_vector_t) * mat->size);
	return mat;
}
Esempio n. 5
0
static void _ccv_sparse_matrix_expand(ccv_sparse_matrix_t* mat)
{
	int length = CCV_GET_SPARSE_PRIME(mat->prime);
	mat->prime++;
	int new_length = CCV_GET_SPARSE_PRIME(mat->prime);
	ccv_dense_vector_t* new_vector = (ccv_dense_vector_t*)ccmalloc(new_length * sizeof(ccv_dense_vector_t));
	int i;
	for (i = 0; i < new_length; i++)
	{
		new_vector[i].index = -1;
		new_vector[i].length = 0;
		new_vector[i].next = 0;
	}
	for (i = 0; i < length; i++)
		if (mat->vector[i].index != -1)
		{
			int h = (mat->vector[i].index * 33) % new_length;
			if (new_vector[h].length == 0)
			{
				memcpy(new_vector + h, mat->vector + i, sizeof(ccv_dense_vector_t));
				new_vector[h].next = 0;
			} else {
				ccv_dense_vector_t* t = (ccv_dense_vector_t*)ccmalloc(sizeof(ccv_dense_vector_t));
				memcpy(t, mat->vector + i, sizeof(ccv_dense_vector_t));
				t->next = new_vector[h].next;
				new_vector[h].next = t;
			}
			ccv_dense_vector_t* iter = mat->vector[i].next;
			while (iter != 0)
			{
				ccv_dense_vector_t* iter_next = iter->next;
				h = (iter->index * 33) % new_length;
				if (new_vector[h].length == 0)
				{
					memcpy(new_vector + h, iter, sizeof(ccv_dense_vector_t));
					new_vector[h].next = 0;
					ccfree(iter);
				} else {
					iter->next = new_vector[h].next;
					new_vector[h].next = iter;
				}
				iter = iter_next;
			}
		}
	ccfree(mat->vector);
	mat->vector = new_vector;
}
Esempio n. 6
0
ccv_dense_matrix_t* ccv_dense_matrix_new(int rows, int cols, int type, void* data, uint64_t sig)
{
	ccv_dense_matrix_t* mat;
	if (ccv_cache_opt && sig != 0 && !data && !(type & CCV_NO_DATA_ALLOC))
	{
		uint8_t type;
		mat = (ccv_dense_matrix_t*)ccv_cache_out(&ccv_cache, sig, &type);
		if (mat)
		{
			assert(type == 0);
			mat->type |= CCV_GARBAGE; // set the flag so the upper level function knows this is from recycle-bin
			mat->refcount = 1;
			return mat;
		}
	}
	if (type & CCV_NO_DATA_ALLOC)
	{
		mat = (ccv_dense_matrix_t*)ccmalloc(sizeof(ccv_dense_matrix_t));
		mat->type = (CCV_GET_CHANNEL(type) | CCV_GET_DATA_TYPE(type) | CCV_MATRIX_DENSE | CCV_NO_DATA_ALLOC) & ~CCV_GARBAGE;
		mat->data.u8 = data;
	} else {
		const size_t hdr_size = (sizeof(ccv_dense_matrix_t) + 15) & -16;
		mat = (ccv_dense_matrix_t*)(data ? data : ccmalloc(ccv_compute_dense_matrix_size(rows, cols, type)));
		mat->type = (CCV_GET_CHANNEL(type) | CCV_GET_DATA_TYPE(type) | CCV_MATRIX_DENSE) & ~CCV_GARBAGE;
		mat->type |= data ? CCV_UNMANAGED : CCV_REUSABLE; // it still could be reusable because the signature could be derived one.
		mat->data.u8 = (unsigned char*)mat + hdr_size;
	}
	mat->sig = sig;
#if CCV_NNC_TENSOR_TFB
	mat->resides = CCV_TENSOR_CPU_MEMORY;
	mat->format = CCV_TENSOR_FORMAT_NHWC;
	mat->datatype = CCV_GET_DATA_TYPE(type);
	mat->channels = CCV_GET_CHANNEL(type);
	mat->reserved = 0;
#endif
	mat->rows = rows;
	mat->cols = cols;
	mat->step = CCV_GET_STEP(cols, type);
	mat->refcount = 1;
	return mat;
}
Esempio n. 7
0
ccv_sparse_matrix_t* ccv_sparse_matrix_new(int rows, int cols, int type, int major, uint64_t sig)
{
	ccv_sparse_matrix_t* mat;
	mat = (ccv_sparse_matrix_t*)ccmalloc(sizeof(ccv_sparse_matrix_t));
	mat->rows = rows;
	mat->cols = cols;
	mat->type = type | CCV_MATRIX_SPARSE | ((type & CCV_DENSE_VECTOR) ? CCV_DENSE_VECTOR : CCV_SPARSE_VECTOR);
	mat->major = major;
	mat->prime = 0;
	mat->load_factor = 0;
	mat->refcount = 1;
	mat->vector = (ccv_dense_vector_t*)ccmalloc(CCV_GET_SPARSE_PRIME(mat->prime) * sizeof(ccv_dense_vector_t));
	int i;
	for (i = 0; i < CCV_GET_SPARSE_PRIME(mat->prime); i++)
	{
		mat->vector[i].index = -1;
		mat->vector[i].length = 0;
		mat->vector[i].next = 0;
	}
	return mat;
}
Esempio n. 8
0
ccv_bbf_classifier_cascade_t* ccv_bbf_classifier_cascade_read_binary(char* s)
{
	int i;
	ccv_bbf_classifier_cascade_t* cascade = (ccv_bbf_classifier_cascade_t*)ccmalloc(sizeof(ccv_bbf_classifier_cascade_t));
        APPROX int* count_ptr = DEDORSE(&cascade->count);
	memcpy(count_ptr, s, sizeof(cascade->count)); s += sizeof(cascade->count);
	memcpy(&cascade->size.width, s, sizeof(cascade->size.width)); s += sizeof(cascade->size.width);
	memcpy(&cascade->size.height, s, sizeof(cascade->size.height)); s += sizeof(cascade->size.height);
	ccv_bbf_stage_classifier_t* classifier = cascade->stage_classifier = (ccv_bbf_stage_classifier_t*)ccmalloc(ENDORSE(cascade->count) * sizeof(ccv_bbf_stage_classifier_t));
	for (i = 0; i < ENDORSE(cascade->count); i++, classifier++)
	{
		memcpy(&classifier->count, s, sizeof(classifier->count)); s += sizeof(classifier->count);
		memcpy(&classifier->threshold, s, sizeof(classifier->threshold)); s += sizeof(classifier->threshold);
		classifier->feature = (ccv_bbf_feature_t*)ccmalloc(ENDORSE(classifier->count) * sizeof(ccv_bbf_feature_t));
		classifier->alpha = (float*)DEDORSE(ccmalloc(ENDORSE(classifier->count) * 2 * sizeof(float)));
		memcpy(classifier->feature, s, classifier->count * sizeof(ccv_bbf_feature_t)); s += classifier->count * sizeof(ccv_bbf_feature_t);
		memcpy(classifier->alpha, s, classifier->count * 2 * sizeof(float)); s += classifier->count * 2 * sizeof(float);
	}
	return cascade;

}
void ccv_nnc_symbolic_graph_set_while_expr(ccv_nnc_symbolic_graph_t* const while_graph, const ccv_nnc_graph_while_f while_expr, const void* const while_data, const ccv_nnc_graph_exec_symbol_t* const breakpoints, const int breakpoint_size)
{
	while_graph->while_expr = while_expr;
	while_graph->while_data = while_data;
	if (breakpoint_size > 0)
	{
		assert(breakpoints);
		while_graph->breakpoint_size = breakpoint_size;
		while_graph->breakpoints = (ccv_nnc_graph_exec_symbol_t*)ccmalloc(sizeof(ccv_nnc_graph_exec_symbol_t) * breakpoint_size);
		memcpy(while_graph->breakpoints, breakpoints, sizeof(ccv_nnc_graph_exec_symbol_t) * breakpoint_size);
	}
}
int main(int argc, char** argv)
{
	ccv_enable_default_cache();
	assert(argc == 2);
	FILE *r = fopen(argv[1], "r");
	char* file = (char*)malloc(1024);
	ccv_array_t* categorizeds = ccv_array_new(sizeof(ccv_categorized_t), 64, 0);
	size_t len = 1024;
	ssize_t read;
	while ((read = getline(&file, &len, r)) != -1)
	{
		while(read > 1 && isspace(file[read - 1]))
			read--;
		file[read] = 0;
		ccv_file_info_t input;
		input.filename = (char*)ccmalloc(1024);
		strncpy(input.filename, file, 1024);
		ccv_categorized_t categorized = ccv_categorized(0, 0, &input);
		ccv_array_push(categorizeds, &categorized);
	}
	fclose(r);
	free(file);
	/* MattNet parameters */
	ccv_convnet_layer_param_t params[13] = {
		// first layer (convolutional => max pool => rnorm)
		{
			.type = CCV_CONVNET_CONVOLUTIONAL,
			.bias = 0,
			.glorot = sqrtf(2),
			.input = {
				.matrix = {
					.rows = 225,
					.cols = 225,
					.channels = 3,
					.partition = 1,
				},
			},
			.output = {
				.convolutional = {
					.count = 96,
					.strides = 2,
					.border = 1,
					.rows = 7,
					.cols = 7,
					.channels = 3,
					.partition = 2,
				},
			},
		},
		{
			.type = CCV_CONVNET_LOCAL_RESPONSE_NORM,
Esempio n. 11
0
ccv_bbf_classifier_cascade_t* ccv_bbf_read_classifier_cascade(const char* directory)
{
	char buf[1024];
	sprintf(buf, "%s/cascade.txt", directory);
	int s, i;
	FILE* r = fopen(buf, "r");
	if (r == 0)
		return 0;
	ccv_bbf_classifier_cascade_t* cascade = (ccv_bbf_classifier_cascade_t*)ccmalloc(sizeof(ccv_bbf_classifier_cascade_t));
	s = fscanf(r, "%d %d %d", &cascade->count, &cascade->size.width, &cascade->size.height);
	assert(s > 0);
	cascade->stage_classifier = (ccv_bbf_stage_classifier_t*)ccmalloc(ENDORSE(cascade->count) * sizeof(ccv_bbf_stage_classifier_t));
	for (i = 0; i < ENDORSE(cascade->count); i++)
	{
		sprintf(buf, "%s/stage-%d.txt", directory, i);
		if (_ccv_read_bbf_stage_classifier(buf, &cascade->stage_classifier[i]) < 0)
		{
			cascade->count = i;
			break;
		}
	}
	fclose(r);
	return cascade;
}
Esempio n. 12
0
ccv_array_t* ccv_array_new(int rsize, int rnum, uint64_t sig)
{
	ccv_array_t* array;
	if (ccv_cache_opt && sig != 0)
	{
		uint8_t type;
		array = (ccv_array_t*)ccv_cache_out(&ccv_cache, sig, &type);
		if (array)
		{
			assert(type == 1);
			array->type |= CCV_GARBAGE;
			array->refcount = 1;
			return array;
		}
	}
	array = (ccv_array_t*)ccmalloc(sizeof(ccv_array_t));
	array->sig = sig;
	array->type = CCV_REUSABLE & ~CCV_GARBAGE;
	array->rnum = 0;
	array->rsize = rsize;
	array->size = ccv_max(rnum, 2 /* allocate memory for at least 2 items */);
	array->data = ccmalloc((size_t)array->size * (size_t)rsize);
	return array;
}
Esempio n. 13
0
void ccv_compress_sparse_matrix(ccv_sparse_matrix_t* mat, ccv_compressed_sparse_matrix_t** csm)
{
	int i, j;
	int nnz = 0;
	int length = CCV_GET_SPARSE_PRIME(mat->prime);
	for (i = 0; i < length; i++)
	{
		ccv_dense_vector_t* vector = &mat->vector[i];
#define while_block(_, _while_get) \
		while (vector != 0) \
		{ \
			if (vector->index != -1) \
			{ \
				if (mat->type & CCV_DENSE_VECTOR) \
				{ \
					for (j = 0; j < vector->length; j++) \
						if (_while_get(vector->data.u8, j, 0) != 0) \
							nnz++; \
				} else { \
					nnz += vector->load_factor; \
				} \
			} \
			vector = vector->next; \
		}
		ccv_matrix_getter(mat->type, while_block);
#undef while_block
	}
	ccv_compressed_sparse_matrix_t* cm = *csm = (ccv_compressed_sparse_matrix_t*)ccmalloc(sizeof(ccv_compressed_sparse_matrix_t) + nnz * sizeof(int) + nnz * CCV_GET_DATA_TYPE_SIZE(mat->type) + (((mat->major == CCV_SPARSE_COL_MAJOR) ? mat->cols : mat->rows) + 1) * sizeof(int));
	cm->type = (mat->type & ~CCV_MATRIX_SPARSE & ~CCV_SPARSE_VECTOR & ~CCV_DENSE_VECTOR) | ((mat->major == CCV_SPARSE_COL_MAJOR) ? CCV_MATRIX_CSC : CCV_MATRIX_CSR);
	cm->nnz = nnz;
	cm->rows = mat->rows;
	cm->cols = mat->cols;
	cm->index = (int*)(cm + 1);
	cm->offset = cm->index + nnz;
	cm->data.i32 = cm->offset + ((mat->major == CCV_SPARSE_COL_MAJOR) ? mat->cols : mat->rows) + 1;
	unsigned char* m_ptr = cm->data.u8;
	int* idx = cm->index;
	cm->offset[0] = 0;
	for (i = 0; i < ((mat->major == CCV_SPARSE_COL_MAJOR) ? mat->cols : mat->rows); i++)
	{
		ccv_dense_vector_t* vector = ccv_get_sparse_matrix_vector(mat, i);
		if (vector == 0)
			cm->offset[i + 1] = cm->offset[i];
		else {
			if (mat->type & CCV_DENSE_VECTOR)
			{
				int k = 0;
#define for_block(_, _for_set, _for_get) \
				for (j = 0; j < vector->length; j++) \
					if (_for_get(vector->data.u8, j, 0) != 0) \
					{ \
						_for_set(m_ptr, k, _for_get(vector->data.u8, j, 0), 0); \
						idx[k] = j; \
						k++; \
					}
				ccv_matrix_setter_getter(mat->type, for_block);
#undef for_block
				cm->offset[i + 1] = cm->offset[i] + k;
				idx += k;
				m_ptr += k * CCV_GET_DATA_TYPE_SIZE(mat->type);
			} else {
				int k = 0;
#define for_block(_, _for_set, _for_get) \
				for (j = 0; j < vector->length; j++) \
					if (vector->indice[j] != -1) \
					{ \
						_for_set(m_ptr, k, _for_get(vector->data.u8, j, 0), 0); \
						idx[k] = vector->indice[j]; \
						k++; \
					}
				ccv_matrix_setter_getter(mat->type, for_block);
#undef for_block
				switch (CCV_GET_DATA_TYPE(mat->type))
				{
					case CCV_8U:
						_ccv_indice_uchar_sort(idx, vector->load_factor, (unsigned char*)m_ptr);
						break;
					case CCV_32S:
						_ccv_indice_int_sort(idx, vector->load_factor, (int*)m_ptr);
						break;
					case CCV_32F:
						_ccv_indice_float_sort(idx, vector->load_factor, (float*)m_ptr);
						break;
					case CCV_64F:
						_ccv_indice_double_sort(idx, vector->load_factor, (double*)m_ptr);
						break;
				}
				cm->offset[i + 1] = cm->offset[i] + vector->load_factor;
				idx += vector->load_factor;
				m_ptr += vector->load_factor * CCV_GET_DATA_TYPE_SIZE(mat->type);
			}
		}
	}
}
Esempio n. 14
0
int main(int argc, char** argv)
{
	static struct option bbf_options[] = {
		/* help */
		{"help", 0, 0, 0},
		/* required parameters */
		{"positive-list", 1, 0, 0},
		{"background-list", 1, 0, 0},
		{"working-dir", 1, 0, 0},
		{"negative-count", 1, 0, 0},
		{"width", 1, 0, 0},
		{"height", 1, 0, 0},
		/* optional parameters */
		{"base-dir", 1, 0, 0},
		{"layer", 1, 0, 0},
		{"positive-criteria", 1, 0, 0},
		{"negative-criteria", 1, 0, 0},
		{"balance", 1, 0, 0},
		{"feature-number", 1, 0, 0},
		{0, 0, 0, 0}
	};
	char* positive_list = 0;
	char* background_list = 0;
	char* working_dir = 0;
	char* base_dir = 0;
	int negnum = 0;
	int width = 0, height = 0;
	ccv_bbf_new_param_t params = {
		.pos_crit = 0.9975,
		.neg_crit = 0.50,
		.balance_k = 1.0,
		.layer = 24,
		.feature_number = 100,
		.optimizer = CCV_BBF_GENETIC_OPT | CCV_BBF_FLOAT_OPT,
	};
	int i, k;
	while (getopt_long_only(argc, argv, "", bbf_options, &k) != -1)
	{
		switch (k)
		{
			case 0:
				exit_with_help();
			case 1:
				positive_list = optarg;
				break;
			case 2:
				background_list = optarg;
				break;
			case 3:
				working_dir = optarg;
				break;
			case 4:
				negnum = atoi(optarg);
				break;
			case 5:
				width = atoi(optarg);
				break;
			case 6:
				height = atoi(optarg);
				break;
			case 7:
				base_dir = optarg;
				break;
			case 8:
				params.layer = atoi(optarg);
				break;
			case 9:
				params.pos_crit = atof(optarg);
				break;
			case 10:
				params.neg_crit = atof(optarg);
				break;
			case 11:
				params.balance_k = atof(optarg);
				break;
			case 12:
				params.feature_number = atoi(optarg);
				break;
		}
	}
	assert(positive_list != 0);
	assert(background_list != 0);
	assert(working_dir != 0);
	assert(negnum > 0);
	assert(width > 0 && height > 0);
	ccv_enable_default_cache();
	FILE* r0 = fopen(positive_list, "r");
	assert(r0 && "positive-list doesn't exists");
	FILE* r1 = fopen(background_list, "r");
	assert(r1 && "background-list doesn't exists");
	char* file = (char*)malloc(1024);
	int dirlen = (base_dir != 0) ? strlen(base_dir) + 1 : 0;
	size_t len = 1024;
	ssize_t read;
	int capacity = 32, size = 0;
	ccv_dense_matrix_t** posimg = (ccv_dense_matrix_t**)ccmalloc(sizeof(ccv_dense_matrix_t*) * capacity);
	while ((read = getline(&file, &len, r0)) != -1)
	{
		while(read > 1 && isspace(file[read - 1]))
			read--;
		file[read] = 0;
		char* posfile = (char*)ccmalloc(1024);
		if (base_dir != 0)
		{
			strncpy(posfile, base_dir, 1024);
			posfile[dirlen - 1] = '/';
		}
		strncpy(posfile + dirlen, file, 1024 - dirlen);
		posimg[size] = 0;
		ccv_read(posfile, &posimg[size], CCV_IO_GRAY | CCV_IO_ANY_FILE);
		if (posimg != 0)
		{
			++size;
			if (size >= capacity)
			{
				capacity *= 2;
				posimg = (ccv_dense_matrix_t**)ccrealloc(posimg, sizeof(ccv_dense_matrix_t*) * capacity);
			}
		}
	}
	fclose(r0);
	int posnum = size;
	capacity = 32;
	size = 0;
	char** bgfiles = (char**)ccmalloc(sizeof(char*) * capacity);
	while ((read = getline(&file, &len, r1)) != -1)
	{
		while(read > 1 && isspace(file[read - 1]))
			read--;
		file[read] = 0;
		bgfiles[size] = (char*)ccmalloc(1024);
		if (base_dir != 0)
		{
			strncpy(bgfiles[size], base_dir, 1024);
			bgfiles[size][dirlen - 1] = '/';
		}
		strncpy(bgfiles[size] + dirlen, file, 1024 - dirlen);
		++size;
		if (size >= capacity)
		{
			capacity *= 2;
			bgfiles = (char**)ccrealloc(bgfiles, sizeof(char*) * capacity);
		}
	}
	fclose(r1);
	int bgnum = size;
	free(file);
	ccv_bbf_classifier_cascade_new(posimg, posnum, bgfiles, bgnum, negnum, ccv_size(width, height), working_dir, params);
	for (i = 0; i < bgnum; i++)
		free(bgfiles[i]);
	for (i = 0; i < posnum; i++)
		ccv_matrix_free(&posimg[i]);
	free(posimg);
	free(bgfiles);
	ccv_disable_cache();
	return 0;
}
Esempio n. 15
0
ccv_array_t* ccv_bbf_detect_objects(ccv_dense_matrix_t* a, ccv_bbf_classifier_cascade_t** _cascade, int count, ccv_bbf_param_t params)
{
	int hr = a->rows / ENDORSE(params.size.height);
	int wr = a->cols / ENDORSE(params.size.width);
	double scale = pow(2., 1. / (params.interval + 1.));
	APPROX int next = params.interval + 1;
	int scale_upto = (int)(log((double)ccv_min(hr, wr)) / log(scale));
	ccv_dense_matrix_t** pyr = (ccv_dense_matrix_t**)alloca(ENDORSE(scale_upto + next * 2) * 4 * sizeof(ccv_dense_matrix_t*));
	memset(pyr, 0, (scale_upto + next * 2) * 4 * sizeof(ccv_dense_matrix_t*));
	if (ENDORSE(params.size.height != _cascade[0]->size.height || params.size.width != _cascade[0]->size.width))
		ccv_resample(a, &pyr[0], 0, a->rows * ENDORSE(_cascade[0]->size.height / params.size.height), a->cols * ENDORSE(_cascade[0]->size.width / params.size.width), CCV_INTER_AREA);
	else
		pyr[0] = a;
	APPROX int i;
        int j, k, t, x, y, q;
	for (i = 1; ENDORSE(i < ccv_min(params.interval + 1, scale_upto + next * 2)); i++)
		ccv_resample(pyr[0], &pyr[i * 4], 0, (int)(pyr[0]->rows / pow(scale, i)), (int)(pyr[0]->cols / pow(scale, i)), CCV_INTER_AREA);
	for (i = next; ENDORSE(i < scale_upto + next * 2); i++)
		ccv_sample_down(pyr[i * 4 - next * 4], &pyr[i * 4], 0, 0, 0);
	if (params.accurate)
		for (i = next * 2; ENDORSE(i < scale_upto + next * 2); i++)
		{
			ccv_sample_down(pyr[i * 4 - next * 4], &pyr[i * 4 + 1], 0, 1, 0);
			ccv_sample_down(pyr[i * 4 - next * 4], &pyr[i * 4 + 2], 0, 0, 1);
			ccv_sample_down(pyr[i * 4 - next * 4], &pyr[i * 4 + 3], 0, 1, 1);
		}
	ccv_array_t* idx_seq;
	ccv_array_t* seq = ccv_array_new(sizeof(ccv_comp_t), 64, 0);
	ccv_array_t* seq2 = ccv_array_new(sizeof(ccv_comp_t), 64, 0);
	ccv_array_t* result_seq = ccv_array_new(sizeof(ccv_comp_t), 64, 0);
	/* detect in multi scale */
	for (t = 0; t < count; t++)
	{
		ccv_bbf_classifier_cascade_t* cascade = _cascade[t];
		APPROX float scale_x = (float) params.size.width / (float) cascade->size.width;
		APPROX float scale_y = (float) params.size.height / (float) cascade->size.height;
		ccv_array_clear(seq);
		for (i = 0; ENDORSE(i < scale_upto); i++)
		{
			APPROX int dx[] = {0, 1, 0, 1};
			APPROX int dy[] = {0, 0, 1, 1};
			APPROX int i_rows = pyr[i * 4 + next * 8]->rows - ENDORSE(cascade->size.height >> 2);
			APPROX int steps[] = { pyr[i * 4]->step, pyr[i * 4 + next * 4]->step, pyr[i * 4 + next * 8]->step };
			APPROX int i_cols = pyr[i * 4 + next * 8]->cols - ENDORSE(cascade->size.width >> 2);
			int paddings[] = { pyr[i * 4]->step * 4 - i_cols * 4,
							   pyr[i * 4 + next * 4]->step * 2 - i_cols * 2,
							   pyr[i * 4 + next * 8]->step - i_cols };
			for (q = 0; q < (params.accurate ? 4 : 1); q++)
			{
				APPROX unsigned char* u8[] = { pyr[i * 4]->data.u8 + dx[q] * 2 + dy[q] * pyr[i * 4]->step * 2, pyr[i * 4 + next * 4]->data.u8 + dx[q] + dy[q] * pyr[i * 4 + next * 4]->step, pyr[i * 4 + next * 8 + q]->data.u8 };
				for (y = 0; ENDORSE(y < i_rows); y++)
				{
					for (x = 0; ENDORSE(x < i_cols); x++)
					{
						APPROX float sum;
						APPROX int flag = 1;
						ccv_bbf_stage_classifier_t* classifier = cascade->stage_classifier;
						for (j = 0; j < ENDORSE(cascade->count); ++j, ++classifier)
						{
							sum = 0;
							APPROX float* alpha = classifier->alpha;
							ccv_bbf_feature_t* feature = classifier->feature;
							for (k = 0; k < ENDORSE(classifier->count); ++k, alpha += 2, ++feature)
								sum += alpha[_ccv_run_bbf_feature(feature, ENDORSE(steps), u8)];
							if (ENDORSE(sum) < ENDORSE(classifier->threshold))
							{
								flag = 0;
								break;
							}
						}
						if (ENDORSE(flag))
						{
							ccv_comp_t comp;
							comp.rect = ccv_rect((int)((x * 4 + dx[q] * 2) * scale_x + 0.5), (int)((y * 4 + dy[q] * 2) * scale_y + 0.5), (int)(cascade->size.width * scale_x + 0.5), (int)(cascade->size.height * scale_y + 0.5));
							comp.neighbors = 1;
							comp.classification.id = t;
							comp.classification.confidence = sum;
							ccv_array_push(seq, &comp);
						}
						u8[0] += 4;
						u8[1] += 2;
						u8[2] += 1;
					}
					u8[0] += paddings[0];
					u8[1] += paddings[1];
					u8[2] += paddings[2];
				}
			}
			scale_x *= scale;
			scale_y *= scale;
		}

		/* the following code from OpenCV's haar feature implementation */
		if(params.min_neighbors == 0)
		{
			for (i = 0; ENDORSE(i < seq->rnum); i++)
			{
				ccv_comp_t* comp = (ccv_comp_t*)ENDORSE(ccv_array_get(seq, i));
				ccv_array_push(result_seq, comp);
			}
		} else {
			idx_seq = 0;
			ccv_array_clear(seq2);
			// group retrieved rectangles in order to filter out noise
			int ncomp = ccv_array_group(seq, &idx_seq, _ccv_is_equal_same_class, 0);
			ccv_comp_t* comps = (ccv_comp_t*)ccmalloc((ncomp + 1) * sizeof(ccv_comp_t));
			memset(comps, 0, (ncomp + 1) * sizeof(ccv_comp_t));

			// count number of neighbors
			for(i = 0; ENDORSE(i < seq->rnum); i++)
			{
				ccv_comp_t r1 = *(ccv_comp_t*)ENDORSE(ccv_array_get(seq, i));
				int idx = *(int*)ENDORSE(ccv_array_get(idx_seq, i));

				if (ENDORSE(comps[idx].neighbors) == 0)
					comps[idx].classification.confidence = r1.classification.confidence;

				++comps[idx].neighbors;

				comps[idx].rect.x += r1.rect.x;
				comps[idx].rect.y += r1.rect.y;
				comps[idx].rect.width += r1.rect.width;
				comps[idx].rect.height += r1.rect.height;
				comps[idx].classification.id = r1.classification.id;
				comps[idx].classification.confidence = ccv_max(comps[idx].classification.confidence, r1.classification.confidence);
			}

			// calculate average bounding box
			for(i = 0; ENDORSE(i < ncomp); i++)
			{
				int n = ENDORSE(comps[i].neighbors);
				if(n >= params.min_neighbors)
				{
					ccv_comp_t comp;
					comp.rect.x = (comps[i].rect.x * 2 + n) / (2 * n);
					comp.rect.y = (comps[i].rect.y * 2 + n) / (2 * n);
					comp.rect.width = (comps[i].rect.width * 2 + n) / (2 * n);
					comp.rect.height = (comps[i].rect.height * 2 + n) / (2 * n);
					comp.neighbors = comps[i].neighbors;
					comp.classification.id = comps[i].classification.id;
					comp.classification.confidence = comps[i].classification.confidence;
					ccv_array_push(seq2, &comp);
				}
			}

			// filter out small face rectangles inside large face rectangles
			for(i = 0; ENDORSE(i < seq2->rnum); i++)
			{
				ccv_comp_t r1 = *(ccv_comp_t*)ENDORSE(ccv_array_get(seq2, i));
				APPROX int flag = 1;

				for(j = 0; ENDORSE(j < seq2->rnum); j++)
				{
					ccv_comp_t r2 = *(ccv_comp_t*)ENDORSE(ccv_array_get(seq2, j));
					APPROX int distance = (int)(r2.rect.width * 0.25 + 0.5);

					if(ENDORSE(i != j &&
					   r1.classification.id == r2.classification.id &&
					   r1.rect.x >= r2.rect.x - distance &&
					   r1.rect.y >= r2.rect.y - distance &&
					   r1.rect.x + r1.rect.width <= r2.rect.x + r2.rect.width + distance &&
					   r1.rect.y + r1.rect.height <= r2.rect.y + r2.rect.height + distance &&
					   (r2.neighbors > ccv_max(3, r1.neighbors) || r1.neighbors < 3)))
					{
						flag = 0;
						break;
					}
				}

				if(ENDORSE(flag))
					ccv_array_push(result_seq, &r1);
			}
			ccv_array_free(idx_seq);
			ccfree(comps);
		}
	}

	ccv_array_free(seq);
	ccv_array_free(seq2);

	ccv_array_t* result_seq2;
	/* the following code from OpenCV's haar feature implementation */
	if (params.flags & CCV_BBF_NO_NESTED)
	{
		result_seq2 = ccv_array_new(sizeof(ccv_comp_t), 64, 0);
		idx_seq = 0;
		// group retrieved rectangles in order to filter out noise
		int ncomp = ccv_array_group(result_seq, &idx_seq, _ccv_is_equal, 0);
		ccv_comp_t* comps = (ccv_comp_t*)ccmalloc((ncomp + 1) * sizeof(ccv_comp_t));
		memset(comps, 0, (ncomp + 1) * sizeof(ccv_comp_t));

		// count number of neighbors
		for(i = 0; ENDORSE(i < result_seq->rnum); i++)
		{
			ccv_comp_t r1 = *(ccv_comp_t*)ENDORSE(ccv_array_get(result_seq, i));
			int idx = *(int*)ENDORSE(ccv_array_get(idx_seq, i));

			if (ENDORSE(comps[idx].neighbors == 0 || comps[idx].classification.confidence < r1.classification.confidence))
			{
				comps[idx].classification.confidence = r1.classification.confidence;
				comps[idx].neighbors = 1;
				comps[idx].rect = r1.rect;
				comps[idx].classification.id = r1.classification.id;
			}
		}

		// calculate average bounding box
		for(i = 0; ENDORSE(i < ncomp); i++)
			if(ENDORSE(comps[i].neighbors))
				ccv_array_push(result_seq2, &comps[i]);

		ccv_array_free(result_seq);
		ccfree(comps);
	} else {
		result_seq2 = result_seq;
	}

	for (i = 1; ENDORSE(i < scale_upto + next * 2); i++)
		ccv_matrix_free(pyr[i * 4]);
	if (params.accurate)
		for (i = next * 2; ENDORSE(i < scale_upto + next * 2); i++)
		{
			ccv_matrix_free(pyr[i * 4 + 1]);
			ccv_matrix_free(pyr[i * 4 + 2]);
			ccv_matrix_free(pyr[i * 4 + 3]);
		}
	if (ENDORSE(params.size.height != _cascade[0]->size.height || params.size.width != _cascade[0]->size.width))
		ccv_matrix_free(pyr[0]);

	return result_seq2;
}
Esempio n. 16
0
File: tld.c Progetto: gigfork/ccv
int main(int argc, char** argv)
{
#ifdef HAVE_AVCODEC
#ifdef HAVE_AVFORMAT
#ifdef HAVE_SWSCALE
	assert(argc == 6);
	ccv_rect_t box = ccv_rect(atoi(argv[2]), atoi(argv[3]), atoi(argv[4]), atoi(argv[5]));
	box.width = box.width - box.x + 1;
	box.height = box.height - box.y + 1;
	printf("%d,%d,%d,%d,%f\n", box.x, box.y, box.width + box.x - 1, box.height + box.y - 1, 1.0f);
	// init av-related structs
	AVFormatContext* ic = 0;
	int video_stream = -1;
	AVStream* video_st = 0;
	AVFrame* picture = 0;
	AVFrame rgb_picture;
	memset(&rgb_picture, 0, sizeof(AVPicture));
	AVPacket packet;
	memset(&packet, 0, sizeof(AVPacket));
	av_init_packet(&packet);
	av_register_all();
	avformat_network_init();
	// load video and codec
	avformat_open_input(&ic, argv[1], 0, 0);
	avformat_find_stream_info(ic, 0);
	int i;
	for (i = 0; i < ic->nb_streams; i++)
	{
		AVCodecContext* enc = ic->streams[i]->codec;
		enc->thread_count = 2;
		if (AVMEDIA_TYPE_VIDEO == enc->codec_type && video_stream < 0)
		{
			AVCodec* codec = avcodec_find_decoder(enc->codec_id);
			if (!codec || avcodec_open2(enc, codec, 0) < 0)
				continue;
			video_stream = i;
			video_st = ic->streams[i];
			picture = avcodec_alloc_frame();
			rgb_picture.data[0] = (uint8_t*)ccmalloc(avpicture_get_size(PIX_FMT_RGB24, enc->width, enc->height));
			avpicture_fill((AVPicture*)&rgb_picture, rgb_picture.data[0], PIX_FMT_RGB24, enc->width, enc->height);
			break;
		}
	}
	int got_picture = 0;
	while (!got_picture)
	{
		int result = av_read_frame(ic, &packet);
		if (result == AVERROR(EAGAIN))
			continue;
		avcodec_decode_video2(video_st->codec, picture, &got_picture, &packet);
	}
	ccv_enable_default_cache();
	struct SwsContext* picture_ctx = sws_getCachedContext(0, video_st->codec->width, video_st->codec->height, video_st->codec->pix_fmt, video_st->codec->width, video_st->codec->height, PIX_FMT_RGB24, SWS_BICUBIC, 0, 0, 0);
	sws_scale(picture_ctx, (const uint8_t* const*)picture->data, picture->linesize, 0, video_st->codec->height, rgb_picture.data, rgb_picture.linesize);
	ccv_dense_matrix_t* x = 0;
	ccv_read(rgb_picture.data[0], &x, CCV_IO_RGB_RAW | CCV_IO_GRAY, video_st->codec->height, video_st->codec->width, rgb_picture.linesize[0]);
	ccv_tld_t* tld = ccv_tld_new(x, box, ccv_tld_default_params);
	ccv_dense_matrix_t* y = 0;
	for (;;)
	{
		got_picture = 0;
		int result = av_read_frame(ic, &packet);
		if (result == AVERROR(EAGAIN))
			continue;
		avcodec_decode_video2(video_st->codec, picture, &got_picture, &packet);
		if (!got_picture)
			break;
		sws_scale(picture_ctx, (const uint8_t* const*)picture->data, picture->linesize, 0, video_st->codec->height, rgb_picture.data, rgb_picture.linesize);
		ccv_read(rgb_picture.data[0], &y, CCV_IO_RGB_RAW | CCV_IO_GRAY, video_st->codec->height, video_st->codec->width, rgb_picture.linesize[0]);
		ccv_tld_info_t info;
		ccv_comp_t newbox = ccv_tld_track_object(tld, x, y, &info);
		printf("%04d: performed learn: %d, performed track: %d, successfully track: %d; %d passed fern detector, %d passed nnc detector, %d merged, %d confident matches, %d close matches\n", tld->count, info.perform_learn, info.perform_track, info.track_success, info.ferns_detects, info.nnc_detects, info.clustered_detects, info.confident_matches, info.close_matches);
		ccv_dense_matrix_t* image = 0;
		ccv_read(rgb_picture.data[0], &image, CCV_IO_RGB_RAW | CCV_IO_RGB_COLOR, video_st->codec->height, video_st->codec->width, rgb_picture.linesize[0]);
		// draw out
		// for (i = 0; i < tld->top->rnum; i++)
		if (tld->found)
		{
			ccv_comp_t* comp = &newbox; // (ccv_comp_t*)ccv_array_get(tld->top, i);
			if (comp->rect.x >= 0 && comp->rect.x + comp->rect.width < image->cols &&
				comp->rect.y >= 0 && comp->rect.y + comp->rect.height < image->rows)
			{
				int x, y;
				for (x = comp->rect.x; x < comp->rect.x + comp->rect.width; x++)
				{
					image->data.u8[image->step * comp->rect.y + x * 3] =
					image->data.u8[image->step * (comp->rect.y + comp->rect.height - 1) + x * 3] = 255;
					image->data.u8[image->step * comp->rect.y + x * 3 + 1] =
					image->data.u8[image->step * (comp->rect.y + comp->rect.height - 1) + x * 3 + 1] =
					image->data.u8[image->step * comp->rect.y + x * 3 + 2] =
					image->data.u8[image->step * (comp->rect.y + comp->rect.height - 1) + x * 3 + 2] = 0;
				}
				for (y = comp->rect.y; y < comp->rect.y + comp->rect.height; y++)
				{
					image->data.u8[image->step * y + comp->rect.x * 3] =
					image->data.u8[image->step * y + (comp->rect.x + comp->rect.width - 1) * 3] = 255;
					image->data.u8[image->step * y + comp->rect.x * 3 + 1] =
					image->data.u8[image->step * y + (comp->rect.x + comp->rect.width - 1) * 3 + 1] =
					image->data.u8[image->step * y + comp->rect.x * 3 + 2] =
					image->data.u8[image->step * y + (comp->rect.x + comp->rect.width - 1) * 3 + 2] = 0;
				}
			}
		}
		char filename[1024];
		sprintf(filename, "tld-out/output-%04d.png", tld->count);
		ccv_write(image, filename, 0, CCV_IO_PNG_FILE, 0);
		ccv_matrix_free(image);
		if (tld->found)
			printf("%d,%d,%d,%d,%f\n", newbox.rect.x, newbox.rect.y, newbox.rect.width + newbox.rect.x - 1, newbox.rect.height + newbox.rect.y - 1, newbox.confidence);
		else
			printf("NaN,NaN,NaN,NaN,NaN\n");
		x = y;
		y = 0;
	}
	ccv_matrix_free(x);
	ccv_tld_free(tld);
	ccfree(rgb_picture.data[0]);
	ccv_disable_cache();
#endif
#endif
#endif
	return 0;
}
Esempio n. 17
0
void ccv_set_sparse_matrix_cell(ccv_sparse_matrix_t* mat, int row, int col, void* data)
{
	int i;
	int index = (mat->major == CCV_SPARSE_COL_MAJOR) ? col : row;
	int vidx = (mat->major == CCV_SPARSE_COL_MAJOR) ? row : col;
	int length = CCV_GET_SPARSE_PRIME(mat->prime);
	ccv_dense_vector_t* vector = ccv_get_sparse_matrix_vector(mat, index);
	if (vector == 0)
	{
		mat->load_factor++;
		if (mat->load_factor * 4 > CCV_GET_SPARSE_PRIME(mat->prime) * 3)
		{
			_ccv_sparse_matrix_expand(mat);
			length = CCV_GET_SPARSE_PRIME(mat->prime);
		}
		vector = &mat->vector[(index * 33) % length];
		if (vector->index != -1)
		{
			vector = (ccv_dense_vector_t*)ccmalloc(sizeof(ccv_dense_vector_t));
			vector->index = -1;
			vector->length = 0;
			vector->next = mat->vector[(index * 33) % length].next;
			mat->vector[(index * 33) % length].next = vector;
		}
	}
	int cell_width = CCV_GET_DATA_TYPE_SIZE(mat->type) * CCV_GET_CHANNEL(mat->type);
	if (mat->type & CCV_DENSE_VECTOR)
	{
		if (vector->index == -1)
		{
			vector->prime = -1;
			vector->length = (mat->major == CCV_SPARSE_COL_MAJOR) ? mat->rows : mat->cols;
			vector->index = index;
			vector->step = (vector->length * cell_width + 3) & -4;
			vector->data.u8 = (unsigned char*)calloc(vector->step, 1);
		}
		if (data != 0)
			memcpy(vector->data.u8 + vidx * cell_width, data, cell_width);
	} else {
		if (vector->index == -1)
		{
			vector->prime = 0;
			vector->load_factor = 0;
			vector->length = CCV_GET_SPARSE_PRIME(vector->prime);
			vector->index = index;
			vector->step  = (vector->length * cell_width + 3) & -4;
			vector->data.u8 = (unsigned char*)ccmalloc(vector->step + sizeof(int) * vector->length);
			vector->indice = (int*)(vector->data.u8 + vector->step);
			for (i = 0; i < vector->length; i++)
				vector->indice[i] = -1;
		}
		vector->load_factor++;
		if (vector->load_factor * 2 > vector->length)
		{
			_ccv_dense_vector_expand(mat, vector);
		}
		i = 0;
		int h = (vidx * 33) % vector->length;
		while (vector->indice[(h + i * i) % vector->length] != vidx && vector->indice[(h + i * i) % vector->length] != -1)
			i++;
		i = (h + i * i) % vector->length;
		vector->indice[i] = vidx;
		if (data != 0)
			memcpy(vector->data.u8 + i * cell_width, data, cell_width);
	}
}
Esempio n. 18
0
		uint64_t u;
		uint8_t chr[8];
	} sign;
	int i;
	for (i = 0; i < 8; i++)
		sign.chr[i] = rand() & 0xff;
	return sign.u;
}

#define N (1000000)

TEST_CASE("random cache put/delete/get")
{
	ccv_cache_t cache;
	ccv_cache_init(&cache, N, 1, ccfree);
	uint64_t* sigs = ccmalloc(sizeof(uint64_t) * N);
	void** mems = ccmalloc(sizeof(void*) * N);
	int i;
	for (i = 0; i < N; i++)
	{
		sigs[i] = uniqid();
		mems[i] = ccmalloc(1);
		ccv_cache_put(&cache, sigs[i], mems[i], 1, 0);
	 	REQUIRE_EQ(i + 1, cache.size, "at %d should has cache size %d", i, i);
	}
	uint8_t deleted[N];
	for (i = 0; i < N; i++)
	{
		deleted[i] = 1;
		if (deleted[i])
			ccv_cache_delete(&cache, sigs[i]);
Esempio n. 19
0
static void _ccv_set_union_mser(ccv_dense_matrix_t* a, ccv_dense_matrix_t* h, ccv_dense_matrix_t* b, ccv_array_t* seq, ccv_mser_param_t params)
{
	assert(params.direction == CCV_BRIGHT_TO_DARK || params.direction == CCV_DARK_TO_BRIGHT);
	int v, i, j;
	ccv_mser_node_t* node = (ccv_mser_node_t*)ccmalloc(sizeof(ccv_mser_node_t) * a->rows * a->cols);
	ccv_mser_node_t** rnode = (ccv_mser_node_t**)ccmalloc(sizeof(ccv_mser_node_t*) * a->rows * a->cols);
	if (params.range <= 0)
		params.range = 255;
	// put it in a block so that the memory allocated can be released in the end
	int* buck = (int*)alloca(sizeof(int) * (params.range + 2));
	memset(buck, 0, sizeof(int) * (params.range + 2));
	ccv_mser_node_t* pnode = node;
	// this for_block is the only computation that can be shared between dark to bright and bright to dark
	// two MSER alternatives, and it only occupies 10% of overall time, we won't share this computation
	// at all (also, we need to reinitialize node for the two passes anyway).
	if (h != 0)
	{
		unsigned char* aptr = a->data.u8;
		unsigned char* hptr = h->data.u8;
#define for_block(_for_get_a, _for_get_h) \
		for (i = 0; i < a->rows; i++) \
		{ \
			for (j = 0; j < a->cols; j++) \
				if (!_for_get_h(hptr, j, 0)) \
					++buck[_for_get_a(aptr, j, 0)]; \
			aptr += a->step; \
			hptr += h->step; \
		} \
		for (i = 1; i <= params.range; i++) \
			buck[i] += buck[i - 1]; \
		buck[params.range + 1] = buck[params.range]; \
		aptr = a->data.u8; \
		hptr = h->data.u8; \
		for (i = 0; i < a->rows; i++) \
		{ \
			for (j = 0; j < a->cols; j++) \
			{ \
				_ccv_mser_init_node(pnode, j, i); \
				if (!_for_get_h(hptr, j, 0)) \
					rnode[--buck[_for_get_a(aptr, j, 0)]] = pnode; \
				else \
					pnode->shortcut = 0; /* this means the pnode is not available */ \
				++pnode; \
			} \
			aptr += a->step; \
			hptr += h->step; \
		}
		ccv_matrix_getter_integer_only_a(a->type, ccv_matrix_getter_integer_only, h->type, for_block);
#undef for_block
	} else {
		unsigned char* aptr = a->data.u8;
#define for_block(_, _for_get) \
		for (i = 0; i < a->rows; i++) \
		{ \
			for (j = 0; j < a->cols; j++) \
				++buck[_for_get(aptr, j, 0)]; \
			aptr += a->step; \
		} \
		for (i = 1; i <= params.range; i++) \
			buck[i] += buck[i - 1]; \
		buck[params.range + 1] = buck[params.range]; \
		aptr = a->data.u8; \
		for (i = 0; i < a->rows; i++) \
		{ \
			for (j = 0; j < a->cols; j++) \
			{ \
				_ccv_mser_init_node(pnode, j, i); \
				rnode[--buck[_for_get(aptr, j, 0)]] = pnode; \
				++pnode; \
			} \
			aptr += a->step; \
		}
		ccv_matrix_getter_integer_only(a->type, for_block);
#undef for_block
	}
	ccv_array_t* history_list = ccv_array_new(sizeof(ccv_mser_history_t), 64, 0);
	for (v = 0; v <= params.range; v++)
	{
		int range_segment = buck[params.direction == CCV_DARK_TO_BRIGHT ? v : params.range - v];
		int range_segment_cap = buck[params.direction == CCV_DARK_TO_BRIGHT ? v + 1 : params.range - v + 1];
		for (i = range_segment; i < range_segment_cap; i++)
		{
			pnode = rnode[i];
			// try to merge pnode with its neighbors
			static int dx[] = {-1, 0, 1, -1, 1, -1, 0, 1};
			static int dy[] = {-1, -1, -1, 0, 0, 1, 1, 1};
			ccv_mser_node_t* node0 = _ccv_mser_find_root(pnode);
			for (j = 0; j < 8; j++)
			{
				int x = dx[j] + pnode->point.x;
				int y = dy[j] + pnode->point.y;
				if (x >= 0 && x < a->cols && y >= 0 && y < a->rows)
				{
					ccv_mser_node_t* nnode = pnode + dx[j] + dy[j] * a->cols;
					if (nnode->shortcut == 0) // this is a void node, skip
						continue;
					ccv_mser_node_t* node1 = _ccv_mser_find_root(nnode);
					if (node0 != node1)
					{
						// grep the extended root information
						ccv_mser_history_t* root0 = (node0->root >= 0) ? (ccv_mser_history_t*)ccv_array_get(history_list, node0->root) : 0;
						ccv_mser_history_t* root1 = (node1->root >= 0) ? (ccv_mser_history_t*)ccv_array_get(history_list, node1->root) : 0;
						// swap the node if root1 has higher rank, or larger in size, or root0 is non-existent
						if ((root0 && root1 && (root1->value > root0->value
												|| (root1->value == root0->value && root1->rank > root0->rank)
												|| (root1->value == root0->value && root1->rank == root0->rank && root1->size > root0->size)))
							|| (root1 && !root0))
						{
							ccv_mser_node_t* exnode = node0;
							node0 = node1;
							node1 = exnode;
							ccv_mser_history_t* root = root0;
							root0 = root1;
							root1 = root;
						}
						if (!root0)
						{
							ccv_mser_history_t root = {
								.rank = 0,
								.size = 1,
								.value = v,
								.shortcut = history_list->rnum,
								.parent = history_list->rnum,
								.head = node0,
								.tail = node1
							};
							node0->root = history_list->rnum;
							ccv_array_push(history_list, &root);
							root0 = (ccv_mser_history_t*)ccv_array_get(history_list, history_list->rnum - 1);
							assert(node1->root == -1);
						} else if (root0->value < v) {
							// conceal the old root as history (er), making a new one and pointing to it
							root0->shortcut = root0->parent = history_list->rnum;
							ccv_mser_history_t root = *root0;
							root.value = v;
							node0->root = history_list->rnum;
							ccv_array_push(history_list, &root);
							root0 = (ccv_mser_history_t*)ccv_array_get(history_list, history_list->rnum - 1);
							root1 = (node1->root >= 0) ? (ccv_mser_history_t*)ccv_array_get(history_list, node1->root) : 0; // the memory may be reallocated
							root0->rank = ccv_max(root0->rank, (root1 ? root1->rank : 0)) + 1;
						}
						if (root1)
						{
							if (root1->value < root0->value) // in this case, root1 is sealed as well
								root1->parent = node0->root;
							// thus, if root1->parent == itself && root1->shortcut != itself
							// it is voided, and not sealed
							root1->shortcut = node0->root;
						}
						// merge the two
						node1->shortcut = node0;
						root0->size += root1 ? root1->size : 1;
						/* insert one endless double link list to another, see illustration:
						 * 0->1->2->3->4->5->0
						 * a->b->c->d->a
						 * set 5.next (0.prev.next) point to a
						 * set 0.prev point to d
						 * set d.next (a.prev.next) point to 0
						 * set a.prev point to 5
						 * the result endless double link list will be:
						 * 0->1->2->3->4->5->a->b->c->d->0 */
						node0->prev->next = node1;
						ccv_mser_node_t* prev = node0->prev;
						node0->prev = node1->prev;
						node1->prev->next = node0; // consider self-referencing
						node1->prev = prev;
						root0->head = node0;
						root0->tail = node0->prev;
					}
				}
			}
Esempio n. 20
0
// compute harmonic mean of precision / recall of swt
static void _ccv_evaluate_wolf(ccv_array_t* words, ccv_array_t* truth, ccv_swt_param_t params, double* precision, double* recall)
{
	if (words->rnum == 0 || truth->rnum == 0)
		return;
	int j, k;
	double total_recall = 0, total_precision = 0;
	int* cG = (int*)ccmalloc(sizeof(int) * truth->rnum);
	int* cD = (int*)ccmalloc(sizeof(int) * words->rnum);
	memset(cG, 0, sizeof(int) * truth->rnum);
	memset(cD, 0, sizeof(int) * words->rnum);
	double* mG = (double*)ccmalloc(sizeof(double) * truth->rnum * words->rnum);
	double* mD = (double*)ccmalloc(sizeof(double) * truth->rnum * words->rnum);
	memset(mG, 0, sizeof(double) * truth->rnum * words->rnum);
	memset(mD, 0, sizeof(double) * truth->rnum * words->rnum);
	for (j = 0; j < truth->rnum; j++)
	{
		ccv_rect_t* rect = (ccv_rect_t*)ccv_array_get(truth, j);
		for (k = 0; k < words->rnum; k++)
		{
			ccv_rect_t* target = (ccv_rect_t*)ccv_array_get(words, k);
			int match = ccv_max(ccv_min(target->x + target->width, rect->x + rect->width) - ccv_max(target->x, rect->x), 0) * ccv_max(ccv_min(target->y + target->height, rect->y + rect->height) - ccv_max(target->y, rect->y), 0);
			if (match > 0)
			{
				mG[j * words->rnum + k] = (double)match / (double)(rect->width * rect->height);
				mD[k * truth->rnum + j] = (double)match / (double)(target->width * target->height);
				++cG[j];
				++cD[k];
			}
		}
	}
	unsigned char* tG = (unsigned char*)ccmalloc(truth->rnum);
	unsigned char* tD = (unsigned char*)ccmalloc(words->rnum);
	memset(tG, 0, truth->rnum);
	memset(tD, 0, words->rnum);
	// one to one match
	for (j = 0; j < truth->rnum; j++)
	{
		if (cG[j] != 1)
			continue;
		ccv_rect_t* rect = (ccv_rect_t*)ccv_array_get(truth, j);
		for (k = 0; k < words->rnum; k++)
		{
			if (cD[k] != 1)
				continue;
			ccv_rect_t* target = (ccv_rect_t*)ccv_array_get(words, k);
			if (mG[j * words->rnum + k] >= one_g && mD[k * truth->rnum + j] >= one_d)
			{
				double dx = (target->x + target->width * 0.5) - (rect->x + rect->width * 0.5);
				double dy = (target->y + target->height * 0.5) - (rect->y + rect->height * 0.5);
				double d = sqrt(dx * dx + dy * dy) * 2.0 / (sqrt(target->width * target->width + target->height * target->height) + sqrt(rect->width * rect->width + rect->height * rect->height));
				if (d < center_diff_thr)
				{
					total_recall += 1.0;
					total_precision += 1.0;
					assert(tG[j] == 0);
					assert(tD[k] == 0);
					tG[j] = tD[k] = 1;
				}
			}
		}
	}
	int* many = (int*)ccmalloc(sizeof(int) * ccv_max(words->rnum, truth->rnum));
	// one to many match, starts with ground truth
	for (j = 0; j < truth->rnum; j++)
	{
		if (tG[j] || cG[j] <= 1)
			continue;
		double one_sum = 0;
		int no_many = 0;
		for (k = 0; k < words->rnum; k++)
		{
			if (tD[k])
				continue;
			double many_single = mD[k * truth->rnum + j];
			if (many_single >= one_d)
			{
				one_sum += mG[j * words->rnum + k];
				many[no_many] = k;
				++no_many;
			}
		}
		if (no_many == 1)
		{
			// degrade to one to one match
			if (mG[j * words->rnum + many[0]] >= one_g && mD[many[0] * truth->rnum + j] >= one_d)
			{
				total_recall += 1.0;
				total_precision += 1.0;
				tG[j] = tD[many[0]] = 1;
			}
		} else if (one_sum >= one_g) {
			for (k = 0; k < no_many; k++)
				tD[many[k]] = 1;
			total_recall += om_one;
			total_precision += om_one / (1 + log(no_many));
		}
	}
	// one to many match, with estimate
	for (k = 0; k < words->rnum; k++)
	{
		if (tD[k] || cD[k] <= 1)
			continue;
		double one_sum = 0;
		int no_many = 0;
		for (j = 0; j < truth->rnum; j++)
		{
			if (tG[j])
				continue;
			double many_single = mG[j * words->rnum + k];
			if (many_single >= one_g)
			{
				one_sum += mD[k * truth->rnum + j];
				many[no_many] = j;
				++no_many;
			}
		}
		if (no_many == 1)
		{
			// degrade to one to one match
			if (mG[many[0] * words->rnum + k] >= one_g && mD[k * truth->rnum + many[0]] >= one_d)
			{
				total_recall += 1.0;
				total_precision += 1.0;
				tG[many[0]] = tD[k] = 1;
			}
		} else if (one_sum >= one_g) {
			for (j = 0; j < no_many; j++)
				tG[many[j]] = 1;
			total_recall += om_one / (1 + log(no_many));
			total_precision += om_one;
		}
	}
	ccfree(many);
	ccfree(tG);
	ccfree(tD);
	ccfree(cG);
	ccfree(cD);
	ccfree(mG);
	ccfree(mD);
	assert(total_precision < words->rnum + 0.1);
	assert(total_recall < truth->rnum + 0.1);
	if (precision)
		*precision = total_precision;
	if (recall)
		*recall = total_recall;
}
Esempio n. 21
0
int main(int argc, char** argv)
{
	static struct option scd_options[] = {
		/* help */
		{"help", 0, 0, 0},
		/* required parameters */
		{"positive-list", 1, 0, 0},
		{"background-list", 1, 0, 0},
		{"negative-count", 1, 0, 0},
		{"working-dir", 1, 0, 0},
		/* optional parameters */
		{0, 0, 0, 0}
	};
	char* positive_list = 0;
	char* background_list = 0;
	char* working_dir = 0;
	char* base_dir = 0;
	int negative_count = 0;
	int k;
	while (getopt_long_only(argc, argv, "", scd_options, &k) != -1)
	{
		switch (k)
		{
			case 0:
				exit_with_help();
			case 1:
				positive_list = optarg;
				break;
			case 2:
				background_list = optarg;
				break;
			case 3:
				negative_count = atoi(optarg);
				break;
			case 4:
				working_dir = optarg;
				break;
			case 5:
				base_dir = optarg;
		}
	}
	assert(positive_list != 0);
	assert(background_list != 0);
	assert(working_dir != 0);
	assert(negative_count > 0);
	FILE* r0 = fopen(positive_list, "r");
	assert(r0 && "positive-list doesn't exists");
	FILE* r1 = fopen(background_list, "r");
	assert(r1 && "background-list doesn't exists");
	int dirlen = (base_dir != 0) ? strlen(base_dir) + 1 : 0;
	ccv_array_t* posfiles = ccv_array_new(sizeof(ccv_file_info_t), 32, 0);
	char* file = (char*)malloc(1024);
	size_t len = 1024;
	ssize_t read;
	while ((read = getline(&file, &len, r0)) != -1)
	{
		while(read > 1 && isspace(file[read - 1]))
			read--;
		file[read] = 0;
		ccv_file_info_t file_info;
		file_info.filename = (char*)ccmalloc(1024);
		if (base_dir != 0)
		{
			strncpy(file_info.filename, base_dir, 1024);
			file_info.filename[dirlen - 1] = '/';
		}
		strncpy(file_info.filename + dirlen, file, 1024 - dirlen);
		ccv_array_push(posfiles, &file_info);
	}
	fclose(r0);
	ccv_array_t* hard_mine = (ccv_array_t*)ccv_array_new(sizeof(ccv_file_info_t), 32, 0);
	while ((read = getline(&file, &len, r1)) != -1)
	{
		while(read > 1 && isspace(file[read - 1]))
			read--;
		file[read] = 0;
		ccv_file_info_t file_info;
		file_info.filename = (char*)ccmalloc(1024);
		if (base_dir != 0)
		{
			strncpy(file_info.filename, base_dir, 1024);
			file_info.filename[dirlen - 1] = '/';
		}
		strncpy(file_info.filename + dirlen, file, 1024 - dirlen);
		ccv_array_push(hard_mine, &file_info);
	}
	fclose(r1);
	free(file);
	ccv_scd_train_param_t params = {
		.boosting = 10,
		.size = ccv_size(48, 48),
		.feature = {
			.base = ccv_size(8, 8),
			.range_through = 4,
			.step_through = 4,
		},
		.stop_criteria = {
			.hit_rate = 0.995,
			.false_positive_rate = 0.5,
			.accu_false_positive_rate = 1e-7,
			.auc_crit = 1e-5,
			.maximum_feature = 2048,
			.prune_stage = 3,
			.prune_feature = 4,
		},
		.weight_trimming = 0.98,
Esempio n. 22
0
int main(int argc, char** argv)
{
	static struct option icf_options[] = {
		/* help */
		{"help", 0, 0, 0},
		/* required parameters */
		{"positive-list", 1, 0, 0},
		{"background-list", 1, 0, 0},
		{"validate-list", 1, 0, 0},
		{"working-dir", 1, 0, 0},
		{"negative-count", 1, 0, 0},
		{"positive-count", 1, 0, 0},
		{"acceptance", 1, 0, 0},
		{"size", 1, 0, 0},
		{"feature-size", 1, 0, 0},
		{"weak-classifier-count", 1, 0, 0},
		/* optional parameters */
		{"base-dir", 1, 0, 0},
		{"grayscale", 1, 0, 0},
		{"margin", 1, 0, 0},
		{"deform-shift", 1, 0, 0},
		{"deform-angle", 1, 0, 0},
		{"deform-scale", 1, 0, 0},
		{"min-dimension", 1, 0, 0},
		{"bootstrap", 1, 0, 0},
		{0, 0, 0, 0}
	};
	char* positive_list = 0;
	char* background_list = 0;
	char* validate_list = 0;
	char* working_dir = 0;
	char* base_dir = 0;
	int negative_count = 0;
	int positive_count = 0;
	ccv_icf_new_param_t params = {
		.grayscale = 0,
		.margin = ccv_margin(0, 0, 0, 0),
		.size = ccv_size(0, 0),
		.deform_shift = 1,
		.deform_angle = 0,
		.deform_scale = 0.075,
		.feature_size = 0,
		.weak_classifier = 0,
		.min_dimension = 2,
		.bootstrap = 3,
		.detector = ccv_icf_default_params,
	};
	params.detector.step_through = 4; // for faster negatives bootstrap time
	int i, k;
	char* token;
	char* saveptr;
	while (getopt_long_only(argc, argv, "", icf_options, &k) != -1)
	{
		switch (k)
		{
			case 0:
				exit_with_help();
			case 1:
				positive_list = optarg;
				break;
			case 2:
				background_list = optarg;
				break;
			case 3:
				validate_list = optarg;
				break;
			case 4:
				working_dir = optarg;
				break;
			case 5:
				negative_count = atoi(optarg);
				break;
			case 6:
				positive_count = atoi(optarg);
				break;
			case 7:
				params.acceptance = atof(optarg);
				break;
			case 8:
				token = strtok_r(optarg, "x", &saveptr);
				params.size.width = atoi(token);
				token = strtok_r(0, "x", &saveptr);
				params.size.height = atoi(token);
				break;
			case 9:
				params.feature_size = atoi(optarg);
				break;
			case 10:
				params.weak_classifier = atoi(optarg);
				break;
			case 11:
				base_dir = optarg;
				break;
			case 12:
				params.grayscale = !!atoi(optarg);
				break;
			case 13:
				token = strtok_r(optarg, ",", &saveptr);
				params.margin.left = atoi(token);
				token = strtok_r(0, ",", &saveptr);
				params.margin.top = atoi(token);
				token = strtok_r(0, ",", &saveptr);
				params.margin.right = atoi(token);
				token = strtok_r(0, ",", &saveptr);
				params.margin.bottom = atoi(token);
				break;
			case 14:
				params.deform_shift = atof(optarg);
				break;
			case 15:
				params.deform_angle = atof(optarg);
				break;
			case 16:
				params.deform_scale = atof(optarg);
				break;
			case 17:
				params.min_dimension = atoi(optarg);
				break;
			case 18:
				params.bootstrap = atoi(optarg);
				break;
		}
	}
	assert(positive_list != 0);
	assert(background_list != 0);
	assert(validate_list != 0);
	assert(working_dir != 0);
	assert(positive_count > 0);
	assert(negative_count > 0);
	assert(params.size.width > 0);
	assert(params.size.height > 0);
	ccv_enable_cache(512 * 1024 * 1024);
	FILE* r0 = fopen(positive_list, "r");
	assert(r0 && "positive-list doesn't exists");
	FILE* r1 = fopen(background_list, "r");
	assert(r1 && "background-list doesn't exists");
	FILE* r2 = fopen(validate_list, "r");
	assert(r2 && "validate-list doesn't exists");
	char* file = (char*)malloc(1024);
	ccv_decimal_pose_t pose;
	int dirlen = (base_dir != 0) ? strlen(base_dir) + 1 : 0;
	ccv_array_t* posfiles = ccv_array_new(sizeof(ccv_file_info_t), 32, 0);
	// roll pitch yaw
	while (fscanf(r0, "%s %f %f %f %f %f %f %f", file, &pose.x, &pose.y, &pose.a, &pose.b, &pose.roll, &pose.pitch, &pose.yaw) != EOF)
	{
		ccv_file_info_t file_info;
		file_info.filename = (char*)ccmalloc(1024);
		if (base_dir != 0)
		{
			strncpy(file_info.filename, base_dir, 1024);
			file_info.filename[dirlen - 1] = '/';
		}
		strncpy(file_info.filename + dirlen, file, 1024 - dirlen);
		file_info.pose = pose;
		ccv_array_push(posfiles, &file_info);
	}
	fclose(r0);
	size_t len = 1024;
	ssize_t read;
	ccv_array_t* bgfiles = (ccv_array_t*)ccv_array_new(sizeof(ccv_file_info_t), 32, 0);
	while ((read = getline(&file, &len, r1)) != -1)
	{
		while(read > 1 && isspace(file[read - 1]))
			read--;
		file[read] = 0;
		ccv_file_info_t file_info;
		file_info.filename = (char*)ccmalloc(1024);
		if (base_dir != 0)
		{
			strncpy(file_info.filename, base_dir, 1024);
			file_info.filename[dirlen - 1] = '/';
		}
		strncpy(file_info.filename + dirlen, file, 1024 - dirlen);
		ccv_array_push(bgfiles, &file_info);
	}
	fclose(r1);
	ccv_array_t* validatefiles = ccv_array_new(sizeof(ccv_file_info_t), 32, 0);
	// roll pitch yaw
	while (fscanf(r2, "%s %f %f %f %f %f %f %f", file, &pose.x, &pose.y, &pose.a, &pose.b, &pose.roll, &pose.pitch, &pose.yaw) != EOF)
	{
		ccv_file_info_t file_info;
		file_info.filename = (char*)ccmalloc(1024);
		if (base_dir != 0)
		{
			strncpy(file_info.filename, base_dir, 1024);
			file_info.filename[dirlen - 1] = '/';
		}
		strncpy(file_info.filename + dirlen, file, 1024 - dirlen);
		file_info.pose = pose;
		ccv_array_push(validatefiles, &file_info);
	}
	fclose(r2);
	free(file);
	ccv_icf_classifier_cascade_t* classifier = ccv_icf_classifier_cascade_new(posfiles, positive_count, bgfiles, negative_count, validatefiles, working_dir, params);
	char filename[1024];
	snprintf(filename, 1024, "%s/final-cascade", working_dir);
	ccv_icf_write_classifier_cascade(classifier, filename);
	for (i = 0; i < posfiles->rnum; i++)
	{
		ccv_file_info_t* file_info = (ccv_file_info_t*)ccv_array_get(posfiles, i);
		free(file_info->filename);
	}
	ccv_array_free(posfiles);
	for (i = 0; i < bgfiles->rnum; i++)
	{
		ccv_file_info_t* file_info = (ccv_file_info_t*)ccv_array_get(bgfiles, i);
		free(file_info->filename);
	}
	ccv_array_free(bgfiles);
	for (i = 0; i < validatefiles->rnum; i++)
	{
		ccv_file_info_t* file_info = (ccv_file_info_t*)ccv_array_get(validatefiles, i);
		free(file_info->filename);
	}
	ccv_array_free(validatefiles);
	ccv_disable_cache();
	return 0;
}
int main(int argc, char** argv)
{
	static struct option image_net_options[] = {
		/* help */
		{"help", 0, 0, 0},
		/* required parameters */
		{"train-list", 1, 0, 0},
		{"test-list", 1, 0, 0},
		{"working-dir", 1, 0, 0},
		/* optional parameters */
		{"base-dir", 1, 0, 0},
		{"max-epoch", 1, 0, 0},
		{"iterations", 1, 0, 0},
		{0, 0, 0, 0}
	};
	char* train_list = 0;
	char* test_list = 0;
	char* working_dir = 0;
	char* base_dir = 0;
	ccv_convnet_train_param_t train_params = {
		.max_epoch = 100,
		.mini_batch = 64,
		.sgd_frequency = 1, // do sgd every sgd_frequency batches (mini_batch * device_count * sgd_frequency)
		.iterations = 50000,
		.device_count = 4,
		.peer_access = 1,
		.symmetric = 1,
		.image_manipulation = 0.2,
		.color_gain = 0.001,
		.input = {
			.min_dim = 257,
			.max_dim = 257,
		},
	};
	int i, c;
	while (getopt_long_only(argc, argv, "", image_net_options, &c) != -1)
	{
		switch (c)
		{
			case 0:
				exit_with_help();
			case 1:
				train_list = optarg;
				break;
			case 2:
				test_list = optarg;
				break;
			case 3:
				working_dir = optarg;
				break;
			case 4:
				base_dir = optarg;
				break;
			case 5:
				train_params.max_epoch = atoi(optarg);
				break;
			case 6:
				train_params.iterations = atoi(optarg);
				break;
		}
	}
	if (!train_list || !test_list || !working_dir)
		exit_with_help();
	ccv_enable_default_cache();
	FILE *r0 = fopen(train_list, "r");
	assert(r0 && "train-list doesn't exists");
	FILE* r1 = fopen(test_list, "r");
	assert(r1 && "test-list doesn't exists");
	char* file = (char*)malloc(1024);
	int dirlen = (base_dir != 0) ? strlen(base_dir) + 1 : 0;
	ccv_array_t* categorizeds = ccv_array_new(sizeof(ccv_categorized_t), 64, 0);
	while (fscanf(r0, "%d %s", &c, file) != EOF)
	{
		char* filename = (char*)ccmalloc(1024);
		if (base_dir != 0)
		{
			strncpy(filename, base_dir, 1024);
			filename[dirlen - 1] = '/';
		}
		strncpy(filename + dirlen, file, 1024 - dirlen);
		ccv_file_info_t file_info = {
			.filename = filename,
		};
		// imageNet's category class starts from 1, thus, minus 1 to get 0-index
		ccv_categorized_t categorized = ccv_categorized(c - 1, 0, &file_info);
		ccv_array_push(categorizeds, &categorized);
	}
	fclose(r0);
	ccv_array_t* tests = ccv_array_new(sizeof(ccv_categorized_t), 64, 0);
	while (fscanf(r1, "%d %s", &c, file) != EOF)
	{
		char* filename = (char*)ccmalloc(1024);
		if (base_dir != 0)
		{
			strncpy(filename, base_dir, 1024);
			filename[dirlen - 1] = '/';
		}
		strncpy(filename + dirlen, file, 1024 - dirlen);
		ccv_file_info_t file_info = {
			.filename = filename,
		};
		// imageNet's category class starts from 1, thus, minus 1 to get 0-index
		ccv_categorized_t categorized = ccv_categorized(c - 1, 0, &file_info);
		ccv_array_push(tests, &categorized);
	}
	fclose(r1);
	free(file);
// #define model_params vgg_d_params
#define model_params matt_c_params
	int depth = sizeof(model_params) / sizeof(ccv_convnet_layer_param_t);
	ccv_convnet_t* convnet = ccv_convnet_new(1, ccv_size(257, 257), model_params, depth);
	if (ccv_convnet_verify(convnet, 1000) == 0)
	{
		ccv_convnet_layer_train_param_t layer_params[depth];
		memset(layer_params, 0, sizeof(layer_params));
		for (i = 0; i < depth; i++)
		{
			layer_params[i].w.decay = 0.0005;
			layer_params[i].w.learn_rate = 0.01;
			layer_params[i].w.momentum = 0.9;
			layer_params[i].bias.decay = 0;
			layer_params[i].bias.learn_rate = 0.01;
			layer_params[i].bias.momentum = 0.9;
		}
		// set the two full connect layers to last with dropout rate at 0.5
		for (i = depth - 3; i < depth - 1; i++)
			layer_params[i].dor = 0.5;
		train_params.layer_params = layer_params;
		ccv_set_cli_output_levels(ccv_cli_output_level_and_above(CCV_CLI_INFO));
		ccv_convnet_supervised_train(convnet, categorizeds, tests, working_dir, train_params);
	} else {
		PRINT(CCV_CLI_ERROR, "Invalid convnet configuration\n");
	}
	ccv_convnet_free(convnet);
	ccv_disable_cache();
	return 0;
}
Esempio n. 24
0
/* it is a supposely cleaner and faster implementation than original OpenCV (ccv_canny_deprecated,
 * removed, since the newer implementation achieve bit accuracy with OpenCV's), after a lot
 * profiling, the current implementation still uses integer to speed up */
void ccv_canny(ccv_dense_matrix_t* a, ccv_dense_matrix_t** b, int type, int size, double low_thresh, double high_thresh)
{
	assert(a->type & CCV_C1);
	ccv_declare_matrix_signature(sig, a->sig != 0, ccv_sign_with_format(64, "ccv_canny(%d,%lf,%lf)", size, low_thresh, high_thresh), a->sig, 0);
	type = (type == 0) ? CCV_8U | 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_matrix_return_if_cached(, db);
	if ((a->type & CCV_8U) || (a->type & CCV_32S))
	{
		ccv_dense_matrix_t* dx = 0;
		ccv_dense_matrix_t* dy = 0;
		ccv_sobel(a, &dx, 0, size, 0);
		ccv_sobel(a, &dy, 0, 0, size);
		/* special case, all integer */
		int low = (int)(low_thresh + 0.5);
		int high = (int)(high_thresh + 0.5);
		int* dxi = dx->data.i32;
		int* dyi = dy->data.i32;
		int i, j;
		int* mbuf = (int*)alloca(3 * (a->cols + 2) * sizeof(int));
		memset(mbuf, 0, 3 * (a->cols + 2) * sizeof(int));
		int* rows[3];
		rows[0] = mbuf + 1;
		rows[1] = mbuf + (a->cols + 2) + 1;
		rows[2] = mbuf + 2 * (a->cols + 2) + 1;
		for (j = 0; j < a->cols; j++)
			rows[1][j] = abs(dxi[j]) + abs(dyi[j]);
		dxi += a->cols;
		dyi += a->cols;
		int* map = (int*)ccmalloc(sizeof(int) * (a->rows + 2) * (a->cols + 2));
		memset(map, 0, sizeof(int) * (a->cols + 2));
		int* map_ptr = map + a->cols + 2 + 1;
		int map_cols = a->cols + 2;
		int** stack = (int**)ccmalloc(sizeof(int*) * a->rows * a->cols);
		int** stack_top = stack;
		int** stack_bottom = stack;
		for (i = 1; i <= a->rows; i++)
		{
			/* the if clause should be unswitched automatically, no need to manually do so */
			if (i == a->rows)
				memset(rows[2], 0, sizeof(int) * a->cols);
			else
				for (j = 0; j < a->cols; j++)
					rows[2][j] = abs(dxi[j]) + abs(dyi[j]);
			int* _dx = dxi - a->cols;
			int* _dy = dyi - a->cols;
			map_ptr[-1] = 0;
			int suppress = 0;
			for (j = 0; j < a->cols; j++)
			{
				int f = rows[1][j];
				if (f > low)
				{
					int x = abs(_dx[j]);
					int y = abs(_dy[j]);
					int s = _dx[j] ^ _dy[j];
					/* x * tan(22.5) */
					int tg22x = x * (int)(0.4142135623730950488016887242097 * (1 << 15) + 0.5);
					/* x * tan(67.5) == 2 * x + x * tan(22.5) */
					int tg67x = tg22x + ((x + x) << 15);
					y <<= 15;
					/* it is a little different from the Canny original paper because we adopted the coordinate system of
					 * top-left corner as origin. Thus, the derivative of y convolved with matrix:
					 * |-1 -2 -1|
					 * | 0  0  0|
					 * | 1  2  1|
					 * actually is the reverse of real y. Thus, the computed angle will be mirrored around x-axis.
					 * In this case, when angle is -45 (135), we compare with north-east and south-west, and for 45,
					 * we compare with north-west and south-east (in traditional coordinate system sense, the same if we
					 * adopt top-left corner as origin for "north", "south", "east", "west" accordingly) */
#define high_block \
					{ \
						if (f > high && !suppress && map_ptr[j - map_cols] != 2) \
						{ \
							map_ptr[j] = 2; \
							suppress = 1; \
							*(stack_top++) = map_ptr + j; \
						} else { \
							map_ptr[j] = 1; \
						} \
						continue; \
					}
					/* sometimes, we end up with same f in integer domain, for that case, we will take the first occurrence
					 * suppressing the second with flag */
					if (y < tg22x)
					{
						if (f > rows[1][j - 1] && f >= rows[1][j + 1])
							high_block;
					} else if (y > tg67x) {
						if (f > rows[0][j] && f >= rows[2][j])
							high_block;
					} else {
						s = s < 0 ? -1 : 1;
						if (f > rows[0][j - s] && f > rows[2][j + s])
							high_block;
					}
#undef high_block
				}
				map_ptr[j] = 0;
				suppress = 0;
			}
			map_ptr[a->cols] = 0;
			map_ptr += map_cols;
			dxi += a->cols;
			dyi += a->cols;
			int* row = rows[0];
			rows[0] = rows[1];
			rows[1] = rows[2];
			rows[2] = row;
		}
		memset(map_ptr - map_cols - 1, 0, sizeof(int) * (a->cols + 2));
		int dr[] = {-1, 1, -map_cols - 1, -map_cols, -map_cols + 1, map_cols - 1, map_cols, map_cols + 1};
		while (stack_top > stack_bottom)
		{
			map_ptr = *(--stack_top);
			for (i = 0; i < 8; i++)
				if (map_ptr[dr[i]] == 1)
				{
					map_ptr[dr[i]] = 2;
					*(stack_top++) = map_ptr + dr[i];
				}
		}
		map_ptr = map + map_cols + 1;
		unsigned char* b_ptr = db->data.u8;
#define for_block(_, _for_set) \
		for (i = 0; i < a->rows; i++) \
		{ \
			for (j = 0; j < a->cols; j++) \
				_for_set(b_ptr, j, (map_ptr[j] == 2), 0); \
			map_ptr += map_cols; \
			b_ptr += db->step; \
		}
		ccv_matrix_setter(db->type, for_block);
#undef for_block
		ccfree(stack);
		ccfree(map);
		ccv_matrix_free(dx);
		ccv_matrix_free(dy);
	} else {
		/* general case, use all ccv facilities to deal with it */
		ccv_dense_matrix_t* mg = 0;
		ccv_dense_matrix_t* ag = 0;
		ccv_gradient(a, &ag, 0, &mg, 0, size, size);
		ccv_matrix_free(ag);
		ccv_matrix_free(mg);
		/* FIXME: Canny implementation for general case */
	}
}