int main(int argc, char **argv)
{
	int ret = 0;
	catcierge_matcher_t *matcher = NULL;
	IplImage *img = NULL;
	CvSize img_size;
	CvScalar match_color;
	int match_success = 0;
	double match_res = 0;
	int i;
	int j;
	int success_count = 0;
	match_result_t result;

	clock_t start;
	clock_t end;
	catcierge_args_t args;
	memset(&args, 0, sizeof(args));
	memset(&result, 0, sizeof(result));

	fprintf(stderr, "Catcierge Image match Tester (C) Joakim Soderberg 2013-2016\n");

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

	if (add_options(&args))
	{
		fprintf(stderr, "Failed to init tester args\n");
		ret = -1; goto fail;
	}

	if (catcierge_args_parse(&args, argc, argv))
	{
		ret = -1; goto fail;
	}

	// Create output directory.
	if (ctx.save)
	{
		catcierge_make_path("%s", ctx.output_path);
	}

	if (catcierge_matcher_init(&matcher, catcierge_get_matcher_args(&args)))
	{
		fprintf(stderr, "\n\nFailed to %s init matcher\n\n", matcher->name);
		return -1;
	}

	matcher->debug = ctx.debug;

	if (!(ctx.imgs = calloc(ctx.img_count, sizeof(IplImage *))))
	{
		fprintf(stderr, "Out of memory!\n");
		ret = -1;
		goto fail;
	}

	// TODO: Move to function
	// If we should preload the images or not
	// (Don't let file IO screw with benchmark)
	if (ctx.preload)
	{
		for (i = 0; i < (int)ctx.img_count; i++)
		{
			printf("Preload image %s\n", ctx.img_paths[i]);

			if (!(ctx.imgs[i] = cvLoadImage(ctx.img_paths[i], 1)))
			{
				fprintf(stderr, "Failed to load match image: %s\n", ctx.img_paths[i]);
				ret = -1;
				goto fail;
			}
		}
	}

	start = clock();

	if (ctx.test_matchable)
	{
		for (i = 0; i < (int)ctx.img_count; i++)
		{
			// This tests if an image frame is clear or not (matchable).
			int frame_obstructed;

			if ((frame_obstructed = matcher->is_obstructed(matcher, ctx.imgs[i])) < 0)
			{
				fprintf(stderr, "Failed to detect check for matchability frame\n");
				return -1;
			}

			printf("%s: Frame obstructed = %d\n",
				ctx.img_paths[i], frame_obstructed);

			if (ctx.show)
			{
				cvShowImage("image", ctx.imgs[i]);
				cvWaitKey(0);
			}
		}
	}
	else
	{
		for (i = 0; i < (int)ctx.img_count; i++)
		{
			match_success = 0;

			printf("---------------------------------------------------\n");
			printf("%s:\n", ctx.img_paths[i]);

			if (ctx.preload)
			{
				img = ctx.imgs[i];
			}
			else
			{
				if (!(img = cvLoadImage(ctx.img_paths[i], 1)))
				{
					fprintf(stderr, "Failed to load match image: %s\n", ctx.img_paths[i]);
					goto fail;
				}
			}

			img_size = cvGetSize(img);

			printf("  Image size: %dx%d\n", img_size.width, img_size.height);


			if ((match_res = matcher->match(matcher, img, &result, 0)) < 0)
			{
				fprintf(stderr, "Something went wrong when matching image: %s\n", ctx.img_paths[i]);
				catcierge_matcher_destroy(&matcher);
				return -1;
			}

			match_success = (match_res >= args.templ.match_threshold);

			if (match_success)
			{
				printf("  Match (%s)! %f\n", catcierge_get_direction_str(result.direction), match_res);
				match_color = CV_RGB(0, 255, 0);
				success_count++;
			}
			else
			{
				printf("  No match! %f\n", match_res);
				match_color = CV_RGB(255, 0, 0);
			}

			if (ctx.show || ctx.save)
			{
				for (j = 0; j < (int)result.rect_count; j++)
				{
					printf("x: %d\n", result.match_rects[j].x);
					printf("y: %d\n", result.match_rects[j].y);
					printf("w: %d\n", result.match_rects[j].width);
					printf("h: %d\n", result.match_rects[j].height);
					cvRectangleR(img, result.match_rects[j], match_color, 1, 8, 0);
				}

				if (ctx.show)
				{
					cvShowImage("image", img);
					cvWaitKey(0);
				}

				if (ctx.save)
				{
					char out_file[PATH_MAX]; 
					char tmp[PATH_MAX];
					char *filename = tmp;
					char *ext;
					char *start;

					// Get the extension.
					strncpy(tmp, ctx.img_paths[i], sizeof(tmp));
					ext = strrchr(tmp, '.');
					*ext = '\0';
					ext++;

					// And filename.
					filename = strrchr(tmp, '/');
					start = strrchr(tmp, '\\');
					if (start> filename)
						filename = start;
					filename++;

					snprintf(out_file, sizeof(out_file) - 1, "%s/match_%s__%s.%s", 
							ctx.output_path, match_success ? "ok" : "fail", filename, ext);

					printf("Saving image \"%s\"\n", out_file);

					cvSaveImage(out_file, img, 0);
				}
			}

			cvReleaseImage(&img);
		}
	}

	end = clock();

	if (!ctx.test_matchable)
	{
		if (ctx.show)
		{
			printf("Note that the duration is affected by using --show\n");
		}
		printf("%d of %d successful! (%f seconds)\n",
			success_count, (int)ctx.img_count, (float)(end - start) / CLOCKS_PER_SEC);
	}

fail:
	catcierge_matcher_destroy(&matcher);
	cvDestroyAllWindows();

	return ret;
}
Esempio n. 2
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;
}