标签:style blog http color os width
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. It‘s 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 ray 101 sizeOfRay = sizeOfRay + 1; 102 103 % Another edge pixel has been found 104 if edgeMap(nextX,nextY) 105 106 oppositeTheta = theta(nextX,nextY); 107 108 % Gradient direction roughtly opposite 109 if abs(abs(initialTheta - oppositeTheta) - pi) < pi/2 110 isStroke = 1; 111 strokePointsX(sizeOfStrokePoints+1) = initialX; 112 strokePointsY(sizeOfStrokePoints+1) = initialY; 113 sizeOfStrokePoints = sizeOfStrokePoints + 1; 114 end 115 116 break 117 end 118 end 119 120 % Edge pixel is part of stroke 121 if isStroke 122 123 % Calculate stoke width 124 strokeWidth = sqrt((nextX - initialX)^2 + (nextY - initialY)^2); 125 126 % Iterate all ray points and populate with the minimum stroke width 127 for j=1:sizeOfRay 128 swtMap(pointOfRayX(j),pointOfRayY(j)) = min(swtMap(pointOfRayX(j),pointOfRayY(j)),strokeWidth); 129 end 130 end 131 end 132 133 %figure, imshow(swtMap, []), title(‘Stroke Width Transform: First Pass‘); 134 135 % Iterate through all stoke points for a refinement pass. Refer to figure 136 % 4b in the paper. 137 138 for i=1:sizeOfStrokePoints 139 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 ray 150 pointOfRayX(sizeOfRay+1) = initialX; 151 pointOfRayY(sizeOfRay+1) = initialY; 152 153 % Increase the size of the ray 154 sizeOfRay = sizeOfRay + 1; 155 156 % Record the swt value of first stoke point 157 swtValues(sizeOfSWTValues+1) = swtMap(initialX,initialY); 158 sizeOfSWTValues = sizeOfSWTValues + 1; 159 160 % Follow the ray 161 while step < maxStrokeWidth 162 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 ray 168 pointOfRayX(sizeOfRay+1) = nextX; 169 pointOfRayY(sizeOfRay+1) = nextY; 170 171 % Increase size of the ray 172 sizeOfRay = sizeOfRay + 1; 173 174 % Record the swt value of next stoke point 175 swtValues(sizeOfSWTValues+1) = swtMap(nextX,nextY); 176 sizeOfSWTValues = sizeOfSWTValues + 1; 177 178 % Another edge pixel has been found 179 if edgeMap(nextX,nextY) 180 break 181 end 182 end 183 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 width 188 for j=1:sizeOfRay 189 swtMap(pointOfRayX(j),pointOfRayY(j)) = min(swtMap(pointOfRayX(j),pointOfRayY(j)),strokeWidth); 190 end 191 192 end 193 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 neighborhood 102 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 else 107 error(‘The second input argument must be either 4 or 8.‘) 108 end 109 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 end 119 while root2~=id(root2) 120 id(root2) = id(id(root2)); 121 root2 = id(root2); 122 end 123 124 if root1==root2, continue, end 125 % (The two pixels belong to the same group) 126 127 N1 = sz(root1); % size of the group belonging to root1 128 N2 = sz(root2); % size of the group belonging to root2 129 130 if max(I(root1),I(root2))/min(I(root1),I(root2)) <= 3 131 % then merge the two groups 132 if N1 < N2 133 id(root1) = root2; 134 sz(root2) = N1+N2; 135 else 136 id(root2) = root1; 137 sz(root1) = N1+N2; 138 end 139 end 140 end 141 142 while 1 143 id0 = id; 144 id = id(id); 145 if isequal(id0,id), break, end 146 end 147 sz = sz(id); 148 149 % Label matrix 150 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:ccNum 11 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 300px 25 if height>maxLetterHeight | height<minLetterHeight, continue, end 26 27 % Reject CC with hight stroke width variance. The threshold if half 28 % the average stroke width of a connected component 29 if varianceSW/meanSW > .5, continue, end 30 31 % Ratio between the diameter of the connected component and its 32 % median stroke width to be a value less than 10 33 if diameter/medianSW >= 10, continue, end 34 35 % Aspect ratio to be a value between 0.1 and 10 36 if aspectRatio < 0.1 && aspectRatio > 10, continue, end 37 38 if size(componentSW,1)/maxSW < 5, continue, end 39 40 if width > height*2.5, continue, end 41 42 43 letters(idx) = 1; 44 45 % if varianceSW <= meanSW*0.5 46 % %if 0.1 <= aspectRatio && aspectRatio <= 10 47 % numLetters = numLetters + 1; 48 % letters(idx) = 1; 49 % %end 50 % end 51 52 end 53 54 end
function [ final ] = detecttext( imName ) %DETECTTEXT Summary of this function goes here % Detailed explanation goes here image = imread(imName); swtMap = swt(image,-1); [swtLabel numCC] = swtlabel(swtMap); final = extractletters(swtMap, swtLabel, numCC); end
标签:style blog http color os width
原文地址:http://www.cnblogs.com/fandaojian/p/3849837.html