I assume you doing an OCR related project. There are so many different ways to do the image segmentation. In image segmentation fist you need to identify the upper and lower boundary of the image. Here is the code for the Line segmentation. you can optimize this further.....
histogramCreation histo = new histogramCreation();
getSpecificArea getSpecific = new getSpecificArea();
private Bitmap inputImage = null;
List<int> hHisto = new List<int>();
List<int> vHisto = new List<int>();
internal histogramCreation histogramCreation
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}
public List<bitmap> lineDetection(Bitmap image)
{
Bitmap Image = (Bitmap)image.Clone ();
setImage(Image);
hHisto = histo.horizontalProjection(inputImage);
vHisto = histo.verticalProjection (inputImage);
removeVLines();
removeHLines();
hHisto = histo.horizontalProjection(inputImage);
vHisto = histo.verticalProjection(inputImage);
int y = 0;
bool lineDetect = true;
List<int> lineTop = new List <int>();
List<int> lineBot = new List<int>();
List<bitmap> lineCapture = new List<bitmap>();
while (lineDetect)
{
y = findNextLine(hHisto,y);
if (y == -1) break;
if (y >= hHisto.Count)
{
lineDetect = false;
}
if (lineDetect)
{
if (lineTop.Count >= hHisto.Count)
{
break;
}
lineTop.Add(y);
y = findBottomOfLine(hHisto, y);
lineBot.Add(y);
bool flag = false;
for (int j = y; j < hHisto.Count; j++)
{
if (hHisto[j] > 0)
{
flag = true;
}
}
if (flag == false)
{
y = hHisto.Count;
}
if (y == hHisto.Count - 1)
{
break;
}
}
}
for (int lineCount = 0; lineCount < lineTop.Count; lineCount++)
{
int height = lineBot[lineCount] - lineTop[lineCount];
if (height >2 )
{
Bitmap newLine = new Bitmap(inputImage.Width, height);
newLine = getSpecific.GetSpecificAreaOfImage(new Rectangle(0, lineTop[lineCount], inputImage.Width, height), inputImage);
Bitmap cropLines = new Bitmap(newLine);
if (cropLines.Height > 12)
{
lineCapture.Add(cropLines);
}
}
}
if (lineCapture.Count == 0)
{
lineCapture.Add(image);
}
inputImage.Dispose();
return lineCapture;
}
private void removeHLines()
{
Bitmap tempImage = (Bitmap)inputImage.Clone();
for (int i = 0; i < hHisto.Count; i++)
{
if (hHisto[i] >= (tempImage.Width - 10))
{
for (int j = 0; j < tempImage.Width; j++)
{
tempImage.SetPixel(j, i, Color.White);
}
}
}
inputImage = tempImage;
}
private void removeVLines()
{
Bitmap tempImage = (Bitmap)inputImage.Clone();
for (int i = 0; i < vHisto.Count; i++)
{
if (vHisto[i] >= (tempImage.Height - 10) || vHisto[i + 2] == 0)
{
for (int j = 0; j < tempImage.Height; j++)
{
tempImage.SetPixel(i, j, Color.White);
}
}
if (i + 3 >= vHisto.Count)
{
break;
}
}
inputImage = tempImage;
}
private void setImage(Bitmap image)
{
this.inputImage = image;
}
private int findNextLine(List<int> histo, int start)
{
if (start > histo.Count)
{
return -1;
}
for (int i = start; i < histo.Count;i++)
{
if (histo[i] > 0)
{
start = i;
break;
}
}
return start < histo.Count ? start : -1;
}
private int findBottomOfLine(List<int> histo, int end)
{
for (int i = end; i < histo.Count; i++)
{
if (histo[i] == 0)
{
end = i;
break;
}
else if (i == hHisto.Count-1)
{
end = i;
}
}
return end < histo.Count ? end : -1;
}
}
In the above code snippet i used the histogram (projection profiling) to do the segmentation. Hope you know how to do the histogram creation, if not this is how to do histogram creation.
private pixelCheck pixelCheck = new pixelCheck();
List<int> hHisto = new List<int>();
List<int> vHisto = new List<int>();
internal pixelCheck pixelCheck1
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}
public List<int> horizontalProjection(Bitmap image)
{
hHisto.Clear();
for (int i = 0; i < image.Height; i++)
{
int val = 0;
for (int j = 0; j < image.Width; j++)
{
Color color = image.GetPixel(j, i);
int pixelValue = (int)(color.R + color.G + color.B) / 3;
val += (pixelCheck.getpixelCheck(pixelValue));
}
hHisto.Add(val);
}
return hHisto;
}
public List<int> verticalProjection(Bitmap image)
{
vHisto.Clear();
for (int i = 0; i < image.Width; i++)
{
int val = 0;
for (int j = 0; j < image.Height; j++)
{
Color color = image.GetPixel(i, j);
int pixelValue = (int)(color.R + color.G + color.B) / 3;
val += (pixelCheck.getpixelCheck(pixelValue));
}
vHisto.Add(val);
}
return vHisto;
}
you can archive character segmentation if following manner...
private histogramCreation histo = new histogramCreation();
private getSpecificArea getSpecific = new getSpecificArea();
private NoiceRemoval2 noise = new NoiceRemoval2();
private Bitmap inputImage = null;
private recognize recognize1 = new recognize();
private List<int> vHisto = new List<int>();
private List<int> hHisto = new List<int>();
private string value = "";
internal histogramCreation histogramCreation
{
get
{
throw new System.NotImplementedException();
}
set
{
}
}
public List<bitmap> charactorSegmentImage(Bitmap image)
{
vHisto.Clear();
hHisto.Clear();
string value = null;
setImage(image);
vHisto = histo.verticalProjection(inputImage);
hHisto = histo.horizontalProjection(inputImage);
int x = 0;
bool charactorDetect = true;
List<int> start = new List<int>();
List<int> end = new List<int>();
List<bitmap> charactorCapture = new List<bitmap>();
List<bitmap> finalCharacters = new List<bitmap>();
List<string> wordsDetected = new List<string>();
List<string> sectionDetected = new List<string>();
int charactorCount = 0;
while (charactorDetect)
{
if (x >= vHisto.Count)
{
break;
}
x = findNextCharactor(vHisto, x);
if (x >= vHisto.Count)
{
charactorDetect = false;
}
if (charactorDetect)
{
if (start.Count >= vHisto.Count)
{
break;
}
start.Add(x);
x = findnextWord(vHisto, x);
end.Add(x);
if (start[start.Count - 1] == end[end.Count - 1])
{
charactorDetect = false;
}
if (start.Count > 2)
{
if (start[start.Count - 1] == start[start.Count - 2])
{
start.Remove(start.Count - 1);
}
}
if (end.Count > 2)
{
if (end[end.Count - 1] == end[end.Count - 2])
{
end.Remove(end.Count - 1);
}
}
}
}
for (charactorCount = 0; charactorCount < start.Count; charactorCount++)
{
int width = end[charactorCount] - start[charactorCount];
if (width >= 2 && inputImage.Height > 10)
{
Bitmap newCharactor = new Bitmap(width, inputImage.Height);
newCharactor = getSpecific.GetSpecificAreaOfImage(new Rectangle(start[charactorCount], 0, width, inputImage.Height), inputImage);
Bitmap cropCharactors = new Bitmap(newCharactor);
cropCharactors = removeInvalidChar(cropCharactors);
if (cropCharactors != null)
{
charactorCapture.Add(cropCharactors);
}
for (int i = 0; i < charactorCapture.Count; i++)
{
string val = recognize1.characterRecognition(charactorCapture[i]);
value += (val);
}
}
if (end.Count - 1 == charactorCount && charactorCapture != null)
{
for (int i = 0; i < charactorCapture.Count; i++)
{
{
string val = recognize1.characterRecognition(charactorCapture[i]);
value += (val);
}
wordsDetected.Add(value);
}
}
}
return charactorCapture;
}
private void setImage(Bitmap image)
{
this.inputImage = image;
}
private int findNextCharactor(List<int> vHisto, int x)
{
if (x > vHisto.Count)
{
return -1;
}
for (int i = x; i < vHisto.Count; i++)
{
if (vHisto[i] > 0 && vHisto[i + 1] > 0)
{
x = i + 1;
break;
}
}
return x < vHisto.Count ? x : -1;
}
private int findnextWord(List<int> vHisto, int x)
{
for (int i = x; i < vHisto.Count; i++)
{
if (vHisto[i] == 0 && vHisto [i+1]==0)
{
x = i;
break;
}
else
{
if (vHisto[(vHisto.Count) - 1] != 0)
{
x = vHisto.Count;
}
}
if (i + 2 == vHisto.Count)
{
break;
}
}
return x <= vHisto.Count ? x : -1;
}
private Bitmap removeWhiteSpaces(Bitmap img)
{
Bitmap tempImg = img;
Bitmap recImg = (Bitmap)tempImg.Clone();
List<int> tempHiso = histo.horizontalProjection(img);
List<int> start = new List<int>();
for (int i = 0; i < tempHiso.Count; i++)
{
if (tempHiso[i] > 0)
{
start.Add(i);
}
}
int height = start[start.Count - 1] - start[0];
int width = img.Width;
if (start[0] + height > img.Height)
height = img.Height - start[0];
Rectangle rect = new Rectangle(0, start[0], img.Width, height + 1);
return img = (Bitmap)recImg.Clone(rect, recImg.PixelFormat);
}
private Bitmap removeInvalidChar(Bitmap image)
{
int count = 0;
List<int> charHist = new List<int>();
Bitmap img = null;
if (image.Height <= 15 || image.Width < 3)
{
charHist = histo.horizontalProjection(image);
for (int d = 0; d < charHist.Count; d++)
{
if (charHist[d] > 0)
{
count++;
}
}
if (count >= 12)
{
img = removeWhiteSpaces(image);
}
}
else
{
img = removeWhiteSpaces(image);
}
return img;
}
This is the GetSpecificArea code snipet
public Bitmap FillImage(Bitmap image, Brush brush)
{
Graphics g = Graphics.FromImage(image);
g.FillRectangle(brush, new Rectangle(0, 0, image.Width, image.Height));
g.Dispose();
return image;
}
public Bitmap GetSpecificAreaOfImage(Rectangle areaFromSourceImage, Bitmap duplicate)
{
Bitmap Picture = new Bitmap(areaFromSourceImage.Width, areaFromSourceImage.Height);
Graphics grPhoto = Graphics.FromImage(Picture);
grPhoto.DrawImage(duplicate, new Rectangle(0, 0, areaFromSourceImage.Width,
areaFromSourceImage.Height), areaFromSourceImage, GraphicsUnit.Pixel);
grPhoto.Dispose();
return Picture;
}
As you can see in the above code snippet i have used a method call
GetSpecificAreaOfImage. This method does is giving you an area in an image as a Bitmap.
Hope this help you in your future work....
if you have any question feel free to ask.
Steve Roziro