How to detect particular letters in a binary text image?

8 views (last 30 days)
I have a binary image like this:
I want to detect lower case 'e'/ or some other letter in the binary image and the output image should show detected text highlighted in some color and all other text in black. is this possible?? using binary morphological techniques??
if yes how do I do it? where should I start from?
Thanks for your time and guidance.
Dishant Arora.
  1 Comment
Image Analyst
Image Analyst on 4 Oct 2012
Edited: Image Analyst on 4 Oct 2012
That's a grayscale image, not a binary (logical, true/false, 1/0) image. It's not binary until you threshold it.

Sign in to comment.

Answers (3)

Image Analyst
Image Analyst on 4 Oct 2012
You need to threshold, then separate letters if necessary (like with imclose). Then label and call regionprops. Then find things that define an "e", like maybe the Euler number, area, solidity, etc. - whatever makes the e unique and different from the other letters. But the letters are close together and blurry so it might be a little tough. You can also get the BoundingBox to identify the region around the e, which you can use to set the pixels above the threshold to yellow or some other color. The black pixels in the e could also be set to some other color if desired. That would work for this one image because you can tweak/optimize parameters until you pick out just the e. Now whether this will work on all other images with text of different sizes, fonts, colors, etc. is doubtful, but then you're not planning on writing a full-blown OCR program are you? You're planning on just finding the e's in this one image, or images of the same typeface.
  2 Comments
Dishant Arora
Dishant Arora on 4 Oct 2012
Thanks image analyst.
no, am not willing to use OCR program. I didn't get "find things that define e". what does that mean??
Image Analyst
Image Analyst on 4 Oct 2012
Edited: Image Analyst on 4 Oct 2012
For example, maybe all the e's have an area between 22 and 25 pixels and all the other letters have different areas. Then maybe all the E's have an Euler number of 0 and that narrows the blob down to letters that have holes in them. Them the solidity for e's is probably in a certain range also - different than the solidity for other characters. See my BlobsDemo for how to combine all those criteria using logical operations and ismember() to get an image with only those blobs meeting all those criteria. Try this for starters:
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
imtool close all; % Close all imtool figures.
clear; % Erase all existing variables.
workspace; % Make sure the workspace panel is showing.
format longg;
format compact;
fontSize = 20;
% Read in a standard MATLAB color demo image.
folder = 'C:\Users\Dishant\Documents\Temporary';
baseFileName = '33xhc8x.jpg';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
if ~exist(fullFileName, 'file')
% Didn't find it there. Check the search path for it.
fullFileName = baseFileName; % No path this time.
if ~exist(fullFileName, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
rgbImage = imread(fullFileName);
% Get the dimensions of the image. numberOfColorBands should be = 3.
[rows columns numberOfColorBands] = size(rgbImage);
% Display the original color image.
subplot(2, 2, 1);
imshow(rgbImage, []);
title('Original Color Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
% Extract the individual green color channels.
grayImage = rgbImage(:, :, 2);
% Display the monochrome image.
subplot(2, 2, 2);
imshow(grayImage, []);
title('Original Monochrome Image', 'FontSize', fontSize);
% Let's compute and display the histogram.
[pixelCount grayLevels] = imhist(grayImage);
subplot(2, 2, 3);
bar(pixelCount);
grid on;
title('Histogram of original image', 'FontSize', fontSize);
xlim([0 grayLevels(end)]); % Scale x axis manually.
% Threshold the image
binaryImage = grayImage < 140;
% Display the binary image.
subplot(2, 2, 4);
imshow(binaryImage, []);
title('Binary Image', 'FontSize', fontSize);
% Label each blob with 8-connectivity, so we can make measurements of it
[labeledImage numberOfBlobs] = bwlabel(binaryImage, 8);
% Apply a variety of pseudo-colors to the regions.
coloredLabelsImage = label2rgb (labeledImage, 'hsv', 'k', 'shuffle');
% Display the pseudo-colored image.
figure;
subplot(2, 1, 1);
imshow(binaryImage, []);
title('Binary Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
imshow(coloredLabelsImage);
% Get all the blob properties. Can only pass in originalImage in version R2008a and later.
blobMeasurements = regionprops(labeledImage, grayImage, 'all');

Sign in to comment.


Kristopher Hazen Goodyear
Kristopher Hazen Goodyear on 18 Nov 2019
Edited: Kristopher Hazen Goodyear on 18 Nov 2019
This will show the the image "I" and letter you crop an area. After cropping, will use xcorr to find where the temple match in the rest of the image with a score above a threshold, in this case 0.7. You could modify this to just have a templet of the letter you are looking for.
clear all
close all
% Read in image
I = imread('textsample.tif');
% Have user select a section of the image and create template
a_template = imcrop(I);
figure
imshow(a_template)
% Cross-correlate the image with the template
Xcorr = normxcorr2(a_template, I);
% Threshold the image
t_Xcorr = graythresh(Xcorr);
Xcorr_threshold = Xcorr > 0.7;
figure
imshow(Xcorr_threshold);
% Dim of the template and image are needed for drawing boxes and loops
temp_dim = size(a_template);
I_dim = size(I);
y_len = temp_dim(1); x_len = temp_dim(2);
% Find the blods in the thresholded image
L = bwlabel(Xcorr_threshold);
blobs = regionprops(L);
% Draw red box around all the centroids of the blobs
figure
imshow(I)
for k = 1:length(blobs)
y1 = blobs(k).Centroid(2) - y_len/2; x1 = blobs(k).Centroid(1) - x_len/2;
pos_vec = [x1-x_len/2 y1-y_len/2 temp_dim(2) temp_dim(1)];
rectangle('Position', pos_vec, 'EdgeColor', 'r');
drawnow;
end
% Display the number of a's
text(175,100, "There are: " + length(blobs) + " a's", 'FontSize', 14, 'color', 'r')
  2 Comments
Image Analyst
Image Analyst on 31 Dec 2021
Edited: Image Analyst on 31 Dec 2021
@Areen Drwesh perhaps the image you're asking for, and is in Kristopher's code, is the one the original poster attached. I'm attaching it here.
Change his code to 'textsample.png' because I had to attach it as a PNG file because (for now) Answers doesn't let you attach a TIF file.
% Read in image
I = imread('textsample.png');

Sign in to comment.


Navneet  Kaur
Navneet Kaur on 1 Jun 2022
Edited: Image Analyst on 1 Jun 2022
clear all
close all
% Read in image
I = imread('textsample.png');
% Have user select a section of the image and create template
a_template = imcrop(I);
figure
imshow(a_template)
% Cross-correlate the image with the template
Xcorr = normxcorr2(a_template, I);
% Threshold the image
t_Xcorr = graythresh(Xcorr);
Xcorr_threshold = Xcorr > 0.7;
figure
imshow(Xcorr_threshold);
% Dim of the template and image are needed for drawing boxes and loops
temp_dim = size(a_template);
I_dim = size(I);
y_len = temp_dim(1); x_len = temp_dim(2);
% Find the blods in the thresholded image
L = bwlabel(Xcorr_threshold);
blobs = regionprops(L);
% Draw red box around all the centroids of the blobs
figure
imshow(I)
for k = 1:length(blobs)
y1 = blobs(k).Centroid(2) - y_len/2; x1 = blobs(k).Centroid(1) - x_len/2;
pos_vec = [x1-x_len/2 y1-y_len/2 temp_dim(2) temp_dim(1)];
rectangle('Position', pos_vec, 'EdgeColor', 'r');
drawnow;
end
% Display the number of a's
text(175,100, "There are: " + length(blobs) + " a's", 'FontSize', 14, 'color', 'r')

Tags

No tags entered yet.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!