vowel.m
上传用户:zslfgd
上传日期:2010-04-06
资源大小:115k
文件大小:6k
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %% %%
- %% Prof. Sclaroff's CS585 Image avd Video Processing %%
- %% Project ONE %%
- %% C H A R A C T E R R E C O G N I T I O N %%
- %% %%
- %% by Stanislav Rost %%
- %% ID: 31764117 %%
- %% %%
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- function result = vowel(filename)
- % VOWEL.M
- %
- % function result = vowel(filename)
- %
- % Arguments: name of the file containing scanned letters
- %
- % Vowel.m performs vowel recognition using moments, part ratios and
- % compactness.
- %
- % As a result, the function shows an image with letters O marked
- % blue, E magenta, A red, U green. All other letters are white/gray.
- %
- % Assumptions:
- % - if the paragraph is tilted, then it is rectangular
- % - no more than two letters are joined at any instance of joined letters
- imageData = im2bw(imread(filename,'tif'),0.5);
- imageData = ~imageData;
- % Find out average height of letters
- avgLabel = bwlabel(imageData, 4);
- avgLetters = imfeature(avgLabel, 'BoundingBox');
- numAvg = max(avgLabel(:));
- avgHeight = 0;
- for i = 1:numAvg,
- avgHeight = avgHeight + avgLetters(i).BoundingBox(4);
- end
- avgHeight = round(avgHeight / numAvg);
- clear avgLetters
- % #################### ROTATOR ############################
- % Rotate the image so that letters are properly oriented
- % This is how it's done: we use the find out imfeature's Orientation
- % for the entire paragraph (so the assumption here is that the paragraph
- % is wider than it is tall), and then rotate by that value...
- % only if the image is tilted, which can be checked by breaking the image in 2,
- % and then seeing if the top boundaries on their bounding boxes are about the
- % same height
- origFeature = imfeature(double(imageData), 'BoundingBox', 'Orientation');
- angle = - origFeature.Orientation;
- midpoint = floor(origFeature.BoundingBox(3)/2);
- leftHalf = imageData(:,1:midpoint);
- rightHalf = imageData(:,(midpoint+1):end);
- leftFeature = imfeature(double(leftHalf), 'BoundingBox');
- rightFeature = imfeature(double(rightHalf), 'BoundingBox');
- % If the distance between upper boundaries of bounding boxes
- % is bigger than half the average letter size, rotate image.
- if (abs(leftFeature.BoundingBox(2) - rightFeature.BoundingBox(2)) > avgHeight/2 )
- disp('Rotation accepted');
- imageData = imrotate(imageData, angle, 'nearest');
- end
- % ################### LABEL 1 ##############################
- imageData = bwlabel(imageData, 4);
- % #################### SPLITTER ############################
- % Split the letters that need to be split
- % First, calculate the averge width of letters
- splitLetters = imfeature(imageData, 'BoundingBox', 'Image');
- numSplit = max(imageData(:));
- avgWidth = 0;
- for i = 1:numSplit,
- avgWidth = avgWidth + splitLetters(i).BoundingBox(3);
- end
- avgWidth = round(avgWidth / numSplit);
- % Now, go through all the letters and if their width
- % is bigger than 1.5 average then split them.
- for i = 1:numSplit,
- if splitLetters(i).BoundingBox(3) > 1.5 * avgWidth
- [ rows columns ] = size(splitLetters(i).Image);
- % Draw vertical line
- splitLetters(i).Image(:, avgWidth ) = 0;
- splitLetters(i).Image(:, splitLetters(i).BoundingBox(3) - avgWidth) = 0;
- if (columns>avgWidth*2.5)
- splitLetters(i).Image(:, columns - avgWidth +2 ) = 0;
- end
- for k = 1:2,
- splitLetters(i).Image =erode(splitLetters(i).Image, ...
- [ 0,1,0;0,1,0 ]);
- splitLetters(i).Image = bwmorph(splitLetters(i).Image, 'spur');
- end
- % insert the split image back into the original image
- xoffset = round(splitLetters(i).BoundingBox(1));
- yoffset = round(splitLetters(i).BoundingBox(2));
- % Put the image back into training data
- for c = 1:splitLetters(i).BoundingBox(3),
- for d = 1:splitLetters(i).BoundingBox(4),
- imageData(yoffset+d-1, xoffset+c-1) = ...
- splitLetters(i).Image(d,c);
- end
- end
- end
- end
- imageData = im2bw(imageData, 0.5);
- imageData = bwlabel(imageData, 4);
- % #################### RECOGNITION LOOP ################
- % Relabel everything because it might be rotated
- imageLetters = imfeature(imageData,'Image', 'Area', 'EulerNumber', 'BoundingBox');
- imageNumLetters = max(imageData(:));
- % Load recognizable letter data from file(s)
- letterName(1) = 'o';
- letterName(2) = 'e';
- letterName(3) = 'a';
- letterName(4) = 'u';
- load 'o.mat' meanO covO
- letterObj(1) = struct('Name', 'o', ...
- 'Mean', meanO, ...
- 'Covariance', covO);
- load 'e.mat' meanE covE
- letterObj(2) = struct('Name', 'e', ...
- 'Mean', meanE, ...
- 'Covariance', covE);
- load 'a.mat' meanA covA
- letterObj(3) = struct('Name', 'a', ...
- 'Mean', meanA, ...
- 'Covariance', covA);
- load 'u.mat' meanU covU
- letterObj(4) = struct('Name', 'u', ...
- 'Mean', meanU, ...
- 'Covariance', covU);
- % Save a copy of a colormap
- cmap = colormap;
- % A spinning tick mark indicates that processing is underway
- tickArray = [ '-' '/' '|' '' '-' '/' '|' '' ];
- % Main recognition loop
- % newColors will hold the number of colors that was added as a result of splitting
- newColors = 0;
- % Main recognition loop - go through each letter (or joined sequence of letters)
- for k = 1:imageNumLetters,
- % Output the tick mark
- temp = mod(k,8);
- if temp == 0
- temp = 8;
- end
- disp(tickArray(temp));
- % It's a single letter
- % Compare each letter to be recognized to each letter
- matchLetter = letter_compare(letterObj, imageLetters(k));
- % Highlight the letter
- switch matchLetter
- case 1, palentry = [ 0.0 0.0 1.0 ];
- case 2, palentry = [ 1.0 0.0 1.0 ];
- case 3, palentry = [ 1.0 0.0 0.0 ];
- case 4, palentry = [ 0.0 1.0 0.0 ];
- otherwise, palentry = [ 0 0 0 ];
- end
- cmap(k,:) = palentry;
- end
- % End main recognition loop
- % Shift the data values up to make room for black background
- imageData = imageData +1;
- % Add the black color into the palette
- tempMap = [ 1,1,1; cmap ];
- % Show results
- figure;
- image(imageData);
- colormap(tempMap);