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

图形/文字识别

开发平台:

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 = letter_compare(ocr_letters, document_letter)
  12. % LETTER_COMPARE.M
  13. %
  14. % function result = letter_compare(ocr_letters, document_letter)
  15. %
  16. % Parameters:  ocr_letters is an array (1..4) of structures
  17. % with fields:  Mean, Covariance
  18. %        Subscripts of array mean 1=O 2=E 3=A 4=U
  19. %        document_letter fields is a structure which has
  20. % with fields:  Image, EulerNumber, Area, BoundingBox
  21. %
  22. % This function compares a letter extracted from the image paragraph
  23. % to each of the four vowels.  Returns the index of the vowel
  24. % which the letter from the paragraph matches, if any.
  25. % If no vowels match up, return 0.
  26. %
  27. % Assumptions:  
  28. %  - the letter form the document/paragraph is properly oriented
  29. % Calculate the data necessary for the matching
  30. perImg = bwperim(document_letter.Image);
  31. perArea = bwarea(perImg);
  32. compactness = perArea^2/document_letter.Area;
  33. moments = invmoments(document_letter.Image);
  34. % Calculate the top/bottom area ratio
  35. midpoint = floor(document_letter.BoundingBox(4)/2);
  36. topPart = document_letter.Image(1:midpoint,:);
  37. bottomPart = document_letter.Image((midpoint+1):end,:);
  38. partRatio = bwarea(topPart)/bwarea(bottomPart);
  39. % Final vector for the doucment image which will be used for comparison
  40. vector = [ moments(1) moments(2) moments(3) compactness partRatio ];
  41. % Go through all four letters
  42. for i = 1: 4,
  43. % Closeness will be Mahalanobis distance without the log term
  44. closeness(i) = (vector - ocr_letters(i).Mean)*...
  45. inv(ocr_letters(i).Covariance)*...
  46. (vector - ocr_letters(i).Mean)';
  47. % Distance is Mahalanobis distance with the log term
  48. % The log term equalizes the distance space so that
  49. % we can compare which one of the four letters
  50. % is closer to the letter extracted from the paragraph
  51. distance(i) = closeness(i) + log(det(ocr_letters(i).Covariance));
  52. end
  53. % Find one of the vowels with the smallest distance to the document letter
  54. minimumDistance = distance(1);
  55. closestMatch = 1;
  56. for j = 1:4,
  57. if distance(j)<minimumDistance
  58. minimumDistance = distance(j);
  59. closestMatch = j;
  60. end
  61. end
  62. % Now we have to determine if the closest match is noise or not
  63. variance = [ ocr_letters(closestMatch).Covariance(1,1) ...
  64.      ocr_letters(closestMatch).Covariance(2,2) ...
  65.      ocr_letters(closestMatch).Covariance(3,3) ...
  66.      ocr_letters(closestMatch).Covariance(4,4) ...
  67.      ocr_letters(closestMatch).Covariance(5,5) ];
  68. % Standard deviation
  69. std = sqrt(variance);
  70. matchCloseness = closeness(closestMatch);
  71. % Use Mahalanobis distance to figure out the allowed range for
  72. % the closeness within which the letter is accepted as a match
  73. allowedRange =  6.5*(std) * inv(ocr_letters(closestMatch).Covariance) * (std)';
  74. % Closeness is within allowed interval
  75. if (matchCloseness <= allowedRange)
  76. % ######################  SECONDARY CHECKS  ################
  77. if closestMatch == 1
  78. % It thinks it is an O
  79. if (document_letter.EulerNumber ~= 0)
  80. % Reject
  81. closestMatch = 0;
  82. end
  83. elseif closestMatch == 2
  84. % It thinks it is an E
  85. if (document_letter.EulerNumber ~= 0)
  86. % Reject
  87. closestMatch = 0;
  88. end
  89. elseif closestMatch == 3
  90. % It thinks it is an A
  91. % Euler# can be 0 or 1
  92. if (document_letter.EulerNumber ~= 0) & ...
  93. (document_letter.EulerNumber ~= -1)
  94. % Reject
  95. closestMatch = 0;
  96. end
  97. % Ahh, but it might be an S !
  98. % S's have about equal distribution
  99. % of weight about their midpoint
  100. if (partRatio > 0.87 )
  101. % S rejected because the weight of the top
  102. % half is about equal to the wight of the
  103. % bottom half
  104. closestMatch = 0;
  105. end
  106. elseif closestMatch == 4
  107. % It thinks it is a U
  108. % Euler# can be 0 or 1
  109. if (document_letter.EulerNumber ~=1 )
  110. % Reject
  111. closestMatch = 0;
  112. end
  113. % Also, calculate the Eulers for the top and
  114. % bottom slices
  115. midpoint = floor(document_letter.BoundingBox(4)/2);
  116. topPart = im2bw(document_letter.Image(1:midpoint,:), 0.5);
  117. bottomPart = im2bw(document_letter.Image(midpoint+1,:), 0.5);
  118. topFeature = imfeature(double(topPart), 'EulerNumber');
  119. bottomFeature = imfeature(double(bottomPart), 'EulerNumber');
  120. topEuler = topFeature(1).EulerNumber;
  121. bottomEuler = bottomFeature(1).EulerNumber;
  122. % For u's, the top Euler number is 2, and the bottom
  123. % part has Euler number of 2
  124. if (topEuler~=2) | (bottomEuler ~= 2)
  125. % Can't be an U according to Euler checks
  126. closestMatch = 0;
  127. end
  128. end
  129. result = closestMatch;
  130. else
  131. result = 0;
  132. end