crop an image per words
Show older comments
i wanna crop an image per words,,,example : in image i have a sentence : "everybody going crazy"..and i wanna crop it per words so the result has 3 parts : parts 1 is an image with "everybody' words,parts 2 is an image with "going' words,and part3 is an image with "crazy' words,..what should i do to separated that words ?
11 Comments
Matt Kindig
on 19 Mar 2013
Edited: Image Analyst
on 19 Mar 2013
What you are doing is called Optical Character Recognition (OCR) and is a huge area of study. The exact algorithm will strongly depend on the quality of your image and the characters inside. Can you upload your image for us? To do this, just put it somewhere (e.g. tinypic.com) and post the link to the image in your question.
Dwi Putra Alexander
on 19 Mar 2013
Matt Kindig
on 19 Mar 2013
Edited: Matt Kindig
on 19 Mar 2013
Ok, a follow-up question: Do you need to recognize the letters (i.e., does MATLAB actually have to read the text), or is simply separating the image into thirds based on the spaces between them sufficient? The latter option can be straightforward, provided your images are all similar, while the first option is, as Image Analyst said, a substantial undertaking that would be quite complex and difficult.
Also, how consistent are your images? In other words, do all the images have similar size, color/contrast, space between words, etc.? Maybe upload a couple of other images you also want to classify to help us see the consistency between images...
Dwi Putra Alexander
on 19 Mar 2013
Dwi Putra Alexander
on 19 Mar 2013
Dwi Putra Alexander
on 19 Mar 2013
Matt Kindig
on 19 Mar 2013
Good, that way is much easier. This sounds like a homework question, so I'm not going to do the code for you, but here is one approach that you can try, with the appropriate functions shown. I assume that you have the Image Processing Toolbox.
1. Convert the image to black and white
doc im2bw
2. Thicken the lines of the image using bwmorph, so that all of the cursive letters of a single word are connected. You'll need to play with different methods and settings until you get something that works. You might also need to try imdilate() as well.
doc bwmorph
doc strel
doc imdilate
3. Use regionprops to extract the bounding box of each of the word objects of the image with the thickened lines.
doc regionprops
4. Use imcrop to crop the image based on the bounding box, and output the single word image:
doc imcrop
doc imwrite
Dwi Putra Alexander
on 19 Mar 2013
Matt Kindig
on 19 Mar 2013
How did you get these two images? Which operations did you perform on the images to do this?
Matt Kindig
on 19 Mar 2013
Also, I think part of your problem is that you are working with the RGB (color) images directly, whereas performing the word separation on the black and white images directly is probably easier. As a reminder, the bwmorph() operations work on the white pixels, so you might want to invert the black and white matrix so that the text is white and the background is black, rather than the way you have shown it here.
Image Analyst
on 20 Mar 2013
Dwi, see my code in my Answer below. Basically I did it for you. At least it works for that one image you uploaded.
Answers (3)
Image Analyst
on 19 Mar 2013
Edited: Image Analyst
on 20 Mar 2013
Whole companies of people have been working on this for decades, so as you can guess it's not trivial. Go here : http://iris.usc.edu/Vision-Notes/bibliography/contentschar.html#OCR,%20Document%20Analysis%20and%20Character%20Recognition%20Systems and pick an algorithm, then code it up in MATLAB. We can't help you until you get to that point. There is no OCR toolbox for MATLAB that I'm aware of.
Here's what I would do
- threshold
- call imdilate
- call regionprops
- crop the bounding boxes.
EDIT:
Dwi, I haven't heard from you so I assume you are having trouble. Run my code to see how it's done.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
imtool close all; % Close all imtool figures if you have the Image Processing Toolbox.
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 20;
% Read in a standard MATLAB gray scale demo image.
folder = 'C:\Users\DWI\Documents\Temporary';
baseFileName = '9jmwll.jpg';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% File doesn't exist -- 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 in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
grayImage = imread(fullFileName);
% Get the dimensions of the image.
% numberOfColorBands should be = 1.
[rows columns numberOfColorBands] = size(grayImage);
% Display the original gray scale image.
subplot(2, 3, 1);
imshow(grayImage, []);
title('Original Grayscale Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
% Give a name to the title bar.
set(gcf,'name','Demo by ImageAnalyst for Dwi Putra Alexander','numbertitle','off')
% Convert to grayscale
if numberOfColorBands > 1
grayImage = grayImage(:,:,2); % Take green channel
end
% Let's compute and display the histogram.
[pixelCount grayLevels] = imhist(grayImage);
subplot(2, 3, 2);
bar(pixelCount);
grid on;
title('Histogram of original image', 'FontSize', fontSize);
xlim([0 grayLevels(end)]); % Scale x axis manually.
% Threshold the image.
binaryImage = grayImage < 175;
% Display the image.
subplot(2, 3, 3);
imshow(binaryImage, []);
title('Binary Image', 'FontSize', fontSize);
% Dilate to connect all the letters
binaryImage = imdilate(binaryImage, true(7));
% Get rid of blobs less than 200 pixels (the dot of the i).
binaryImage = bwareaopen(binaryImage, 200);
% Display the image.
subplot(2, 3, 3);
imshow(binaryImage, []);
title('Binary Image', 'FontSize', fontSize);
% Find the areas and bounding boxes.
measurements = regionprops(binaryImage, 'Area', 'BoundingBox');
allAreas = [measurements.Area]
% Crop out each word
for blob = 1 : length(measurements)
% Get the bounding box.
thisBoundingBox = measurements(blob).BoundingBox;
% Crop it out of the original gray scale image.
thisWord = imcrop(grayImage, thisBoundingBox);
% Display the cropped image
subplot(2,3, 3+blob); % Switch to proper axes.
imshow(thisWord); % Display it.
% Put a caption above it.
caption = sprintf('Word #%d', blob);
title(caption, 'FontSize', fontSize);
end
23 Comments
Image Analyst
on 20 Mar 2013
So, what do you think? Did that solve your problem?
Mohamed Mohamed
on 6 Apr 2015
(Y) thanks you are great man :D
sindhu c
on 29 Nov 2015
Is it same for segmenting words in a line of text in an image?
sindhu c
on 12 Dec 2015

for this image,correct cropping is not achieved.How do i achieve this ??Pls help..
Image Analyst
on 12 Dec 2015
Why not? How can anyone possibly know without you telling us what code or algorithm you used? Did you use my code, my code adapted by you, your original code, or your code that tried to follow one of the papers in the reference I gave? We have no idea.
sindhu c
on 13 Dec 2015
Sorry ..very much sorry for that.Yes,i used the code provided by you and it dint work correctly for the above image
Image Analyst
on 13 Dec 2015
sindhu, you didn't change the dilation to correspond to your particular image. When I do that it works just great. Can you at least "Vote" for my answer? Thanks in advance. Here is your code:
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
imtool close all; % Close all imtool figures if you have the Image Processing Toolbox.
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 20;
% Read in a standard MATLAB gray scale demo image.
folder = pwd;
baseFileName = 'secondline.png';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% File doesn't exist -- 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 in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
grayImage = imread(fullFileName);
% Get the dimensions of the image.
% numberOfColorBands should be = 1.
[rows columns numberOfColorBands] = size(grayImage);
% Display the original gray scale image.
subplot(2, 2, 1);
imshow(grayImage, []);
title('Original Grayscale Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
% Give a name to the title bar.
set(gcf,'name','Demo by ImageAnalyst for Dwi Putra Alexander','numbertitle','off')
% Convert to grayscale
if numberOfColorBands > 1
grayImage = grayImage(:,:,2); % Take green channel
end
% Let's compute and display the histogram.
[pixelCount grayLevels] = imhist(grayImage);
subplot(2, 2, 2);
bar(pixelCount);
grid on;
title('Histogram of original image', 'FontSize', fontSize);
xlim([0 grayLevels(end)]); % Scale x axis manually.
% Threshold the image.
binaryImage = grayImage < 175;
% Display the image.
subplot(2, 2, 3);
imshow(binaryImage, []);
title('Binary Image', 'FontSize', fontSize);
% Dilate to connect all the letters
binaryImage = imdilate(binaryImage, true(1, 40));
% Get rid of blobs less than 200 pixels (the dot of the i).
binaryImage = bwareaopen(binaryImage, 200);
% Display the image.
subplot(2, 2, 3);
imshow(binaryImage, []);
title('Binary Image', 'FontSize', fontSize);
% Find the areas and bounding boxes.
measurements = regionprops(binaryImage, 'Area', 'BoundingBox');
allAreas = [measurements.Area]
% Crop out each word
for blob = 1 : length(measurements)
% Get the bounding box.
thisBoundingBox = measurements(blob).BoundingBox;
% Crop it out of the original gray scale image.
thisWord = imcrop(grayImage, thisBoundingBox);
% Display the cropped image
subplot(2, 2, 4); % Switch to proper axes.
imshow(thisWord); % Display it.
% Put a caption above it.
caption = sprintf('Word #%d', blob);
title(caption, 'FontSize', fontSize);
promptMessage = sprintf('This is word #%d\nDo you want to Continue processing,\nor Cancel processing?', blob);
titleBarCaption = 'Continue?';
button = questdlg(promptMessage, titleBarCaption, 'Continue', 'Cancel', 'Continue');
if strcmpi(button, 'Cancel')
return;
end
end

sindhu c
on 13 Dec 2015
Thank you so much sir :)
sindhu c
on 13 Dec 2015
i'm on my final year project,thanks for helping out and i would request you to guide me further also :)
Image Analyst
on 13 Dec 2015
You're welcome. Good luck on your project. If you have any other questions, start your own discussion topic, so we don't bug Dwi Putra with emails, (though he seems to have dropped off the planet).
Meghashree G
on 12 Jan 2016
hello sir,i tried your code for word segmentation,but im not getting it .Pls do help me.. Here's my input image.

Image Analyst
on 13 Jan 2016
Please attach your m-file so I can try to run it and help you.
Meghashree G
on 13 Jan 2016
sure sir.. Please look into code(this input(line2.png ,which i have attached in my previous comment) is got from segmentation of lines from paragraph.
Image Analyst
on 13 Jan 2016
Your image is not a grayscale image - it's a binary image, so you can't threshold at 175. You have to invert the image. If you do this:
% Threshold the image.
binaryImage = ~grayImage;
then it works fine.
Meghashree G
on 14 Jan 2016
Thank you so much sir :) its working fine
sayyed Inamdar
on 7 Apr 2016
AWESOME PIECE OF CODE WORKS GRT
Meghashree G
on 8 Apr 2016
Edited: Meghashree G
on 8 Apr 2016
Hello sir, what changes should be made for the code to work for this line to achieve word segmentation?? please help me!! thank you

lotus whit
on 8 Aug 2016
Edited: Image Analyst
on 8 Aug 2016
it is great work , could you please ask you , why this code is working properly with attached (image_line1), but it doesn't work with attached image_line2..? i don't know where is the problem. the size of font or another factor......can you help me
------------------ Line 1 Below --------------------------

------------------ Line 2 Below --------------------------

Image Analyst
on 8 Aug 2016
Because the letters are white on black instead of black on white. Try inverting your image and getting rid of the big uniform rectangles on the top and bottom.
lotus whit
on 11 Aug 2016
Edited: lotus whit
on 11 Aug 2016
Thank you a lot for your comments
Image Analyst
on 14 Aug 2018
Moved: DGM
on 12 Feb 2023
No algorithm works on all possible images.
Doesn't work correctly on IAM handwriting dataset. Please find the attached result. Can you recommend what changes can I do for the improvement?
sayar chit
on 16 Oct 2017
Edited: Image Analyst
on 16 Oct 2017
0 votes
Hi Sir. I used your code with my images. But both of your codes are not working. So, help me please. Figure 1 is my image, figure 2 is what I got when your first code used and figure 3 is got when your second code used. I am waiting for your reply. Thanks you sir!

My input image is below:

10 Comments
Image Analyst
on 16 Oct 2017
Try the attached.
sayar chit
on 24 Oct 2017
Thanks in advance! I will try it now.
sayar chit
on 24 Oct 2017
Sir My input image is 4.jpg. I want to get it as four pieces for words segmentation. I want to get images as part one like a.jpg figure, second part like b.jpg, third part is c.jpg and final part is d.jpg. This image is as follows.
sayar chit
on 24 Oct 2017
Moved: DGM
on 12 Feb 2023

<<
<<
<<

>>
>>
>>
sayar chit
on 24 Oct 2017
Moved: DGM
on 12 Feb 2023

I got like as below figure using your code. Please help me Sir. I wish you good luck and health for your whole life. Thanks a lot again.

sayar chit
on 24 Oct 2017
Moved: DGM
on 12 Feb 2023
I want to get like this.

Image Analyst
on 24 Oct 2017
Moved: DGM
on 12 Feb 2023
Get the mean of the binary image vertically and look for spaces (white pixels)
horizontalProfile = mean(binaryImage, 1);
hasWord = horizontalProfile < 255;
Now has word will be true if the column is inside a word, and false if it's in the white space between words.
sayar chit
on 25 Oct 2017
Moved: DGM
on 12 Feb 2023
Thank Sir for answering my questions!
sayar chit
on 25 Oct 2017
Moved: DGM
on 12 Feb 2023
Sir! I don't get my result. So Sir help me please, if Sir has free. Thanks in advanced.
sayar chit
on 31 Oct 2017
Moved: DGM
on 12 Feb 2023
Sir! I got line and word segmentation for your codes and your suggestion. Thanks Sir. But I have a little problem. If my input paragraph images is incline (skew, my code do not work as well. So how do I need to overcome it problem? Help me please Sir. Thanks for all REALLY! my inclination input image is below as a sample.

SS Jabeen
on 8 Feb 2018
0 votes
How do I use the above given code to segment the words in my image, can someone please explain me why is the code not working for my image?
6 Comments
Image Analyst
on 8 Feb 2018
What code? You forgot to attach your non-working code.
SS Jabeen
on 12 Feb 2018
The one on the top of the page that you wrote, anyway I could get it to work. Thanks for asking.
SS Jabeen
on 20 Mar 2018
How do I find the coordinates P1 and P2 in this image?

Image Analyst
on 20 Mar 2018
I'd use impoint().
SS Jabeen
on 20 Mar 2018
Thanks for the help, and impoint() would be helpful in verifying but while finding for multiple images manually moving the cursor would be a tad bit difficult. Is there any another alternative?
Image Analyst
on 20 Mar 2018
Another manual way is to use ginput(). If it's automatic, you can use find() to get the leftmost, topmost, rightmost, and bottom most black pixels in the image. If you want it by letter, then you'll have to get the locations of pixels in each letter, like you can get from calling regionprops() and asking for "PixelList'.
Categories
Find more on Startup and Shutdown in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!