📄 vowel.m
字号:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% %% 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 lettersimageData = im2bw(imread(filename,'tif'),0.5);imageData = ~imageData;% Find out average height of lettersavgLabel = bwlabel(imageData, 4);avgLetters = imfeature(avgLabel, 'BoundingBox');numAvg = max(avgLabel(:));avgHeight = 0;for i = 1:numAvg, avgHeight = avgHeight + avgLetters(i).BoundingBox(4);endavgHeight = 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 heightorigFeature = 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 letterssplitLetters = imfeature(imageData, 'BoundingBox', 'Image');numSplit = max(imageData(:));avgWidth = 0;for i = 1:numSplit, avgWidth = avgWidth + splitLetters(i).BoundingBox(3);endavgWidth = 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 endendimageData = im2bw(imageData, 0.5);imageData = bwlabel(imageData, 4);% #################### RECOGNITION LOOP ################% Relabel everything because it might be rotatedimageLetters = 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 covOletterObj(1) = struct('Name', 'o', ... 'Mean', meanO, ... 'Covariance', covO);load 'e.mat' meanE covEletterObj(2) = struct('Name', 'e', ... 'Mean', meanE, ... 'Covariance', covE);load 'a.mat' meanA covAletterObj(3) = struct('Name', 'a', ... 'Mean', meanA, ... 'Covariance', covA);load 'u.mat' meanU covUletterObj(4) = struct('Name', 'u', ... 'Mean', meanU, ... 'Covariance', covU);% Save a copy of a colormapcmap = colormap;% A spinning tick mark indicates that processing is underwaytickArray = [ '-' '/' '|' '\' '-' '/' '|' '\' ];% Main recognition loop% newColors will hold the number of colors that was added as a result of splittingnewColors = 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 backgroundimageData = imageData +1;% Add the black color into the palettetempMap = [ 1,1,1; cmap ];% Show resultsfigure;image(imageData);colormap(tempMap);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -