Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

adding runme()

  • Loading branch information...
commit 83c7d0aa6c599977c641f81647b9a5b055e20c91 1 parent 1ff2477
Jennifer Guo authored
View
197 code/extract_digits/extractdigits.m~
@@ -0,0 +1,197 @@
+function [ output_struct ] = extractdigits_new( sudoku_image, filename )
+%Takes a clean sudoku image and extract the digit portion
+% input sudoku_image should be a binary image!
+% filename is the original image's filename without extension.
+% The output is a struct with the digit image vector and the
+% location vector
+
+ binary_image = sudoku_image;
+
+ %Determine the window size
+ [height, width] = size(binary_image);
+
+ window_height = floor(height/9);
+ window_width = floor(width/9);
+
+ digit_images = {};
+ digit_location = [];
+
+ fig = figure('Visible', 'Off');
+ imshow(sudoku_image);
+ hold on;
+
+ location = 1; % value from 1~81 to mark which square in sudoku box
+ index = 1; % value from 1 ~ #of squares with digits.
+ for grid_h=1:window_height:(height-window_height+1)
+ for grid_w=1:window_width:(width-window_width+1)
+
+ window = imcrop(binary_image, ...
+ [grid_w, grid_h, window_width, window_height]);
+
+ % determine rectangle
+ rect = get_rectangle(window);
+ cropped_img = imcrop(window, rect);
+
+ % Testing: draw rectangles in original image
+ r1 = [grid_w + rect(1,1)-1, grid_h + rect(1,2)-1, ...
+ rect(1,3), rect(1,4)];
+ %rectangle('position', r1, 'edgecolor', 'r', 'linewidth', 2);
+
+ % determine shrinked rectangle
+ shrinked_rect = shrink_rectangle(cropped_img);
+ cropped_img = imcrop(cropped_img, shrinked_rect); % crop image down again
+
+ if (contains_digit(cropped_img))
+ digit_location = [digit_location, location];
+ digit_images{1,index} = cropped_img;
+ index = index + 1;
+
+ % Testing: draw shrinked rectangle in original image
+ r2 = [r1(1,1) + shrinked_rect(1,1) - 1, r1(1,2) + shrinked_rect(1,2) - 1, ...
+ shrinked_rect(1,3), shrinked_rect(1,4)];
+ rectangle('position', r2, 'edgecolor', 'g', 'linewidth', 2);
+ end
+
+ location = location + 1;
+ end
+ end
+
+ set(gca,'position',[0 0 1 1],'units','normalized');
+ output_filename = strcat('../../output/extracted_digits/digits_', filename, '.jpg');
+ print(fig, '-djpeg', '-r300', output_filename);
+
+
+ %Construct the struct for return
+ output_struct.digit_vector = digit_images;
+ output_struct.location_vector = digit_location
+
+end
+
+function [output_rectangle] = get_rectangle(window)
+% determines the inner rectangle of the current window. Used to remove the
+% borders of the grid in a first step. (afterwards we run
+% shrink_inner_rectangle to improve the result)
+% window: pass in the image of the window that we're iterating over
+% output_rectangle: outputs a rectangle [x y w h] as output that can be
+% used for imcrop then. Positions are relative to input "window"
+ stat = regionprops(window,'boundingbox');
+ maxarea = 0;
+ maxsquare = [1 1 size(window, 2) size(window, 1)];
+ for cnt = 1 : numel(stat)
+ bb = stat(cnt).BoundingBox;
+ area = bb(3) * bb(4);
+
+ if (area > maxarea && area < (size(window,1) * size(window,2)))
+ maxarea = area;
+ maxsquare = bb;
+ end
+ end
+
+ maxsquare = floor(maxsquare);
+ if (maxsquare(1,1) == 0)
+ maxsquare(1,1) = 1;
+ end
+ if (maxsquare(1,2) == 0)
+ maxsquare(1,2) = 1;
+ end
+ output_rectangle = maxsquare;
+end
+
+function [output_rectangle] = shrink_rectangle(img)
+% the inner rectangle as determined by regionprops might still contain some
+% black pixels at the border. Use this function to shrink it to remove
+% those black pixels.
+% We look at the middle 1/3 strip of each side and shrink it until that
+% strip has only white pixels
+% img: the inner_rectangle as input
+% output_rectangle: return a rectangle [x y w h] as output, that can be
+% used for imcrop then. Positions are relative to input "img"
+
+ [h, w] = size(img);
+ v_length = floor(h/3); % vertical length
+ h_length = floor(w/3); % horizontal length
+
+ corners = zeros(2, 4); % saves the result coordinates of the 4 corners
+
+ % moving top edge down
+ y_pos = 1;
+ while (1)
+ hline = img(y_pos, h_length:2*h_length-1); % horizontal line
+ if (sum(hline) == h_length) % all white
+ break;
+ end
+ y_pos = y_pos + 1;
+ end
+ corners(2, 1:2) = y_pos;
+
+ % moving bottom edge up;
+ y_pos = h;
+ while (1)
+ hline = img(y_pos, h_length:2*h_length-1);
+ if (sum(hline) == h_length) % all white
+ break;
+ end
+ y_pos = y_pos - 1;
+ end
+ corners(2, 3:4) = y_pos;
+
+ % moving left edge right
+ x_pos = 1;
+ while (1)
+ vline = img(v_length:2*v_length-1, x_pos);
+ if (sum(vline) == v_length) % all white
+ break;
+ end
+ x_pos = x_pos + 1;
+ end
+ corners(1, 1) = x_pos;
+ corners(1, 3) = x_pos;
+
+ % moving right edge left
+ x_pos = w;
+ while (1)
+ vline = img(v_length:2*v_length-1, x_pos);
+ if (sum(vline) == v_length) % all white
+ break;
+ end
+ x_pos = x_pos - 1;
+ end
+ corners(1, 2) = x_pos;
+ corners(1, 4) = x_pos;
+
+ output_rectangle = [corners(1,1), corners(2,1), corners(1,2)-corners(1,1), corners(2,3)-corners(2,1)];
+
+end
+
+
+function [ret] = contains_digit (square)
+% determines if the square which we cropped out contains a digit
+% square: pass in the cropped down image. Has to be a bw image.
+% ret: return value either true (1) or false (0)
+
+ if (islogical(square) == 0)
+ error('input image is not a bw image!');
+ end
+ THRESHOLD_RATIO = 0.1;
+ [h, w] = size(square);
+
+ square = ~square; % let black pixels have value 1 for summing up
+
+ % create a mask by dividing square into 9 regions and have the center
+ % region valued at 3 and the remaining at 1.
+ % this way we're weighing the center of the square more
+ % 1 1 1
+ % 1 3 1
+ % 1 1 1
+ mask = ones(h, w);
+ mask(floor(h/3)+1:floor(h/3*2), floor(w/3)+1:floor(w/3*2)) = 3;
+
+ allblack = sum(sum(mask));
+ black_pixels = sum(sum(square .* mask));
+
+ if (black_pixels / allblack > THRESHOLD_RATIO)
+ ret = true;
+ else
+ ret = false;
+ end
+end
View
58 code/extract_digits/runme.m
@@ -0,0 +1,58 @@
+function [] = runme (force_overwrite)
+ % By default we do not overwrite results
+ if (nargin < 1)
+ force_overwrite = false;
+ end
+
+ close all
+
+ % Get list of all filenames image directory
+ filenames = dir('../../output/extracted_squares');
+
+ % Keep record of the evaluation results for each input image
+ %scores = [];
+
+ % Process all filenames in input directory
+ for i = 1:size(filenames)
+ filename = filenames(i).name;
+
+ % Check if filename is an image
+ if (~isempty(strfind(filename, '.jpg')) || ~isempty(strfind(filename, '.png')))
+ disp(['[+] Processing ' filename]);
+ if (~isempty(strfind(filename, '.jpg')))
+ % Determine filenames
+ basename = strrep(filename, '.jpg', '');
+ input_filename = strcat('../../output/extracted_squares/', basename, '.jpg');
+ output_filename = strcat('../../output/extracted_digits/square_', basename, '.jpg');
+ elseif(~isempty(strfind(filename, '.png')))
+ basename = strrep(filename, '.png', '');
+ input_filename = strcat('../../output/extracted_squares/', basename, '.png');
+ output_filename = strcat('../../output/extracted_digits/square_', basename, '.png');
+ end
+
+
+ % Create output image, if it does not already exist
+ if (force_overwrite || ~exist(output_filename, 'file'))
+
+ % Read the input image
+ input_image = imread(input_filename); % should be a gray image
+
+ % Begin timer
+ tic
+
+ % adaptive thresholding to convert to bw image
+ img = im2bw(input_image);
+ output_struct = extractdigits(img, basename);
+
+ % writing to output folder happens inside extractdigits()
+
+ % End timer
+ toc
+
+
+ end
+
+
+ end
+ end
+end
View
66 code/extract_digits/runme.m~
@@ -0,0 +1,66 @@
+function [] = runme (force_overwrite)
+ % By default we do not overwrite results
+ if (nargin < 1)
+ force_overwrite = false;
+ end
+
+ close all
+
+ % Get list of all filenames image directory
+ filenames = dir('../../output/extracted_squares');
+
+ % Keep record of the evaluation results for each input image
+ %scores = [];
+
+ % Process all filenames in input directory
+ for i = 1:size(filenames)
+ filename = filenames(i).name;
+
+ % Check if filename is an image
+ if (~isempty(strfind(filename, '.jpg')) || ~isempty(strfind(filename, '.png')))
+
+ if (~isempty(strfind(filename, '.jpg')))
+ % Determine filenames
+ basename = strrep(filename, '.jpg', '');
+ input_filename = strcat('../../output/extracted_squares/', basename, '.jpg');
+ output_filename = strcat('../../output/extracted_digits/square_', basename, '.jpg');
+ elseif(~isempty(strfind(filename, '.png')))
+ basename = strrep(filename, '.png', '');
+ input_filename = strcat('../../output/extracted_squares/', basename, '.png');
+ output_filename = strcat('../../output/extracted_digits/square_', basename, '.png');
+ end
+
+
+ % Create output image, if it does not already exist
+ if (force_overwrite || ~exist(output_filename, 'file'))
+ disp(['Creating ' output_filename]);
+
+ % Read the input image
+ input_image = imread(input_filename); % should be a gray image
+
+ % Begin timer
+ tic
+
+ % adaptive thresholding to convert to bw image
+ img = im2bw(input_image);
+
+ sudoku_square = findsquare(bw);
+ rectified_square = rectify(sudoku_square);
+ output_image = rectified_square;
+
+ % End timer
+ toc
+
+ % Write the computed images
+ imwrite(output_image, output_filename);
+ else
+
+ % Read the previously computed output image
+% output_image = im2double(imread(output_filename));
+
+ end
+
+
+ end
+ end
+end
View
BIN  code/extract_digits/test.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
3  output/extracted_digits/README.txt
@@ -0,0 +1,3 @@
+Contains output from step 2: extract digits.
+Can be used for debugging and final project write up.
+Not uploaded on github, content should be generated yourself.
Please sign in to comment.
Something went wrong with that request. Please try again.