如何对手写图像进行图像分割 [英] How to do the image segmentation for handwriting image

查看:143
本文介绍了如何对手写图像进行图像分割的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,我对这种图像处理概念非常陌生.我正在尝试做一个示例项目,该方法如何识别图像中的马来字符.我卡在行和字符分割中.如果有人可以帮助我,那么此示例代码将非常有用.


再次感谢,
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

推荐答案

我假设您正在执行与OCR相关的项目.进行图像分割的方法有很多.在图像分割中,您需要确定图像的上下边界.这是线段的代码.您可以进一步优化它.....

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;
        }



这是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


这篇关于如何对手写图像进行图像分割的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆