问题描述
大家好,我对这种图像处理概念非常陌生.我正在尝试做一个示例项目,该方法如何识别图像中的马来字符.我卡在行和字符分割中.如果有人可以帮助我,那么此示例代码将非常有用.
再次感谢,
Ganesh Ramasamy
Hi guys I''m very new to this image processing concept. I was trying to do a sample project how to recognize malayan characters in an image. Im stuck in line and character segmentation. If some one can help me this sample code would be greate.
Thanks again,
Ganesh Ramasamy
推荐答案
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);
//getSpecific.FillImage(newLine, Brushes.Black);
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);
// getSpecific.FillImage(newCharactor, Brushes.Black);
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;
}
这是GetSpecificArea代码片段
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;
}
如您在上面的代码片段中所看到的,我已经使用了一个方法调用 GetSpecificAreaOfImage .此方法的作用是为您提供图像中的某个区域作为位图.
希望这对您的未来工作有所帮助....
如果您有任何疑问,请随时提出.
史蒂夫·罗兹罗(Steve Roziro)
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
这篇关于如何对手写图像进行图像分割的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!