Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function CV2011_1HW4_ben_delillo()
- imdir = 'C:\Users\Ben\Downloads\'; % Change this as appropriate
- I = imread(strcat(imdir,'TextImage.tif'));
- % Use inverted binary image. Inversion changes the letters and other ink
- % from holes into connected components.
- Iinv = im2bw(I) == 0;
- % After many variatons on refining edge detection I stumbled upon
- % morphological operations and that using a structuring element made up
- % of one element at the origin and one element three pixels above,
- % approximating the separation between the base of an i and its tittle,
- % was enough to change an i into a single connected component without
- % compromising the integrity of the rest of the image as a blur would have.
- Iprocessed = imdilate(Iinv, strel('pair', [-3 0]));
- % Manualy extract example instance of what we want to find
- target = imcrop(Iprocessed, [682 467 16 30]);
- % Split into connected comonents
- [components count] = bwlabel(Iprocessed);
- % Using regionprops FilledImage option lets us easily analyze each
- % candidate letter
- stats = regionprops(components, 'BoundingBox', 'FilledImage');
- % Making all letter candidates the same size as the target makes
- % comparison easier (also allows for finding off-scale matches)
- % It also makes rejecting small (< 10 pixels) clumps as they stretch
- % out as to almost make a solid white box.
- sizeToTemplate = @(img) imresize(img{1},size(target));
- % Embed each image in a cell because arrayfun needs uniformly sized input
- letters = arrayfun(sizeToTemplate, {stats.FilledImage},...
- 'UniformOutput', false); % non-scalar output requires manual override
- % This algorithm relies on two assumptions. The first is that shape
- % matching the target shape will have a similar 'density' of white pixels
- % per row as the target shape. The second is that the pool of candidates
- % will not have non-matching shapes with a similar density 'fingerprint'.
- % That second assumption actually fails for this text when using columns to
- % calculate that fingerprint because of how letters are taller than they
- % are wide and how similar l is to i. However, using the sum of rows
- % instead is high enough resolution that the algorithm can successfully
- % differentiate between l and i.
- sumOfDiffsOfRowPixelSums = @(ltr) sum(abs(sum(ltr, 2) - sum(target,2)));
- colSumDiffs = cellfun(sumOfDiffsOfRowPixelSums, letters);
- % Is there an equivalent of the functional 'filter' idiom?
- results = []; bbs = [];
- for n=1:count
- if colSumDiffs(n) < 50
- results = cat(4, results, letters{n});
- bbs = cat(2, bbs, stats(n).BoundingBox.');
- end
- end
- foundCount = length(results);
- titleStr = ['Found ', num2str(foundCount), ' instances of the letter i'];
- figure('Name', titleStr), imshow(I);
- plotBoundingBoxes(bbs);
- function plotBoundingBoxes(boxes)
- hold on;
- for cnt = 1:length(boxes)
- rectangle('position', boxes(:,cnt), 'edgecolor', 'r');
- end
- function imSxS(im1, im2)
- figure;
- subplot(1,2,1), subimage(im1);
- subplot(1,2,2), subimage(im2);
Add Comment
Please, Sign In to add comment