function [score_total,execution_time_total,num_correct_bits,num_false_alarms,num_repeats,execution_time] = evaluate % % evaluate.m for EE368 project, Spring 2006 % % This script calls your own detection routine and compares the results with the ground truth % data to evaluate the performance of your routine. You can use this program to evaluate how % well your routine works with the provided training images. You are also encouraged to generate % your own training images with the provided generate_code.m to make your detection routine more % robust. % % The detection routine should be named as detect_code.m and put in the same directory as % evaluate.m. Before the project due date, you need to submit your own detect_code.m and all the % auxiliary files. The teaching staff will test your detection routine using this evaluate.m with % a different set of images on the Linux machines in the SCIEN Lab. It is also required that your % routine returns results within 1 minute for each image when running on the SCIEN Linux machines. % Therefore, please make sure your routine works properly on those machines before submission. % % The detection routine should be defined as: % function [data_detected,origin_detected] = detect_code(img) % % The input and output are defined as follows % img: % height-by-width-by-3 uint8 array representing a 24-bit RGB image obtained through % imread() % data_detected: % N-by-83 double array of 0's and 1's where N is the number of code markers detected. Each % row of data_detected corresponds to the 83-bit data embedded in the code. % origin_detected: % N-by-2 double array where N is the number of code markers detected. Each row of origin_detected % corresponds to the [row,column] image-coordinate of the origin of a detected code marker. The % origin of a code is defined as the center of the element at the top-left corner of the code, % i.e., code(1,1) defined in generate_code.m. % % For each code in an image, if there is only one detected code marker with the detected origin within a % radius of 10 pixels (Euclidian distance in the image) to the ground-truth origin, this detected % code marker is considered a "hit". If there are multiple detected code markers within the radius, only the % detected code marker with the detected origin closest to the ground-truth origin is considered a "hit". % Every other detected code marker within the radius is considered a "repeat". A detected code marker with a % detected origin that does not fall within a 10-pixel radius to any of the ground-truth origins % is considered a "false-alarm". % % For each "hit", data_detected is compared with the associated ground truth value and the number % of correctly detected bits (out of 83 bits) is calculated and accumulated over possibly multiple % hits (when there are multiple codes in the image). % % The score of your detection routine for a single image is calculated as % score = number of correctly detected bits % - floor(83/2) * (number of false alarms + number of repeats) % Negative scores are clipped to zero. The score will also be set to zero if the detection routine % takes more than 1 minute for this image. The total score, score_total, is caculated by summing up % the scores over the images in the data set. % % The performance will be ranked among project groups according to the following criteria: % (1) score_total, the higher the better % (2) If there is a tie in (1), consider execution_time_total, the smaller the better GROUND_TRUTH_NAME = './../test_images/testing_ground_truth'; % ground truth data IMAGE_NAME = './../test_images/testing'; %GROUND_TRUTH_NAME = './../test_images/training_ground_truth'; % ground truth data %IMAGE_NAME = './../test_images/training'; NUM_IMAGES = 13; % number of images in the data set NUM_BITS_IN_CODE = 83; % number of data bits embedded in a code MAX_DISTANCE = 10; % the radius for a detected code to be considered a hit MAX_TIME = 60; % maximum allowable execution time for an image (in seconds) load(GROUND_TRUTH_NAME); num_correct_bits = zeros(1,NUM_IMAGES); % number of bits in each image that are correctly detected num_false_alarms = zeros(1,NUM_IMAGES); % number of false alarms for each image num_repeats = zeros(1,NUM_IMAGES); % number of repeats for each image score = zeros(1,NUM_IMAGES); % score for each image execution_time = zeros(1,NUM_IMAGES); % execution time of your detection routine for each image for i = 1:NUM_IMAGES % read the image and the ground truth data img = imread(sprintf('%s_%d.jpg',IMAGE_NAME,i)); eval(sprintf('data_true = data_true_%d;',i)); eval(sprintf('origin_true = origin_true_%d;',i)); % execute your detection routine tic; t0 = cputime ; try [data_detected,origin_detected] = detect_code(img); % For example, if your routine works perfectly you should get % data_detected = data_true; % origin_detected = origin_true; execution_time(i) = cputime - t0 ; catch execution_time(i) = -1; end % toc; if (execution_time(i)<0) disp(sprintf('image %d failed',i)); else disp(sprintf('image %d processed',i)); end if (execution_time(i)<0) | (execution_time(i)>MAX_TIME) | isempty(data_detected) | isempty(origin_detected) continue; % score for this image is zero end % make sure the dimensions of data_detected and origin_detected are consistent if (size(data_detected,1)~=size(origin_detected,1)) data_detected = data_detected(1:min([size(data_detected,1),size(origin_detected,1)]),:); origin_detected = origin_detected(1:min([size(data_detected,1),size(origin_detected,1)]),:); end num_codes_true = size(data_true,1); num_codes_detected = size(data_detected,1); % determine a detected code is a false alarm (type 0), a hit (type 1), or a repeat (type 2) code_type = zeros(1,num_codes_detected); for j = 1:num_codes_true distance = sqrt(sum((repmat(origin_true(j,:),[num_codes_detected 1])-origin_detected).^2,2)); [sorted_dist,sorted_idx] = sort(distance); num_detected_in_radius = sum(sorted_dist<=MAX_DISTANCE); if num_detected_in_radius>0 code_type(sorted_idx(1)) = 1; code_type(sorted_idx(2:num_detected_in_radius)) = 2; num_correct_bits(i) = num_correct_bits(i) ... + sum(data_detected(sorted_idx(1),:)==data_true(j,:)); end end num_false_alarms(i) = length(find(code_type==0)); num_repeats(i) = length(find(code_type==2)); score(i) = num_correct_bits(i) - floor(NUM_BITS_IN_CODE/2)*(num_false_alarms(i)+num_repeats(i)); score(i) = max([score(i) 0]); end score_total = sum(score); execution_time_total = sum(execution_time) + sum(execution_time==-1) ;