Find the bounds of a letter
Post your questions regarding programming in C# in here.
5 posts
Page 1 of 1
How could I find the bounds of the different letters in a pure black/white image?
Lets say I have this image below, the bounds for the letter L is X 101, Y 23, W 40, H 65.
How could I detect that in code?
I would love to have it in C#, but VB is just as good.
Lets say I have this image below, the bounds for the letter L is X 101, Y 23, W 40, H 65.

How could I detect that in code?
I would love to have it in C#, but VB is just as good.
LMAOSHMSFOAIDMT
Laughing my a** of so hard my sombrero fell off and I dropped my taco lmao;
Over 30 projects with source code!
Please give reputation to helpful members!
![Image]()
![Image]()
Laughing my a** of so hard my sombrero fell off and I dropped my taco lmao;
Over 30 projects with source code!
Please give reputation to helpful members!

You mean of a string or an image ? for a string with a certain font you can try Graphics.Measurestring();
I know of that, but I only have the image, no info about font, font size, font style, nothing but the image. I have to find a way to find the rectangle for each letter. Thats all I need, because I have the character recognition ready, I just need to find the right rectangle to take the data from.
LMAOSHMSFOAIDMT
Laughing my a** of so hard my sombrero fell off and I dropped my taco lmao;
Over 30 projects with source code!
Please give reputation to helpful members!
![Image]()
![Image]()
Laughing my a** of so hard my sombrero fell off and I dropped my taco lmao;
Over 30 projects with source code!
Please give reputation to helpful members!

To find the top-left character's rectangle you just need to look for pixel conditions, and keep track of the minimum/maximum coordinate types.
The right of the last character can be used to continue the search.
This basic method will only work for text on one line like above (otherwise overlapping will occur).
In short this algorithm will do all the work:
Edit: Improved efficiency!
The right of the last character can be used to continue the search.
This basic method will only work for text on one line like above (otherwise overlapping will occur).
In short this algorithm will do all the work:
Code: Select all
I have attached a screenshot of the result. private void btnTest_Click(object sender, EventArgs e)
{
Bitmap bmp = new Bitmap("example.png");
Rectangle range = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData bd = bmp.LockBits(range, ImageLockMode.ReadOnly, bmp.PixelFormat);
int cLeft = -1;
int cTop = bd.Height;
int cRight = -1;
int cBottom = -1;
List<Rectangle> regions = new List<Rectangle>();
//search from top to bottom, left to right
//note characters such as " will be seen as 2 seperate regions
for (int x = 0; x < bd.Width; x++)
{
for (int y = 0; y < bd.Height; y++)
{
//Format32bppArgb uses a BGRA pixel structure
IntPtr offset = (IntPtr)(bd.Scan0.ToInt32() + (x * 4) + (y * bd.Stride));
byte b = Marshal.ReadByte(offset);
if (b > 0)//see if blue is greater than 0. example pixel condition
{
if (cLeft == -1)
{
cLeft = x;
}
if (cBottom < y)
{
cBottom = y;
}
if (cTop > y)
{
cTop = y;
}
if (cRight < x)
{
cRight = x;
}
}
else if ((x - cRight) > 1)
{
//if there is more than 1 X pixel after the last successful condition then it can continue
if (cBottom > -1)
{
int cWidth = (x - 1) - cLeft;
int cHeight = cBottom - cTop;
Rectangle rect = new Rectangle(cLeft, cTop, cWidth, cHeight);
regions.Add(rect);
cTop = bd.Height;
cBottom = -1;
cRight = -1;
cLeft = cRight;//start from this region's right
}
}
}
}
bmp.UnlockBits(bd);
MessageBox.Show(regions.Count + " regions found");
Graphics gfx = Graphics.FromImage(bmp);
for (int i = 0; i < regions.Count; i++)
{
gfx.DrawRectangle(Pens.Green, regions[i]);//draw a green rectangle around each letter
}
gfx.Dispose();
pictureBox1.Image = bmp;
}
Edit: Improved efficiency!
You do not have the required permissions to view the files attached to this post.
Last edited by mandai on Thu Feb 09, 2012 2:19 pm, edited 5 times in total.
Thanks, thats just what i needed. I had something similar in mind yesterday
Code: Select all
But t knew it missed something private Letter[] FindLetters(byte[] d, int Stride, int Width, int Height)
{
List<Letter> l = new List<Letter>();
bool inLetter = false;
Rectangle temp = new Rectangle(new Point(int.MaxValue, int.MaxValue), new Size(int.MinValue, int.MinValue));
for (int y = 0; y < Height; y++)
{
for (int x = 0; x < Width; x++)
{
if (d[y * Stride + x * 3] > 245)
{
inLetter = true;
temp.X = Math.Min(temp.X, x);
temp.Y = Math.Min(temp.Y, y);
temp.Width = Math.Max(temp.Width, x);
temp.Height = Math.Max(temp.Height, y);
}
else
{
inLetter = false;
l.Add(new Letter { x = temp.X, y = temp.Y, w = temp.Width, h = temp.Height });
}
}
}
return l.ToArray();
}
LMAOSHMSFOAIDMT
Laughing my a** of so hard my sombrero fell off and I dropped my taco lmao;
Over 30 projects with source code!
Please give reputation to helpful members!
![Image]()
![Image]()
Laughing my a** of so hard my sombrero fell off and I dropped my taco lmao;
Over 30 projects with source code!
Please give reputation to helpful members!

5 posts
Page 1 of 1
Copyright Information
Copyright © Codenstuff.com 2020 - 2023