首页 > 代码库 > matlb

matlb

swt.m:

  1 function [ swtMap ] = swt( im, searchDirection )  2 %swt Preforms stoke width transform on input image  3 %   A novel image operator that seeks to find the value of stroke width  4 %   for each image pixel.  Its use is meant for the task of text  5 %   detection in natural images.  6 %  7 %   im = RGB input image of size m x n x 3  8 %   searchDirection = gradient direction is either 1 to detect dark text on light  9 %   background or -1 to detect light text on dark background. 10 % 11 %   swtMap = resulting mapping of stroke withs for image pixels 12  13 % Convert image to gray scale 14 im = im2double(rgb2gray(im)); 15 %figure, imshow(im), title(Black and White Image); 16  17 % Find edges using canny edge dector 18 edgeMap = edge(im, canny); 19 %figure, imshow(edgeMap), title(Edges Using Canny); 20  21 % Get all edge pixel postitions 22 [edgePointRows, edgePointCols] = find(edgeMap); 23  24 % Find gradient horizontal and vertical gradient 25 sobelMask = fspecial(sobel); 26 dx = imfilter(im,sobelMask); 27 dy = imfilter(im,sobelMask); 28 %figure, imshow(dx, []), title(Horizontal Gradient Image); 29 %figure, imshow(dy, []), title(Vertical Gradient Image); 30  31 % Initializing matrix of gradient direction 32 theta = zeros(size(edgeMap,1),size(edgeMap,2)); 33  34 % Calculating theta, gradient direction, for each pixel on the image. 35 % ***This can be optimized by using edgePointCols and edgePointRows 36 % instead.*** 37 for i=1:size(edgeMap,1) 38     for j=1:size(edgeMap,2) 39         if edgeMap(i,j) == 1 40             theta(i,j) = atan2(dy(i,j),dx(i,j)); 41         end 42     end 43 end 44  45 % Getting size of the image 46 [m,n] = size(edgeMap); 47  48 % Initializing Stoke Width array with infinity 49 swtMap = zeros(m,n); 50 for i=1:m 51     for j=1:n 52         swtMap(i,j) = inf; 53     end 54 end 55  56 % Set the maximum stroke width, this number is variable for now but must be 57 % made to be more dynamic in the future 58 maxStrokeWidth = 350; 59  60 % Initialize container for all stoke points found 61 strokePointsX = zeros(size(edgePointCols)); 62 strokePointsY = zeros(size(strokePointsX)); 63 sizeOfStrokePoints = 0; 64  65 % Iterate through all edge points and compute stoke widths 66 for i=1:size(edgePointRows) 67     step = 1; 68     initialX = edgePointRows(i); 69     initialY = edgePointCols(i); 70     isStroke = 0; 71     initialTheta = theta(initialX,initialY); 72     sizeOfRay = 0; 73     pointOfRayX = zeros(maxStrokeWidth,1); 74     pointOfRayY = zeros(maxStrokeWidth,1); 75      76     % Record first point of the ray 77     pointOfRayX(sizeOfRay+1) = initialX; 78     pointOfRayY(sizeOfRay+1) = initialY; 79      80     % Increase the size of the ray 81     sizeOfRay = sizeOfRay + 1; 82      83     % Follow the ray 84     while step < maxStrokeWidth 85         nextX = round(initialX + cos(initialTheta) * searchDirection * step); 86         nextY = round(initialY + sin(initialTheta) * searchDirection * step); 87          88         step = step + 1; 89          90         % Break loop if out of bounds.  For some reason this is really 91         % slow. 92         if nextX < 1 | nextY < 1 | nextX > m | nextY > n 93             break 94         end 95          96         % Record next point of the ray 97         pointOfRayX(sizeOfRay+1) = nextX; 98         pointOfRayY(sizeOfRay+1) = nextY; 99         100         % Increase size of the ray101         sizeOfRay = sizeOfRay + 1;102         103         % Another edge pixel has been found104         if edgeMap(nextX,nextY)105             106             oppositeTheta = theta(nextX,nextY);107             108             % Gradient direction roughtly opposite109             if abs(abs(initialTheta - oppositeTheta) - pi) < pi/2110                 isStroke = 1;111                 strokePointsX(sizeOfStrokePoints+1) = initialX;112                 strokePointsY(sizeOfStrokePoints+1) = initialY;113                 sizeOfStrokePoints = sizeOfStrokePoints + 1;114             end115             116             break117         end118     end119     120     % Edge pixel is part of stroke121     if isStroke122         123         % Calculate stoke width124         strokeWidth = sqrt((nextX - initialX)^2 + (nextY - initialY)^2);125         126         % Iterate all ray points and populate with the minimum stroke width127         for j=1:sizeOfRay128             swtMap(pointOfRayX(j),pointOfRayY(j)) = min(swtMap(pointOfRayX(j),pointOfRayY(j)),strokeWidth);129         end130     end131 end132 133 %figure, imshow(swtMap, []), title(Stroke Width Transform: First Pass);134 135 % Iterate through all stoke points for a refinement pass.  Refer to figure136 % 4b in the paper.137 138 for i=1:sizeOfStrokePoints139     step = 1;140     initialX = strokePointsX(i);141     initialY = strokePointsY(i);142     initialTheta = theta(initialX,initialY);143     sizeOfRay = 0;144     pointOfRayX = zeros(maxStrokeWidth,1);145     pointOfRayY = zeros(maxStrokeWidth,1);146     swtValues = zeros(maxStrokeWidth,1);147     sizeOfSWTValues = 0;148     149     % Record first point of the ray150     pointOfRayX(sizeOfRay+1) = initialX;151     pointOfRayY(sizeOfRay+1) = initialY;152     153     % Increase the size of the ray154     sizeOfRay = sizeOfRay + 1;155     156     % Record the swt value of first stoke point157     swtValues(sizeOfSWTValues+1) = swtMap(initialX,initialY);158     sizeOfSWTValues = sizeOfSWTValues + 1;159     160     % Follow the ray161     while step < maxStrokeWidth162         nextX = round(initialX + cos(initialTheta) * searchDirection * step);163         nextY = round(initialY + sin(initialTheta) * searchDirection * step);164         165         step = step + 1;166         167         % Record next point of the ray168         pointOfRayX(sizeOfRay+1) = nextX;169         pointOfRayY(sizeOfRay+1) = nextY;170         171         % Increase size of the ray172         sizeOfRay = sizeOfRay + 1;173         174         % Record the swt value of next stoke point175         swtValues(sizeOfSWTValues+1) = swtMap(nextX,nextY);176         sizeOfSWTValues = sizeOfSWTValues + 1;177         178         % Another edge pixel has been found179         if edgeMap(nextX,nextY)180             break181         end182     end183     184     % Calculate stoke width as the median value of all swtValues seen.185     strokeWidth = median(swtValues(1:sizeOfSWTValues));186     187     % Iterate all ray points and populate with the minimum stroke width188     for j=1:sizeOfRay189         swtMap(pointOfRayX(j),pointOfRayY(j)) = min(swtMap(pointOfRayX(j),pointOfRayY(j)),strokeWidth);190     end191     192 end193 194 %figure, imshow(swtMap, []), title(Stroke Width Transform: Second Pass);195 196 end

swtlab.,

  1 function [L,num,sz] = label(I,n)  2 %LABEL Label connected components in 2-D arrays.  3 %   LABEL is a generalization of BWLABEL: BWLABEL works with 2-D binary  4 %   images only, whereas LABEL works with 2-D arrays of any class. Use  5 %   BWLABEL if the input is binary since BWLABEL will be much faster.  6 %  7 %   L = LABEL(I,N) returns a matrix L, of the same size as I, containing  8 %   labels for the connected components in I. Two adjacent components  9 %   (pixels), of respective indexes IDX1 and IDX2, are connected if I(IDX1) 10 %   and I(IDX2) are equal. 11 % 12 %   N can have a value of either 4 or 8, where 4 specifies 4-connected 13 %   objects and 8 specifies 8-connected objects; if the argument is 14 %   omitted, it defaults to 8. 15 % 16 %   Important remark: 17 %   ---------------- 18 %   NaN values are ignored and considered as background. Because LABEL 19 %   works with arrays of any class, the 0s are NOT considered as the 20 %   background.  21 % 22 %   Note: 23 %   ---- 24 %   The elements of L are integer values greater than or equal to 0. The 25 %   pixels labeled 0 are the background (corresponding to the NaN 26 %   components of the input array). The pixels labeled 1 make up one 27 %   object, the pixels labeled 2 make up a second object, and so on. 28 % 29 %   [L,NUM] = LABEL(...) returns in NUM the number of connected objects 30 %   found in I. 31 % 32 %   [L,NUM,SZ] = LABEL(...) returns a matrix SZ, of the same size as I, 33 %   that contains the sizes of the connected objects. For a pixel whose 34 %   index is IDX, we have: SZ(IDX) = NNZ(L==L(IDX)). 35 % 36 %   Class Support 37 %   ------------- 38 %   I can be logical or numeric. L is double. 39 % 40 %   Example 41 %   ------- 42 %       I = [3 3 3 0 0 0 0 0 43 %            3 3 1 0 6.1 6.1 9 0 44 %            1 3 1 3 6.1 6.1 0 0 45 %            1 3 1 3 0 0 1 0 46 %            1 3 3 3 3 3 1 0 47 %            1 3 1 0 0 3 1 0 48 %            1 3 1 0 0 1 1 0 49 %            1 1 1 1 1 0 0 0]; 50 %       L4 = label(I,4); 51 %       L8 = label(I,8); 52 %       subplot(211), imagesc(L4), axis image off 53 %       title(Pixels of same color belong to the same region (4-connection)) 54 %       subplot(212), imagesc(L8), axis image off     55 %       title(Pixels of same color belong to the same region (8-connection)) 56 % 57 %   Note 58 %   ---- 59 %       % Comparison between BWLABEL and LABEL: 60 %       BW = logical([1 1 1 0 0 0 0 0 61 %                     1 1 1 0 1 1 0 0 62 %                     1 1 1 0 1 1 0 0 63 %                     1 1 1 0 0 0 1 0 64 %                     1 1 1 0 0 0 1 0 65 %                     1 1 1 0 0 0 1 0 66 %                     1 1 1 0 0 1 1 0 67 %                     1 1 1 0 0 0 0 0]); 68 %       L = bwlabel(BW,4); 69 %       % The same result can be obtained with LABEL: 70 %       BW2 = double(BW); 71 %       BW2(~BW) = NaN; 72 %       L2 = label(BW2,4); 73 % 74 %   See also BWLABEL, BWLABELN, LABEL2RGB 75 % 76 %   -- Damien Garcia -- 2010/02, revised 2011/01 77 %   http://www.biomecardio.com 78  79 % Check input arguments 80 error(nargchk(1,2,nargin)); 81 if nargin==1, n=8; end 82  83 assert(ndims(I)==2,The input I must be a 2-D array) 84  85 % ----- 86 % The Union-Find algorithm is based on the following document: 87 % http://www.cs.duke.edu/courses/cps100e/fall09/notes/UnionFind.pdf 88 % ----- 89  90 % Initialization of the two arrays (ID & SZ) required during the 91 % Union-Find algorithm. 92 sizI = size(I); 93 id = reshape(1:prod(sizI),sizI); 94 sz = ones(sizI); 95  96 % Indexes of the adjacent pixels 97 vec = @(x) x(:); 98 if n==4 % 4-connected neighborhood 99     idx1 = [vec(id(:,1:end-1)); vec(id(1:end-1,:))];100     idx2 = [vec(id(:,2:end)); vec(id(2:end,:))];101 elseif n==8 % 8-connected neighborhood102     idx1 = [vec(id(:,1:end-1)); vec(id(1:end-1,:))];103     idx2 = [vec(id(:,2:end)); vec(id(2:end,:))];104     idx1 = [idx1; vec(id(1:end-1,1:end-1)); vec(id(2:end,1:end-1))];105     idx2 = [idx2; vec(id(2:end,2:end)); vec(id(1:end-1,2:end))];106 else107     error(The second input argument must be either 4 or 8.)108 end109 110 % Create the groups and merge them (Union/Find Algorithm)111 for k = 1:length(idx1)112     root1 = idx1(k);113     root2 = idx2(k);114     115     while root1~=id(root1)116         id(root1) = id(id(root1));117         root1 = id(root1);118     end119     while root2~=id(root2)120         id(root2) = id(id(root2));121         root2 = id(root2);122     end123     124     if root1==root2, continue, end125     % (The two pixels belong to the same group)126     127     N1 = sz(root1); % size of the group belonging to root1128     N2 = sz(root2); % size of the group belonging to root2129     130     if max(I(root1),I(root2))/min(I(root1),I(root2)) <= 3131         % then merge the two groups132         if N1 < N2133             id(root1) = root2;134             sz(root2) = N1+N2;135         else136             id(root2) = root1;137             sz(root1) = N1+N2;138         end139     end140 end141 142 while 1143     id0 = id;144     id = id(id);145     if isequal(id0,id), break, end146 end147 sz = sz(id);148 149 % Label matrix150 isNaNI = isinf(I);151 id(isNaNI) = NaN;152 [id,m,n] = unique(id);153 I = 1:length(id);154 L = reshape(I(n),sizI);155 L(isNaNI) = 0;156 157 if nargout>1, num = nnz(~isnan(id)); end

extract.m

 1 function [ letters ] = extractletters( swtMap, swtLabel, ccNum ) 2 %LETTERCANDIDATES Summary of this function goes here 3 %   Detailed explanation goes here 4  5 numLetters = 0; 6 letters = zeros(size(swtLabel)); 7 maxLetterHeight = 300; 8 minLetterHeight = 10; 9 10 for i=1:ccNum11     12     [r,c] = find(swtLabel==i);13     idx = sub2ind(size(swtMap),r,c);14     componentSW = swtMap(idx);15     varianceSW = var(componentSW);16     meanSW = mean(componentSW);17     width = max(c) - min(c);18     height = max(r) - min(r);19     aspectRatio = width/height;20     diameter = sqrt(width^2+height^2);21     medianSW = median(componentSW);22     maxSW = max(componentSW);23     24     % Accepted font heights are between 10px and 300px25     if height>maxLetterHeight | height<minLetterHeight, continue, end26     27     % Reject CC with hight stroke width variance.  The threshold if half28     % the average stroke width of a connected component29     if varianceSW/meanSW > .5, continue, end30     31     % Ratio between the diameter of the connected component and its32     % median stroke width to be a value less than 1033     if diameter/medianSW >= 10, continue, end34     35     % Aspect ratio to be a value between 0.1 and 1036     if aspectRatio < 0.1 && aspectRatio > 10, continue, end37     38     if size(componentSW,1)/maxSW < 5, continue, end39     40     if width > height*2.5, continue, end41     42     43     letters(idx) = 1;44     45     %     if varianceSW <= meanSW*0.546     %         %if 0.1 <= aspectRatio && aspectRatio <= 1047     %             numLetters = numLetters + 1;48     %             letters(idx) = 1;49     %         %end50     %     end51     52 end53 54 end
function [ final ] = detecttext( imName )%DETECTTEXT Summary of this function goes here%   Detailed explanation goes hereimage = imread(imName);swtMap = swt(image,-1);[swtLabel numCC] = swtlabel(swtMap);final = extractletters(swtMap, swtLabel, numCC);end