int gpio_set_direction(int pin, int direction)
{
	int ret = 0;
	int fd;
	char *str;
	char path[256];
	snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/direction", pin);

	if ((fd = open(path, O_WRONLY)) < 0)
	{
		CATERR("Failed to open %s\n", path);
		return -1;
	}

	str = direction ? "in" : "out";
	
	if (write(fd, str, strlen(str)) < 0)
	{
		CATERR("Failed to write \"%s\" to %s\n", str, path);
		//ret = -2;
	}

	close(fd);

	return ret;
}
int catcierge_rfid_open(catcierge_rfid_t *rfid)
{
	struct termios options;
	assert(rfid);

	if ((rfid->fd = open(rfid->serial_path, O_RDWR | O_NOCTTY | O_NDELAY)) < 0)
	{
		CATERR("%s RFID Reader: Failed to open RFID serial port %s\n", rfid->name, rfid->serial_path);
		return -1;
	}

	CATLOG("%s RFID Reader: Opened serial port %s on fd %d\n", 
			rfid->name, rfid->serial_path, rfid->fd);

	if (fcntl(rfid->fd, F_SETFL, 0) < 0)
	{
		close(rfid->fd);
		CATERR("%s RFID Reader: fcntl error %d while trying to open file descriptor, %s",
				rfid->name, errno, strerror(errno));
		return -1;
	}

	memset(&options, 0, sizeof(options));

	// Set baud rate.
	cfsetispeed(&options, B9600);
	cfsetospeed(&options, B9600);

	options.c_iflag = 0;
    options.c_oflag = 0; // Raw output.
    options.c_cflag = CS8 | CREAD | CLOCAL;
    options.c_lflag = 0;

	options.c_cc[VTIME]	= 0;
	options.c_cc[VMIN]	= 1;

	// Flush the line and set the options.
	tcflush(rfid->fd, TCIFLUSH);
	tcsetattr(rfid->fd, TCSANOW, &options);

	// Set the reader in RAT mode.
	if (catcierge_rfid_write_rat(rfid))
	{
		CATERR("%s RFID Reader: Failed to write RAT command\n", rfid->name);
		catcierge_rfid_destroy(rfid);
		return -1;
	}

	rfid->state = CAT_CONNECTED;

	return 0;
}
int gpio_export(int pin)
{
	if (write_num_to_file("/sys/class/gpio/export", pin))
	{
		CATERR("Failed to open GPIO export for writing\n");
		return -1;
	}

	return 0;
}
示例#4
0
void setup_sig_handlers()
{
	if (signal(SIGINT, sig_handler) == SIG_ERR)
	{
		CATERR("Failed to set SIGINT handler\n");
	}

	#ifndef _WIN32
	if (signal(SIGUSR1, sig_handler) == SIG_ERR)
	{
		CATERR("Failed to set SIGUSR1 handler (used to force unlock)\n");
	}

	if (signal(SIGUSR2, sig_handler) == SIG_ERR)
	{
		CATERR("Failed to set SIGUSR2 handler (used to force lockout)\n");
	}
	#endif // _WIN32
}
int gpio_write(int pin, int val)
{
	char path[256];

	snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", pin);

	if (write_num_to_file(path, val))
	{
		CATERR("Failed to open GPIO export for writing\n");
		return -1;
	}

	return 0;
}
char *catcierge_read_file(const char *filename)
{
	char *buffer = NULL;
	int string_size;
	int read_size;
	FILE *f;

	if (!(f = fopen(filename,"r")))
	{
		CATERR("Failed to open file %s\n", filename);
		return NULL;
	}

	fseek(f, 0, SEEK_END);
	string_size = ftell(f);
	rewind(f);

	if (!(buffer = (char *)malloc(sizeof(char) * (string_size + 1))))
	{
		goto fail;
	}

	read_size = fread(buffer, sizeof(char), string_size, f);
	buffer[string_size] = '\0';

	if (string_size != read_size)
	{
		CATERR("Failed to read file %s\n", filename);
		free(buffer);
		buffer = NULL;
	}

fail:
	if (f) fclose(f);

	return buffer;
}
static int write_num_to_file(const char *path, int num)
{
	int ret = 0;
	char buf[16];
	int fd;
	ssize_t written;

	if ((fd = open(path, O_WRONLY)) < 0)
	{
		CATERR("Failed to open \"%s\"\n", path);
		return -1;
	}

	written = snprintf(buf, sizeof(buf), "%d", num);
	
	if (write(fd, buf, strlen(buf)) < 0)
	{
		CATERR("Failed to write \"%s\" to %s\n", buf, path);
	}

	close(fd);

	return ret;
}
int catcierge_rfid_write_rat(catcierge_rfid_t *rfid)
{
	const char buf[] = "RAT\r\n";
	ssize_t bytes = write(rfid->fd, buf, sizeof(buf));

	CATLOG("%s RFID Reader: Sent RAT request\n", rfid->name);

	if (bytes < 0)
	{
		CATERR("%s RFID Reader: Failed to write %d, %s\n", rfid->name, errno, strerror(errno));
		return -1;
	}

	return 0;
}
示例#9
0
int catcierge_parse_setting(catcierge_args_t *args, const char *key, char **values, size_t value_count)
{
	size_t i;
	int ret;
	assert(args);
	assert(key);

	if (!strcmp(key, "matcher"))
	{
		if (value_count == 1)
		{
			args->matcher = values[0];
			if (strcmp(args->matcher, "template")
				&& strcmp(args->matcher, "haar"))
			{
				fprintf(stderr, "Invalid template type \"%s\"\n", args->matcher);
				return -1;
			}

			args->matcher_type = !strcmp(args->matcher, "template")
				? MATCHER_TEMPLATE : MATCHER_HAAR;

			return 0;
		}
		else
		{
			fprintf(stderr, "Missing value for --matcher\n");
			return -1;
		}

		return 0;
	}

	ret = catcierge_haar_matcher_parse_args(&args->haar, key, values, value_count);
	if (ret < 0) return -1;
	else if (!ret) return 0;

	ret = catcierge_template_matcher_parse_args(&args->templ, key, values, value_count);
	if (ret < 0) return -1;
	else if (!ret) return 0;

	if (!strcmp(key, "show"))
	{
		args->show = 1;
		if (value_count == 1) args->show = atoi(values[0]);
		return 0;
	}

	if (!strcmp(key, "ok_matches_needed"))
	{
		if (value_count == 1)
		{
			args->ok_matches_needed = atoi(values[0]);

			if ((args->ok_matches_needed < 0)
				|| (args->ok_matches_needed > MATCH_MAX_COUNT))
			{
				fprintf(stderr, "--ok_matches_needed must be between 0 and %d\n", MATCH_MAX_COUNT);
				return -1;
			}

			return 0;
		}

		fprintf(stderr, "--ok_matches_needed missing an integer value\n");
		return -1;
	}

	if (!strcmp(key, "lockout_method"))
	{
		if (value_count == 1)
		{
			args->lockout_method = atoi(values[0]);

			if ((args->lockout_method < OBSTRUCT_OR_TIMER_1)
			 || (args->lockout_method > TIMER_ONLY_3))
			{
				fprintf(stderr, "--lockout_method needs a value between %d and %d\n",
					OBSTRUCT_OR_TIMER_1, TIMER_ONLY_3);
				return -1;
			}

			return 0;
		}

		fprintf(stderr, "--lockout_method missing an integer value\n");
		return -1;
	}

	if (!strcmp(key, "save"))
	{
		args->saveimg = 1;
		if (value_count == 1) args->saveimg = atoi(values[0]);
		return 0;
	}

	if (!strcmp(key, "save_obstruct"))
	{
		args->save_obstruct_img = 1;
		if (value_count == 1) args->save_obstruct_img = atoi(values[0]);
		return 0;
	}

	if (!strcmp(key, "new_execute"))
	{
		args->new_execute = 1;
		if (value_count == 1) args->new_execute = atoi(values[0]);
		return 0;
	}

	if (!strcmp(key, "highlight"))
	{
		args->highlight_match = 1;
		if (value_count == 1) args->highlight_match = atoi(values[0]);
		return 0;
	}

	if (!strcmp(key, "lockout"))
	{
		args->lockout_time = DEFAULT_LOCKOUT_TIME;
		if (value_count == 1) args->lockout_time = atoi(values[0]);

		return 0;
	}

	if (!strcmp(key, "lockout_error_delay"))
	{
		if (value_count == 1)
		{
			args->consecutive_lockout_delay = atof(values[0]);
			return 0;
		}

		fprintf(stderr, "--lockout_error_delay missing a seconds value\n");
		return -1;
	}

	if (!strcmp(key, "lockout_error"))
	{
		if (value_count == 1)
		{
			args->max_consecutive_lockout_count = atoi(values[0]);
			return 0;
		}

		fprintf(stderr, "--lockout_error missing a value\n");
		return -1;
	}

	if (!strcmp(key, "lockout_dummy"))
	{
		args->lockout_dummy = 1;
		if (value_count == 1) args->lockout_dummy = atoi(values[0]);
		return 0;
	}

	if (!strcmp(key, "matchtime"))
	{
		args->match_time = DEFAULT_MATCH_WAIT;
		if (value_count == 1) args->match_time = atoi(values[0]);
		return 0;
	}

	if (!strcmp(key, "no_final_decision"))
	{
		args->no_final_decision = 1;
		if (value_count == 1) args->no_final_decision = atoi(values[0]);
		return 0;
	}

	#ifdef WITH_ZMQ
	if (!strcmp(key, "zmq"))
	{
		args->zmq = 1;
		if (value_count == 1) args->zmq = atoi(values[0]);
		return 0;
	}

	if (!strcmp(key, "zmq_port"))
	{
		args->zmq_port = DEFAULT_ZMQ_PORT;

		if (value_count < 1)
		{
			fprintf(stderr, "--zmq_port missing value\n");
			return -1;
		}

		args->zmq_port = atoi(values[0]);

		return 0;
	}

	if (!strcmp(key, "zmq_iface"))
	{
		if (value_count < 1)
		{
			fprintf(stderr, "--zmq_iface missing interface name\n");
			return -1;
		}

		args->zmq_iface = values[0];

		return 0;
	}

	if (!strcmp(key, "zmq_transport"))
	{
		if (value_count != 1)
		{
			fprintf(stderr, "--zmq_transport missing value\n");
			return -1;
		}

		args->zmq_transport = values[0];

		return 0;
	}
	#endif // WITH_ZMQ

	if (!strcmp(key, "output") || !strcmp(key, "output_path"))
	{
		if (value_count == 1)
		{
			args->output_path = values[0];
			return 0;
		}

		fprintf(stderr, "--output_path missing path value\n");
		return -1;
	}

	if (!strcmp(key, "match_output_path"))
	{
		if (value_count == 1)
		{
			args->match_output_path = values[0];
			return 0;
		}

		fprintf(stderr, "--match_output_path missing path value\n");
		return -1;
	}

	if (!strcmp(key, "steps_output_path"))
	{
		if (value_count == 1)
		{
			args->steps_output_path = values[0];
			return 0;
		}

		fprintf(stderr, "--steps_output_path missing path value\n");
		return -1;
	}

	if (!strcmp(key, "obstruct_output_path"))
	{
		if (value_count == 1)
		{
			args->obstruct_output_path = values[0];
			return 0;
		}

		fprintf(stderr, "--obstruct_output_path missing path value\n");
		return -1;
	}

	if (!strcmp(key, "template_output_path"))
	{
		if (value_count == 1)
		{
			args->template_output_path = values[0];
			return 0;
		}

		fprintf(stderr, "--template_output_path missing path value\n");
		return -1;
	}

	if (!strcmp(key, "input") || !strcmp(key, "template"))
	{
		if (value_count == 0)
		{
			fprintf(stderr, "--template missing value\n");
			return -1;
		}

		for (i = 0; i < value_count; i++)
		{
			if (args->input_count >= MAX_INPUT_TEMPLATES)
			{
				fprintf(stderr, "Max template input reached %d\n", MAX_INPUT_TEMPLATES);
				return -1;
			}
			args->inputs[args->input_count] = values[i];
			args->input_count++;
		}

		return 0;
	}

	#ifdef WITH_RFID
	if (!strcmp(key, "rfid_in"))
	{
		if (value_count == 1)
		{
			args->rfid_inner_path = values[0];
			return 0;
		}

		fprintf(stderr, "--rfid_in missing path value\n");
		return -1;
	}

	if (!strcmp(key, "rfid_out"))
	{
		if (value_count == 1)
		{
			args->rfid_outer_path = values[0];
			return 0;
		}

		fprintf(stderr, "--rfid_out missing path value\n");
		return -1;
	}

	if (!strcmp(key, "rfid_allowed"))
	{
		if (value_count == 1)
		{
			if (catcierge_create_rfid_allowed_list(args, values[0]))
			{
				CATERR("Failed to create RFID allowed list\n");
				return -1;
			}

			return 0;
		}

		fprintf(stderr, "--rfid_allowed missing comma separated list of values\n");
		return -1;
	}

	if (!strcmp(key, "rfid_time"))
	{
		if (value_count == 1)
		{
			args->rfid_lock_time = (double)atof(values[0]);
			return 0;
		}

		fprintf(stderr, "--rfid_time missing seconds value (float)\n");
		return -1;
	}

	if (!strcmp(key, "rfid_lock"))
	{
		args->lock_on_invalid_rfid = 1;
		if (value_count == 1) args->lock_on_invalid_rfid = atoi(values[0]);
		return 0;
	}
	#endif // WITH_RFID

	if (!strcmp(key, "log"))
	{
		if (value_count == 1)
		{
			args->log_path = values[0];
			return 0;
		}

		fprintf(stderr, "--log missing path value\n");
		return -1;
	}

	if (!strcmp(key, "match_cmd"))
	{
		if (value_count == 1)
		{
			args->match_cmd = values[0];
			return 0;
		}

		fprintf(stderr, "--match_cmd missing value\n");
		return -1;
	}

	if (!strcmp(key, "save_img_cmd"))
	{
		if (value_count == 1)
		{
			args->save_img_cmd = values[0];
			return 0;
		}

		fprintf(stderr, "--save_img_cmd missing value\n");
		return -1;
	}

	if (!strcmp(key, "frame_obstructed_cmd"))
	{
		if (value_count == 1)
		{
			args->frame_obstructed_cmd = values[0];
			return 0;
		}

		fprintf(stderr, "--frame_obstructed_cmd missing value\n");
		return -1;
	}

	if (!strcmp(key, "save_imgs_cmd") || !strcmp(key, "match_group_done_cmd"))
	{
		if (value_count == 1)
		{
			args->match_group_done_cmd = values[0];
			return 0;
		}

		fprintf(stderr, "--match_group_done_cmd missing value\n");
		return -1;
	}

	if (!strcmp(key, "match_done_cmd"))
	{
		if (value_count == 1)
		{
			args->match_done_cmd = values[0];
			return 0;
		}

		fprintf(stderr, "--match_done_cmd missing value\n");
		return -1;
	}

	if (!strcmp(key, "do_lockout_cmd"))
	{
		if (value_count == 1)
		{
			args->do_lockout_cmd = values[0];
			return 0;
		}

		fprintf(stderr, "--do_lockout_cmd missing value\n");
		return -1;
	}

	if (!strcmp(key, "do_unlock_cmd"))
	{
		if (value_count == 1)
		{
			args->do_unlock_cmd = values[0];
			return 0;
		}

		fprintf(stderr, "--do_unlock cmd missing value\n");
		return -1;
	}

	if (!strcmp(key, "state_change_cmd"))
	{
		if (value_count == 1)
		{
			args->state_change_cmd = values[0];
			return 0;
		}

		fprintf(stderr, "--state_change_cmd cmd missing value\n");
		return -1;
	}

	if (!strcmp(key, "nocolor"))
	{
		args->nocolor = 1;
		if (value_count == 1) args->nocolor = atoi(values[0]);
		return 0;
	}

	if (!strcmp(key, "noanim"))
	{
		args->noanim = 1;
		if (value_count == 1) args->noanim = atoi(values[0]);
		return 0;
	}

	if (!strcmp(key, "save_steps"))
	{
		args->save_steps = 1;
		if (value_count == 1) args->save_steps = atoi(values[0]);
		return 0;
	}

	if (!strcmp(key, "chuid"))
	{
		if (value_count == 1)
		{
			args->chuid = values[0];
			return 0;
		}

		fprintf(stderr, "--chuid missing value\n");
		return -1;
	}

	#ifdef WITH_RFID
	if (!strcmp(key, "rfid_detect_cmd"))
	{
		if (value_count == 1)
		{
			args->rfid_detect_cmd = values[0];
			return 0;
		}

		fprintf(stderr, "--rfid_detect_cmd missing value\n");
		return -1;
	}

	if (!strcmp(key, "rfid_match_cmd"))
	{
		if (value_count == 1)
		{
			args->rfid_match_cmd = values[0];
			return 0;
		}

		fprintf(stderr, "--rfid_match_cmd missing value\n");
		return -1;
	}
	#endif // WITH_RFID

	#ifndef _WIN32
	// TODO: Support this on windows.
	if (!strcmp(key, "base_time"))
	{
		if (value_count == 1)
		{
			struct tm base_time_tm;
			time_t base_time_t;
			struct timeval base_time_now;
			long base_time_diff;

			memset(&base_time_tm, 0, sizeof(base_time_tm));
			memset(&base_time_now, 0, sizeof(base_time_now));

			args->base_time = values[0];

			if (!strptime(args->base_time, "%Y-%m-%dT%H:%M:%S", &base_time_tm))
			{
				goto fail_base_time;
			}

			if ((base_time_t = mktime(&base_time_tm)) == -1)
			{
				goto fail_base_time;
			}

			gettimeofday(&base_time_now, NULL);
			base_time_diff = base_time_now.tv_sec - base_time_t;

			catcierge_strftime_set_base_diff(base_time_diff);

			return 0;

		fail_base_time:
			fprintf(stderr, "Failed to parse --base_time %s\n", values[0]);
			return -1;
		}

		fprintf(stderr, "--base_time missing value\n");
		return -1;
	}
	#endif // _WIN32

	#ifdef RPI
	if (!strncmp(key, "rpi-", 4))
	{
		int rpiret = 0;
		const char *rpikey = key + strlen("rpi");

		if (!raspicamcontrol_parse_cmdline(&args->rpi_settings.camera_parameters,
			rpikey, (value_count == 1) ? values[0] : NULL))
		{
			return -1;
		}
		return 0;
	}
	#endif // RPI

	return -1;
}
示例#10
0
static int catcierge_rfid_read(catcierge_rfid_t *rfid)
{
	int ret = 0;
	int is_error = 0;
	int errorcode;
	const char *error_msg = NULL;

	if ((rfid->bytes_read = read(rfid->fd, rfid->buf, 
								sizeof(rfid->buf) - 1)) < 0)
	{
		if ((errno != EWOULDBLOCK) && (errno != EAGAIN))
		{
			CATERR("%s RFID Reader: Read error %d, %s\n", rfid->name, errno, strerror(errno));
			ret = -1;
			goto fail;
		}

		CATERR("%s RFID Reader: Need more\n");
		// TODO: Add CAT_NEED_MORE state here and handle that.
		return -1;
	}

	// Get rid of any trailing CRLF.
	if (rfid->buf[rfid->bytes_read - 1] == '\n') rfid->bytes_read--;
	if (rfid->buf[rfid->bytes_read - 1] == '\r') rfid->bytes_read--;

	rfid->buf[rfid->bytes_read] = '\0';
	CATLOG("%s RFID Reader: %ld bytes: %s\n", rfid->name, rfid->bytes_read, rfid->buf);

	if (rfid->bytes_read == 0)
	{
		// TODO: EOF, do something special here?
		return 0;
	}

	// Check for error.
	if (rfid->buf[0] == '?')
	{
		is_error = 1;
		errorcode = atoi(&rfid->buf[1]);
		error_msg = catcierge_rfid_error_str(errorcode);

		CATERR("%s RFID reader: error %d on read, %s\n", 
				rfid->name, errorcode, error_msg);
		// TODO: Hmm should we really just fall through here in all cases?
	}

	if (rfid->state == CAT_CONNECTED)
	{
		CATLOG("%s RFID Reader: Started listening for cats on %s\n", rfid->name, rfid->serial_path);
		rfid->state = CAT_AWAITING_TAG;
	}
	else if (rfid->state == CAT_AWAITING_TAG)
	{
		if (!is_error)
		{
			int complete = (rfid->bytes_read >= 15);
			rfid->cb(rfid, complete, rfid->buf, rfid->bytes_read, rfid->user);
		}
		else
		{
			CATERR("%s RFID Reader: Failed reading tag, %s\n", rfid->name, error_msg);
		}
	}
	else
	{
		CATERR("%s RFID Reader: Invalid state on read, %d\n", rfid->name, rfid->state);
	}

fail:
	rfid->bytes_read = 0;
	rfid->offset = 0;
	return ret;
}
int catcierge_haar_matcher_init(catcierge_matcher_t **octx,
		catcierge_matcher_args_t *oargs)
{
	catcierge_haar_matcher_t *ctx = NULL;
	catcierge_haar_matcher_args_t *args = (catcierge_haar_matcher_args_t *)oargs;
	assert(args);
	assert(octx);

	if (!(*octx = calloc(1, sizeof(catcierge_haar_matcher_t))))
	{
		CATERR("Out of memory!\n");
		return -1;
	}

	ctx = (catcierge_haar_matcher_t *)*octx;

	ctx->super.type = MATCHER_HAAR;
	ctx->super.name = "Haar Cascade";
	ctx->super.short_name = "haar";

	if (!args->cascade)
	{
		CATERR("Haar matcher: No cascade xml specified. Use --cascade\n");
		return -1;
	}

	if (!(ctx->cascade = cv2CascadeClassifier_create()))
	{
		CATERR("Failed to create cascade classifier.\n");
		goto opencv_error;
	}

	if (cv2CascadeClassifier_load(ctx->cascade, args->cascade))
	{
		CATERR("Failed to load cascade xml: %s\n", args->cascade);
		return -1;
	}

	if (!(ctx->storage = cvCreateMemStorage(0)))
	{
		goto opencv_error;
	}

	// TOOD: Make args for kernel sizes. Rename the kernels for what they do instead
	if (!(ctx->kernel2x2 = cvCreateStructuringElementEx(2, 2, 0, 0, CV_SHAPE_RECT, NULL)))
	{
		goto opencv_error;
	}

	if (!(ctx->kernel3x3 = cvCreateStructuringElementEx(3, 3, 0, 0, CV_SHAPE_RECT, NULL)))
	{
		goto opencv_error;
	}

	if (!(ctx->kernel5x1 = cvCreateStructuringElementEx(5, 1, 0, 0, CV_SHAPE_RECT, NULL)))
	{
		goto opencv_error;
	}

	ctx->args = args;
	ctx->super.debug = args->debug;
	ctx->super.match = catcierge_haar_matcher_match;
	ctx->super.decide = catcierge_haar_matcher_decide;
	ctx->super.translate = catcierge_haar_matcher_translate;

	return 0;
opencv_error:
	CATERR("OpenCV error\n");
	return -1;
}
示例#12
0
void catcierge_run(char *command)
{
	#ifndef _WIN32
	{
		char *argv[4] = {0};
		pid_t pid;
		argv[0] = "/bin/sh";
		argv[1] = "-c";
		argv[2] = command;
		argv[3] = NULL;

		// Fork a child process.
		if ((pid = fork()) < 0)
		{
			CATERR("Forking child process failed: %d, %s\n", errno, strerror(errno));
		}
		else if (pid == 0)
		{
			// For the child process.

			// Execute the command.
			if (execvp(*argv, argv) < 0)
			{
				CATERR("Exec \"%s\" failed: %d, %s\n", command, errno, strerror(errno));
				exit(1);
			}
		}
		else
		{
			CATLOG("Called program \"%s\"\n", command);
		}
	}
	#else // _WIN32
	{
		char tmp[4096];
		STARTUPINFO si;
		PROCESS_INFORMATION pi;
		memset(&si, 0, sizeof(si));
		si.dwXSize = sizeof(si);
		memset(&pi, 0, sizeof(pi));

		snprintf(tmp, sizeof(tmp) - 1, "c:\\Windows\\system32\\cmd.exe /c %s", command);

		if (!CreateProcess(
				NULL, 
				tmp,			// Commandline
				NULL,           // Process handle not inheritable
				NULL,           // Thread handle not inheritable
				FALSE,          // Set handle inheritance to FALSE
				0,              // No creation flags
				NULL,           // Use parent's environment block
				NULL,           // Use parent's starting directory 
				&si,            // Pointer to STARTUPINFO structure
				&pi ))          // Pointer to PROCESS_INFORMATION structure
		{
			CATERR("Error %d, Failed to run command %s\n", GetLastError(), command);
		}
		else
		{
			CATLOG("Called program \"%s\"\n", command);
		}
	}
	#endif // _WIN32
}
int catcierge_template_matcher_init(catcierge_matcher_t **octx,
		catcierge_matcher_args_t *oargs)
{
	int i;
	CvSize snout_size;
	CvSize matchres_size;
	IplImage *snout_prep = NULL;
	const char **snout_paths = NULL;
	int snout_count;
	catcierge_template_matcher_t *ctx = NULL;
	catcierge_template_matcher_args_t *args = (catcierge_template_matcher_args_t *)oargs;
	assert(args);
	assert(octx);

	if (!(*octx = calloc(1, sizeof(catcierge_template_matcher_t))))
	{
		CATERR("Out of memory!\n");
		return -1;
	}

	ctx = (catcierge_template_matcher_t *)*octx;

	if (args->snout_count == 0)
		return -1;

	ctx->super.type = MATCHER_TEMPLATE;
	ctx->args = args;

	snout_paths = args->snout_paths;
	snout_count = args->snout_count;
	ctx->match_flipped = args->match_flipped;
	ctx->match_threshold = args->match_threshold;

	ctx->low_binary_thresh = CATCIERGE_LOW_BINARY_THRESH_DEFAULT;
	ctx->high_binary_thresh = CATCIERGE_HIGH_BINARY_THRESH_DEFAULT;

	// TODO: Make these setable instead.
	ctx->width = CATCIERGE_DEFAULT_RESOLUTION_WIDTH;
	ctx->height = CATCIERGE_DEFUALT_RESOLUTION_HEIGHT;

	for (i = 0; i < snout_count; i++)
	{
		if (access(snout_paths[i], F_OK) == -1)
		{
			fprintf(stderr, "No such file %s\n", snout_paths[i]);
			return -1;
		}
	}

	if (!(ctx->storage = cvCreateMemStorage(0)))
	{
		return -1;
	}

	if (!(ctx->kernel = cvCreateStructuringElementEx(3, 3, 0, 0, CV_SHAPE_RECT, NULL)))
	{
		return -1;
	}

	ctx->snout_count = snout_count;

	// Load the snout images.
	ctx->snouts = (IplImage **)calloc(snout_count, sizeof(IplImage *));
	ctx->flipped_snouts = (IplImage **)calloc(snout_count, sizeof(IplImage *));
	ctx->matchres = (IplImage **)calloc(snout_count, sizeof(IplImage *));

	if (!ctx->snouts || !ctx->flipped_snouts || !ctx->matchres)
	{
		fprintf(stderr, "Template matcher: Out of memory!\n");
		return -1;
	}

	for (i = 0; i < snout_count; i++)
	{
		if (!(snout_prep = cvLoadImage(snout_paths[i], 1)))
		{
			fprintf(stderr, "Failed to load snout image: %s\n", snout_paths[i]);
			return -1;
		}

		snout_size = cvGetSize(snout_prep);

		if (!(ctx->snouts[i] = cvCreateImage(snout_size, 8, 1)))
		{
			cvReleaseImage(&snout_prep);
			return -1;
		}

		if (_catcierge_prepare_img(ctx, snout_prep, ctx->snouts[i]))
		{
			fprintf(stderr, "Failed to prepare snout image: %s\n", snout_paths[i]);
			return -1;
		}

		// Flip so we can match for going out as well (and not fail the match).
		ctx->flipped_snouts[i] = cvCloneImage(ctx->snouts[i]);
		cvFlip(ctx->snouts[i], ctx->flipped_snouts[i], 1);

		// Setup a matchres image for each snout
		// (We can share these for normal and flipped snouts).
		matchres_size = cvSize(ctx->width  - snout_size.width + 1, 
							   ctx->height - snout_size.height + 1);
		ctx->matchres[i] = cvCreateImage(matchres_size, IPL_DEPTH_32F, 1);

		cvReleaseImage(&snout_prep);
	}

	ctx->super.match = catcierge_template_matcher_match;
	ctx->super.decide = caticerge_template_matcher_decide;
	ctx->super.translate = catcierge_template_matcher_translate;

	return 0;
}
示例#14
0
int main(int argc, char **argv)
{
	catcierge_args_t *args = &grb.args;

	fprintf(stderr, "\nCatcierge Grabber v" CATCIERGE_VERSION_STR " (" CATCIERGE_GIT_HASH_SHORT "");

	// Was this built with changes in the git sources?
	#ifdef CATCIERGE_GIT_TAINTED
	fprintf(stderr, "-tainted");
	#endif

	fprintf(stderr, ")\n(C) Joakim Soderberg 2013-2016\n\n");

	fprintf(stderr, "Library versions:\n");
	fprintf(stderr, " OpenCV v%d.%d.%d\n", CV_MAJOR_VERSION, CV_MINOR_VERSION, CV_SUBMINOR_VERSION);
	#ifdef WITH_ZMQ
	fprintf(stderr, "   CZMQ v%d.%d.%d\n", CZMQ_VERSION_MAJOR, CZMQ_VERSION_MINOR, CZMQ_VERSION_PATCH);
	#endif
	fprintf(stderr, "\n");

	// TODO: Enable specifying pid path on command line.
	#ifndef _WIN32
	pid_fd = create_pid_file(argv[0], PID_PATH, FD_CLOEXEC);
	#endif

	if (catcierge_grabber_init(&grb))
	{
		fprintf(stderr, "Failed to init\n");
		return -1;
	}

	if (catcierge_args_init(args, argv[0]))
	{
		fprintf(stderr, "Failed to init args\n");
		return -1;
	}

	if (catcierge_args_parse(args, argc, argv))
	{
		return -1;
	}

	if (args->nocolor)
	{
		catcierge_nocolor = 1;
	}

	catcierge_print_settings(args);

	setup_sig_handlers();

	if (args->log_path)
	{
		if (!(grb.log_file = fopen(args->log_path, "a+")))
		{
			CATERR("Failed to open log file \"%s\"\n", args->log_path);
		}
	}

	#ifdef RPI
	if (catcierge_setup_gpio(&grb))
	{
		CATERR("Failed to setup GPIO pins\n");
		return -1;
	}

	CATLOG("Initialized GPIO pins\n");
	#endif // RPI

	assert((args->matcher_type == MATCHER_TEMPLATE)
		|| (args->matcher_type == MATCHER_HAAR));

	if (catcierge_matcher_init(&grb.matcher, catcierge_get_matcher_args(args)))
	{
		CATERR("Failed to init %s matcher\n", grb.matcher->name);
		return -1;
	}

	CATLOG("Initialized catcierge image recognition\n");

	if (catcierge_output_init(&grb, &grb.output))
	{
		CATERR("Failed to init output template system\n");
		return -1;
	}

	if (catcierge_output_load_templates(&grb.output,
			args->inputs, args->input_count))
	{
		CATERR("Failed to load output templates\n");
		return -1;
	}

	CATLOG("Initialized output templates\n");

	#ifdef WITH_RFID
	catcierge_init_rfid_readers(&grb);
	#endif

	catcierge_setup_camera(&grb);

	#ifdef WITH_ZMQ
	catcierge_zmq_init(&grb);
	#endif

	CATLOG("Starting detection!\n");
	// TODO: Create a catcierge_grb_start(grb) function that does this instead.
	catcierge_fsm_start(&grb);

	// Run the program state machine.
	do
	{
		if (!catcierge_timer_isactive(&grb.frame_timer))
		{
			catcierge_timer_start(&grb.frame_timer);
		}

		// Always feed the RFID readers.
		#ifdef WITH_RFID
		if ((args->rfid_inner_path || args->rfid_outer_path) 
			&& catcierge_rfid_ctx_service(&grb.rfid_ctx))
		{
			CATERRFPS("Failed to service RFID readers\n");
		}
		#endif // WITH_RFID

		grb.img = catcierge_get_frame(&grb);

		catcierge_run_state(&grb);
		catcierge_print_spinner(&grb);
	} while (
		grb.running
		#ifdef WITH_ZMQ
		&& !zctx_interrupted
		#endif
		);

	catcierge_matcher_destroy(&grb.matcher);
	catcierge_output_destroy(&grb.output);
	catcierge_destroy_camera(&grb);
	#ifdef WITH_ZMQ
	catcierge_zmq_destroy(&grb);
	#endif
	catcierge_grabber_destroy(&grb);
	catcierge_args_destroy(&grb.args);

	if (grb.log_file)
	{
		fclose(grb.log_file);
	}

	#ifndef _WIN32
	if (pid_fd > 0)
	{
		close(pid_fd);
		unlink(PID_PATH);
	}
	#endif

	return 0;
}