vowel.m
上传用户:zslfgd
上传日期:2010-04-06
资源大小:115k
文件大小:6k
源码类别:

图形/文字识别

开发平台:

Matlab

  1.      %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2.    %%                                                            %%
  3.  %%       Prof. Sclaroff's CS585 Image avd Video Processing       %%
  4. %%                         Project  ONE                            %%
  5. %%           C H A R A C T E R   R E C O G N I T I O N             %%
  6. %%                                                                 %%
  7. %%                    by Stanislav Rost                    %%
  8.  %%                       ID:  31764117                           %%
  9.   %%                                                             %%
  10.    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  11. function result = vowel(filename)
  12. % VOWEL.M
  13. %
  14. % function result = vowel(filename)
  15. %
  16. % Arguments:  name of the file containing scanned letters
  17. %
  18. % Vowel.m performs vowel recognition using moments, part ratios and
  19. % compactness.
  20. %
  21. % As a result, the function shows an image with letters O marked
  22. % blue, E magenta, A red, U green.  All other letters are white/gray.
  23. %
  24. % Assumptions:  
  25. %  - if the paragraph is tilted, then it is rectangular 
  26. %  - no more than two letters are joined at any instance of joined letters
  27. imageData = im2bw(imread(filename,'tif'),0.5);
  28. imageData = ~imageData;
  29. % Find out average height of letters
  30. avgLabel = bwlabel(imageData, 4);
  31. avgLetters = imfeature(avgLabel, 'BoundingBox');
  32. numAvg = max(avgLabel(:));
  33. avgHeight = 0;
  34. for i = 1:numAvg,
  35. avgHeight = avgHeight + avgLetters(i).BoundingBox(4);
  36. end
  37. avgHeight = round(avgHeight / numAvg);
  38. clear avgLetters
  39. % #################### ROTATOR  ############################
  40. % Rotate the image so that letters are properly oriented
  41. % This is how it's done:  we use the find out imfeature's Orientation
  42. % for the entire paragraph (so the assumption here is that the paragraph
  43. % is wider than it is tall), and then rotate by that value...
  44. % only if the image is tilted, which can be checked by breaking the image in 2,
  45. % and then seeing if the top boundaries on their bounding boxes are about the
  46. % same height
  47. origFeature = imfeature(double(imageData), 'BoundingBox', 'Orientation');
  48. angle = - origFeature.Orientation;
  49. midpoint = floor(origFeature.BoundingBox(3)/2);
  50. leftHalf = imageData(:,1:midpoint);
  51. rightHalf = imageData(:,(midpoint+1):end);
  52. leftFeature = imfeature(double(leftHalf), 'BoundingBox');
  53. rightFeature = imfeature(double(rightHalf), 'BoundingBox');
  54. % If the distance between upper boundaries of bounding boxes
  55. % is bigger than half the average letter size, rotate image.
  56. if (abs(leftFeature.BoundingBox(2) - rightFeature.BoundingBox(2)) > avgHeight/2 )
  57. disp('Rotation accepted');
  58. imageData = imrotate(imageData, angle, 'nearest');
  59. end
  60. % ################### LABEL 1 ##############################
  61. imageData = bwlabel(imageData, 4);
  62. % #################### SPLITTER ############################
  63. % Split the letters that need to be split
  64. % First, calculate the averge width of letters
  65. splitLetters = imfeature(imageData, 'BoundingBox', 'Image');
  66. numSplit = max(imageData(:));
  67. avgWidth = 0;
  68. for i = 1:numSplit,
  69. avgWidth = avgWidth + splitLetters(i).BoundingBox(3);
  70. end
  71. avgWidth = round(avgWidth / numSplit);
  72. % Now, go through all the letters and if their width
  73. % is bigger than 1.5 average then split them.
  74. for i = 1:numSplit,
  75. if splitLetters(i).BoundingBox(3) > 1.5 * avgWidth
  76. [ rows columns ] = size(splitLetters(i).Image);
  77. % Draw vertical line
  78. splitLetters(i).Image(:, avgWidth ) = 0;
  79. splitLetters(i).Image(:, splitLetters(i).BoundingBox(3) - avgWidth) = 0;
  80. if (columns>avgWidth*2.5)
  81. splitLetters(i).Image(:, columns - avgWidth +2 ) = 0;
  82. end
  83. for k = 1:2,
  84. splitLetters(i).Image =erode(splitLetters(i).Image, ...
  85. [ 0,1,0;0,1,0 ]);
  86. splitLetters(i).Image = bwmorph(splitLetters(i).Image, 'spur');
  87. end
  88. % insert the split image back into the original image
  89. xoffset = round(splitLetters(i).BoundingBox(1));
  90. yoffset = round(splitLetters(i).BoundingBox(2));
  91. % Put the image back into training data
  92. for c = 1:splitLetters(i).BoundingBox(3),
  93. for d = 1:splitLetters(i).BoundingBox(4),
  94. imageData(yoffset+d-1, xoffset+c-1) = ...
  95. splitLetters(i).Image(d,c);
  96. end
  97. end
  98. end
  99. end
  100. imageData = im2bw(imageData, 0.5);
  101. imageData = bwlabel(imageData, 4);
  102. % #################### RECOGNITION LOOP ################
  103. % Relabel everything because it might be rotated
  104. imageLetters = imfeature(imageData,'Image', 'Area', 'EulerNumber', 'BoundingBox');
  105. imageNumLetters = max(imageData(:));
  106. % Load recognizable letter data from file(s)
  107. letterName(1) = 'o';
  108. letterName(2) = 'e';
  109. letterName(3) = 'a';
  110. letterName(4) = 'u';
  111. load 'o.mat' meanO covO
  112. letterObj(1) = struct('Name', 'o', ...
  113. 'Mean', meanO, ...
  114. 'Covariance', covO);
  115. load 'e.mat' meanE covE
  116. letterObj(2) = struct('Name', 'e', ...
  117. 'Mean', meanE, ...
  118. 'Covariance', covE);
  119. load 'a.mat' meanA covA
  120. letterObj(3) = struct('Name', 'a', ...
  121. 'Mean', meanA, ...
  122. 'Covariance', covA);
  123. load 'u.mat' meanU covU
  124. letterObj(4) = struct('Name', 'u', ...
  125. 'Mean', meanU, ...
  126. 'Covariance', covU);
  127. % Save a copy of a colormap
  128. cmap = colormap;
  129. % A spinning tick mark indicates that processing is underway
  130. tickArray = [ '-' '/' '|' '' '-' '/' '|' '' ];
  131. % Main recognition loop
  132. % newColors will hold the number of colors that was added as a result of splitting
  133. newColors = 0;
  134. % Main recognition loop - go through each letter (or joined sequence of letters)
  135. for k = 1:imageNumLetters,
  136. % Output the tick mark
  137. temp = mod(k,8);
  138. if temp == 0
  139. temp = 8;
  140. end
  141. disp(tickArray(temp));
  142. % It's a single letter   
  143. % Compare each letter to be recognized to each letter
  144. matchLetter = letter_compare(letterObj, imageLetters(k));
  145. % Highlight the letter
  146. switch matchLetter
  147. case 1, palentry = [ 0.0 0.0 1.0 ];
  148. case 2, palentry = [ 1.0 0.0 1.0 ];
  149. case 3, palentry = [ 1.0 0.0 0.0 ];
  150. case 4, palentry = [ 0.0 1.0 0.0 ];
  151. otherwise, palentry = [ 0 0 0 ];
  152. end
  153.         cmap(k,:) = palentry;
  154. end
  155. % End main recognition loop
  156. % Shift the data values up to make room for black background
  157. imageData = imageData +1;
  158. % Add the black color into the palette
  159. tempMap = [ 1,1,1; cmap ];
  160. % Show results
  161. figure;
  162. image(imageData);
  163. colormap(tempMap);