Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C# ImageProcessing , +
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
Posted 6-Jul-12 21:39pm

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

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);
                    //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;
        }
 
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
  Permalink  
v4
Comments
alsaidi52 at 16-Jul-12 22:42pm
   
Can I find this code in Matlab to make character segmentation?
Member 10407815 at 8-Dec-13 14:33pm
   
i have try this in vb, but its seem doesn't work correctly....
 
it can't cropped a single character i have input, may i do wrong??
Member 10407815 at 8-Dec-13 14:39pm
   
there i need to know what inside of function PixelCheck(), Recognize(), and function InlineAssignHelper()....tank you, i need the solution...
Member 3789365 at 17-Jul-14 10:04am
   
Hi, can you please let me know how these objects are being declared ???
histogramCreation histo = new histogramCreation();
getSpecificArea getSpecific = new getSpecificArea();

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 290
1 Jochen Arndt 150
2 Kornfeld Eliyahu Peter 149
3 PIEBALDconsult 110
4 Richard MacCutchan 105
0 OriginalGriff 6,080
1 DamithSL 4,648
2 Maciej Los 4,087
3 Kornfeld Eliyahu Peter 3,624
4 Sergey Alexandrovich Kryukov 3,294


Advertise | Privacy | Mobile
Web03 | 2.8.141220.1 | Last Updated 7 Jul 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100