[Top] c#Authentication Code Recognition, Picture Binarization, Segmentation, Classification, Recognition

Posted by GFXUniverse on Sat, 20 Jul 2019 21:27:48 +0200

Original Link: http://www.cnblogs.com/riasky/p/3473365.html

The identification of c#Authentication Code is mainly divided into three steps: preprocessing, segmentation and recognition.

First I download the verification code from the website

The results are as follows:



1. Picture preprocessing, that is, binary pictures

*Sets the gray value of the pixel point on the image to 0 or 255.

The principle is as follows:



The code is as follows:

 

#region Binary Picture
        /// <summary>
        ///Binary Picture
        ///is to set the gray value of the pixel point on the image to 0 or 255
        /// </summary>
        /// <returns>Authentication code after processing </returns>
        public Bitmap BinaryZaTion()
        {
            for (int x = 0; x < img.Width; x++)
            {
                for (int y = 0; y < img.Height; y++)
                {
                    __c = img.GetPixel(x, y);
                    //Gray value
                    int __tc = (__c.R + __c.G + __c.B) / 3;
                    //Greater than Que Black
                    if (__tc > t)
                    {
                        img.SetPixel(x, y, Color.FromArgb(__c.A, b, b, b));
                        //Black dots add themselves
                        __blackNum++;
                    }
                    //Greater than Que White
                    else
                    {
                        img.SetPixel(x, y, Color.FromArgb(__c.A, w, w, w));
                    }
                }
            }
            return img;
        }
        #endregion


After binarization, you need to determine the black-to-white ratio of the picture. If there is more black than white, you need to reverse the color of the picture.

 

The code is as follows:

 

 #Whether region needs inversion
        /// <summary>
        ///Need Inversion
        /// </summary>
        /// <returns>Need backcolor </returns>
        public bool IsNeedInverseColor()
        {
            if ((__blackNum * 1.0 / (img.Width * img.Height)) > 0.5)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion

        #region Inversion
        /// <summary>
        ///Inverse color
        /// </summary>
        /// <returns>Authentication code after processing </returns>
        public Bitmap InverseColor()
        {
            for (int x = 0; x < img.Width; x++)
            {
                for (int y = 0; y < img.Height; y++)
                {
                    __c = img.GetPixel(x, y);
                    img.SetPixel(x, y, Color.FromArgb(__c.A, w - __c.R, w - __c.G, w - __c.B));
                }
            }
            return img;
        }
        #endregion


The results are as follows:

 


2. Picture segmentation

My practice is to first determine if each vertical line is a pure white line, not record the current x-coordinate, and then not horizontally determine if it is a pure white line, so you can go to the area of each number and draw the area.

The code is as follows:

 

 #region Split Picture
        /// <summary>
        ///Split Picture
        /// </summary>
        /// <returns>Authentication code after processing </returns>
        public Bitmap CutImg()
        {
            //Y-axis Split
            CutY();
            //Number of Areas
            __count = 0;
            if (XList.Count > 1)
            {
                //x Start Value
                int __start = XList[0];
                //x end value
                int __end = XList[XList.Count - 1];
                //x index
                int __idx = 0;
                while (__start != __end)
                {
                    //Area Width
                    int __w = __start;
                    //Number of Areas Added
                    __count++;
                    while (XList.Contains(__w) && __idx < XList.Count)
                    {
                        //Area Width Adds
                        __w++;
                        //x-index self-addition
                        __idx++;
                    }
                    //Area X-axis coordinates
                    int x = __start;
                    //Area Y-axis coordinates
                    int y = 0;
                    //Area Width
                    int width = __w - __start;
                    //Area Height
                    int height = img.Height;
                    /*
                     * X Axis Split Current Area
                     */
                    CutX(img.Clone(new Rectangle(x, y, width, height), img.PixelFormat));
                    if (YList.Count > 1 && YList.Count != img.Height)
                    {
                        int y1 = YList[0];
                        int y2 = YList[YList.Count - 1];
                        if (y1 != 1)
                        {
                            y = y1 - 1;
                        }
                        height = y2 - y1 + 1;
                    }
                    //GDI+Drawing Objects
                    Graphics g = Graphics.FromImage(img);
                    g.SmoothingMode = SmoothingMode.HighQuality;
                    g.CompositingMode = CompositingMode.SourceOver;
                    g.PixelOffsetMode = PixelOffsetMode.HighSpeed;
                    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    //Draw Authentication Code Area
                    g.DrawRectangle(new Pen(Brushes.Green), new Rectangle(x, y, width, height));
                    g.Dispose();
                    //Start value points to next group
                    if (__idx < XList.Count)
                    {
                        __start = XList[__idx];
                    }
                    else
                    {
                        __start = __end;
                    }

                }
            }
            return img;
        }
        #endregion

        #region Y-axis Character Split Picture
        /// <summary>
        ///Get Y-Axis Split Points
        ///Determine if each vertical line is black
        ///or add
        /// </summary>
        /// <param name="img">Picture to verify </param>
        private void CutY()
        {
            XList.Clear();
            for (int x = 0; x < img.Width; x++)
            {
                isWhilteLine = false;
                for (int y = 0; y < img.Height; y++)
                {
                    __c = img.GetPixel(x, y);
                    if (__c.R == w)
                    {
                        isWhilteLine = true;
                    }
                    else
                    {
                        isWhilteLine = false;
                        break;
                    }
                }
                if (!isWhilteLine)
                {
                    XList.Add(x);
                }
            }
        }
        #endregion

        #region X-axis Character Split Picture
        /// <summary>
        ///Get X-Axis Split Points
        ///Determine if each line is black
        ///or add
        /// </summary>
        /// <param name="tempImg">Temporary area</param>
        private void CutX(Bitmap tempImg)
        {
            YList.Clear();
            for (int x = 0; x < tempImg.Height; x++)
            {
                isWhilteLine = false;
                for (int y = 0; y < tempImg.Width; y++)
                {
                    __c = tempImg.GetPixel(y, x);
                    if (__c.R == w)
                    {
                        isWhilteLine = true;
                    }
                    else
                    {
                        isWhilteLine = false;
                        break;
                    }
                }
                if (!isWhilteLine)
                {
                    YList.Add(x);
                }
            }
            tempImg.Dispose();
        }
        #endregion

 


The results are as follows:


3. Identify

Recognition is extracting the features of a picture

My approach is to divide the digital area of the picture into 4*4 areas one by one, calculate the percentage of black dots in each area, and then compare the calculated results with the previously calculated features to find the minimum Euclidean distance d = sqrt ((x1-x2)^2+ (y1-y2)^2) as the result.

Part of the code is as follows:

 

#region Black Pixel Ratio Column
        /// <summary>
        ///Calculate black pixel ratio column
        /// </summary>
        /// <param name="tempimg"></param>
        /// <returns></returns>
        private double PixlPercent(Bitmap tempimg)
        {
            int temp = 0;
            int w_h = tempimg.Width * tempimg.Height;
            for (int x = 0; x < tempimg.Width; x++)
            {
                for (int y = 0; y < tempimg.Height; y++)
                {
                    __c = tempimg.GetPixel(x, y);
                    if (__c.R == b)
                    {
                        temp++;
                    }
                }
            }
            tempimg.Dispose();
            double result = temp * 1.0 / w_h;
            result = result.ToString().Length > 3 ? Convert.ToDouble(result.ToString().Substring(0, 3)) : result;
            return result;
        }
        #endregion


 

The results are as follows:



This code is for research purposes only.

Novice on the road, contact pigkeli@qq.com for any suggestions or comments.


 

Reprinted at: https://www.cnblogs.com/riasky/p/3473365.html