/// <summary>
        /// 根据两条分割路径获取已分割路径之间区域的如下信息:
        /// 1.两个路径之间包含的有效字符的像素点数(黑色像素的数量)
        /// 2.已分割区域的与baseline的交点
        /// 3.已分割区域的与meanine的交点
        /// 4.已分割区域的最高点(离原点最远的,X坐标较大值)
        /// 5.已分割区域的最低点(离原地最低点,X坐标较小值)
        /// </summary>
        public static SegAreaInfo GetSegInfo(ArrayList pathLeft, ArrayList pathRight)
        {
            //遍历两条路径之间的区域用
            Point posRight = new Point();
            Point posLeft = new Point();

            int widthRight = 0;
            int widthLeft = 0;

            int heightRight = 0;
            int heightLeft = 0;

            int indexLeft = 0;
            int indexRight = 0;

            int posCountLeft = 0;
            int posCountRight = 0;

            int bPixCount = 0;

            SegAreaInfo segArea = new SegAreaInfo();

            Boundary tmpBoundary = new Boundary();

            //用于存储已分割区域的二值化数组
            Byte[,] binaryArr = new Byte[ImageHeight, ImageWidth];

            for(int m = 0; m < ImageHeight; m++)
            {
                for (int n = 0; n < ImageWidth;n ++ )
                {
                    binaryArr[m, n] = 255;
                }
            }

            bPixCount = 0;

            posCountLeft = pathLeft.Count;
            posCountRight = pathRight.Count;

            indexLeft = 0;
            indexRight = 0;

            //两条路径之间的点数可能不一致,可能会出现同一个X值对应多个Y值的状况
            while ((indexLeft < posCountLeft) && (indexRight < posCountRight))
            {
                posRight = (Point)pathRight[indexRight];
                posLeft = (Point)pathLeft[indexLeft];

                indexLeft++;
                indexRight++;

                widthLeft = posLeft.Y;
                widthRight = posRight.Y;

                heightRight = posLeft.X;
                heightLeft = posRight.X;

                //路径中可能会出现多个宽度值对应同一高度值的状况,找到同一高度值下最左侧的宽度值
                while (indexLeft < posCountLeft)
                {
                    posLeft = (Point)pathLeft[indexLeft];

                    if (widthLeft != posLeft.X)
                    {
                        break;
                    }
                    else
                    {
                        if (widthLeft > posLeft.Y)
                        {
                            widthLeft = posLeft.Y;
                        }
                        indexLeft++;
                    }
                }

                //路径中可能会出现多个宽度值对应同一高度值的状况,找到同一高度值下最右侧的宽度值
                while (indexRight < posCountRight)
                {
                    posRight = (Point)pathRight[indexRight];

                    if (heightRight != posRight.X)
                    {
                        break;
                    }
                    else
                    {
                        if (widthRight < posRight.Y)
                        {
                            widthRight = posRight.Y;
                        }
                        indexRight++;
                    }
                }

                //从左至右,从上至下,遍历两条路径之间的像素点
                for (Int32 y = widthLeft; y < widthRight; y++)
                {
                    binaryArr[heightLeft, y] = BinaryArray[heightLeft, y];
                                  
                    if (0 == BinaryArray[heightLeft, y])
                    {
                        //将两条路径之间的有效像素点的总数
                        bPixCount++;
                    }
                }                  
            }

            tmpBoundary = Preprocess.Preprocess.getImgBoundary(ImageHeight, ImageWidth, binaryArr);

            segArea.blackPixCount = bPixCount;

            segArea.segAreaB = tmpBoundary;

            segArea.binaryArr = binaryArr;

            return segArea;
        }
        /// <summary>
        ///根据粘连区域与Guideline的关系对粘连区域进行分割
        /// </summary>
        /// <param name="mergedArea">粘连区域的信息</param>
        /// <param name="newPos">此次分割得到的路径在总路径中的位置</param>
        /// <param name="num">当前粘连区域包含的字符数</param>
        public static void SegByGuideLine(SegAreaInfo mergedArea, int newPos, int num)
        {
            //循环用变量
            int k = 0;  //SegAreaInfo

            Boundary mBoundary = mergedArea.segAreaB;

            //当前粘连区域粘连字符宽度判定阈值
            int thVal = (mBoundary.rightUpPoint.Y - mBoundary.leftDownPoint.Y) / (num + 1);

            int bThVal = mergedArea.blackPixCount / (num + 2);

            Point segP = new Point();

            ArrayList pathListA = new ArrayList();

            ArrayList pathListB = new ArrayList();

            //用于标注占据三格的字符根据meanline分割的路径是否为有效路径
            bool bValid = false;

            //获取当前粘连区域在meanline之上区域的竖直投影
            // Point point1 = new Point();

            //获取meanline以上区域竖直投影的右上角的点
            segP.X = GuidePoint.Y;
            segP.Y = mBoundary.rightUpPoint.Y;
            VerPro meanArr = Preprocess.Preprocess.VerticalProjection(mBoundary.leftDownPoint, segP, 2, mergedArea.binaryArr);
            int mCount = meanArr.vRange.Count;

            segP.X = GuidePoint.X;
            segP.Y = mBoundary.leftDownPoint.Y;
            VerPro baseArr = Preprocess.Preprocess.VerticalProjection(segP, mBoundary.rightUpPoint, 1, mergedArea.binaryArr);
            int bCount = baseArr.vRange.Count;

            segP.X = GuidePoint.Y;
            segP.Y = mBoundary.leftDownPoint.Y;
            Point tmpPoint = new Point();
            tmpPoint.X = GuidePoint.X;
            tmpPoint.Y = mBoundary.rightUpPoint.Y;
            VerPro midArr = Preprocess.Preprocess.VerticalProjection(segP, tmpPoint, 0, mergedArea.binaryArr);
            int midCount = midArr.vRange.Count;

            //以GuideLine作为分割依据主要是粘连区域占据四线三格中格数的状况         
            if ((mCount > 0) && (bCount > 0))
            {
                //1.若占据三格,则meanline与粘连区域的左侧交点若不位于边界线,则将其作为一个分割点进行分割
                if (meanArr.vInter.X > (mBoundary.leftDownPoint.Y + thVal))
                {
                    segP.X = GuidePoint.Y;
                    segP.Y = meanArr.vInter.X;

                    bValid = SegByMeanLeft(segP, meanArr, mBoundary, bThVal, newPos);
                }

                //若meanline区域分割无效,或者meanline无有效分割点,将以baseline为分割依据
                //取baseline与字符在左侧的第一个交点,若该交点不位于边界,则以该点为分割点
                //若该点位于边界,则以baseline和字符在右侧的第一个交点为分割点
                if ((!bValid) && (baseArr.vInter.X > (mBoundary.leftDownPoint.Y + thVal)))
                {
                    segP.X = GuidePoint.X;
                    segP.Y = baseArr.vInter.X;

                    bValid = SegByBaseLine(segP, meanArr, mBoundary, bThVal, newPos, true);
                }

                //若baseline与meanline的左侧交点均未得到有效分割线,则以baseline和meanline的右侧交点来进行分割  
                //以meanline的右侧交点为分割点
                if ((!bValid) && (meanArr.vInter.Y < (mBoundary.rightUpPoint.Y - thVal)))
                {
                    segP.X = GuidePoint.Y;
                    segP.Y = meanArr.vInter.Y;

                    bValid = SegByMeanRight(segP, meanArr, mBoundary, bThVal, newPos);
                }

                //以baseline的右侧交点为分割点
                if ((!bValid) && (baseArr.vInter.Y < (mBoundary.leftDownPoint.Y - thVal)))
                {
                    segP.X = GuidePoint.X;
                    segP.Y = baseArr.vInter.Y;

                    bValid = SegByBaseLine(segP, meanArr, mBoundary, bThVal, newPos, false);
                }

                //理论上而言,经过上述几项分割后,应该会得到一条有效路径,若仍未得到有效路径,将考虑用投影特征来分割,目前暂不处理此状况

            }
            else if ((mCount > 0) && (0 == bCount))
            {
                //目前粘连区域位于baseline以上的两个格
                //1.若meanline以上区域位于右侧区域,则以meanline与字符的左侧交点为分割点
                if (meanArr.vInter.X > (mBoundary.leftDownPoint.Y + thVal))
                {
                    segP.X = GuidePoint.Y;
                    segP.Y = meanArr.vInter.X;

                    bValid = SegByMeanLeft(segP, meanArr, mBoundary, bThVal, newPos);
                }

                //2.若meanline以上区域位于左侧区域,则以meanline与字符的右侧交点为分割点
                if ((!bValid) && (meanArr.vInter.Y < (mBoundary.rightUpPoint.Y - thVal)))
                {
                    segP.X = GuidePoint.Y;
                    segP.Y = meanArr.vInter.Y;

                    bValid = SegByMeanRight(segP, meanArr, mBoundary, bThVal, newPos);
                }

                //3.若上述两个条件均不成立,则以竖直投影为分割依据
                thVal = (mBoundary.rightUpPoint.Y + mBoundary.leftDownPoint.Y) / 2;
                //3.1 meanline以上区域粘连,以下区域分割,则以其分割区域靠近中间的投影点作为分割点
                if (!bValid)
                {
                    if ((1 == mCount) && (midCount > 1))
                    {
                        segP = (Point)midArr.vRange[0];
                        tmpPoint = (Point)midArr.vRange[1];

                        if (Math.Abs(thVal - segP.Y) < Math.Abs(thVal - tmpPoint.X))
                        {
                            Point pt1 = new Point();

                            pt1.X = GuidePoint.Y;
                            pt1.Y = segP.Y;

                            pathListA = dropFallUp(pt1);

                            pathListB = dropFallDown(pt1);
                        }
                        else
                        {
                            Point pt1 = new Point();
                            pt1.X = GuidePoint.Y;
                            pt1.Y = tmpPoint.X;

                            pathListA = dropFallUp(pt1);

                            pathListB = dropFallDown(pt1);
                        }
                    }
                    else if ((1 == midCount) && (mCount > 1))
                    {
                        //3.2 meanline以上区域分割,以下区域粘连,则以其分割区域靠近中间的投影点作为分割点
                        segP = (Point)meanArr.vRange[0];
                        tmpPoint = (Point)meanArr.vRange[1];

                        if (Math.Abs(thVal - segP.Y) < Math.Abs(thVal - tmpPoint.X))
                        {
                            Point pt1 = new Point();

                            pt1.X = GuidePoint.Y;
                            pt1.Y = segP.Y;

                            pathListA = dropFallUp(pt1);

                            pathListB = dropFallDown(pt1);
                        }
                        else
                        {
                            Point pt1 = new Point();
                            pt1.X = GuidePoint.Y;
                            pt1.Y = tmpPoint.X;

                            pathListA = dropFallUp(pt1);

                            pathListB = dropFallDown(pt1);
                        }
                    }
                    else
                    {
                        //3.3 上下均粘连,则暂不处理
                    }
                    if ((pathListA.Count > 0) && (pathListB.Count > 0))
                    {
                        for (k = 0; k < pathListA.Count; k++)
                        {
                            pathListB.Add(pathListA[k]);
                        }
                        SegPathList.Insert(newPos, pathListB);

                        bValid = true;
                    }

                }
            }
            else if ((0 == mCount) && (bCount > 0))
            {
                //目前粘连区域位于meanline以下的两个格
                //若baseline以下区域位于粘连区域的右侧,则以baseline和字符在左侧的交点为分割点
                if ((!bValid) && (baseArr.vInter.X > (mBoundary.leftDownPoint.Y + thVal)))
                {
                    segP.X = GuidePoint.X;
                    segP.Y = baseArr.vInter.X;

                    bValid = SegByBaseLine(segP, meanArr, mBoundary, bThVal, newPos, true);
                }

                //若baseline以下区域位于粘连区域的左侧,则以baseline和字符在右侧的交点为分割点
                if ((!bValid) && (baseArr.vInter.Y < (mBoundary.rightUpPoint.Y - thVal)))
                {
                    segP.X = GuidePoint.X;
                    segP.Y = baseArr.vInter.Y;

                    bValid = SegByBaseLine(segP, meanArr, mBoundary, bThVal, newPos, false);
                }

                //3.若上述两个条件均不成立,则以竖直投影为分割依据
                if (!bValid)
                {
                    //3.1 baseline以上区域粘连,以下区域分割,则以其分割区域靠近中间的投影点作为分割点
                    //3.2 baseline以上区域分割,以下区域粘连,则以其分割区域靠近中间的投影点作为分割点
                    //3.3 上下均粘连,则暂不处理
                    //3.若上述两个条件均不成立,则以竖直投影为分割依据
                    thVal = (mBoundary.rightUpPoint.Y + mBoundary.leftDownPoint.Y) / 2;
                    //3.1 meanline以上区域粘连,以下区域分割,则以其分割区域靠近中间的投影点作为分割点
                    if (!bValid)
                    {
                        if ((1 == bCount) && (midCount > 1))
                        {
                            segP = (Point)midArr.vRange[0];
                            tmpPoint = (Point)midArr.vRange[1];

                            if (Math.Abs(thVal - segP.Y) < Math.Abs(thVal - tmpPoint.X))
                            {
                                segP.X = GuidePoint.X;
                                pathListA = dropFallUp(segP);

                                pathListB = dropFallDown(segP);
                            }
                            else
                            {
                                tmpPoint.X = GuidePoint.X;
                                pathListA = dropFallUp(tmpPoint);

                                pathListB = dropFallDown(tmpPoint);
                            }
                        }
                        else if ((1 == midCount) && (bCount > 1))
                        {
                            //3.2 meanline以上区域分割,以下区域粘连,则以其分割区域靠近中间的投影点作为分割点
                            segP = (Point)baseArr.vRange[0];
                            tmpPoint = (Point)baseArr.vRange[1];

                            if (Math.Abs(thVal - segP.Y) < Math.Abs(thVal - tmpPoint.X))
                            {
                                pathListA = dropFallUp(segP);

                                pathListB = dropFallDown(segP);
                            }
                            else
                            {
                                pathListA = dropFallUp(tmpPoint);

                                pathListB = dropFallDown(tmpPoint);
                            }
                        }
                        else
                        {
                            //3.3 上下均粘连,则暂不处理
                        }

                        for (k = 0; k < pathListA.Count; k++)
                        {
                            pathListB.Add(pathListA[k]);
                        }

                      //  pathListA = (ArrayList)SegPathList[newPos - 1];

                      //  SegAreaInfo tmpInfo = GetSegInfo(pathListA, pathListB);
                       // SegAreaList.Add(tmpInfo);
                        SegPathList.Insert(newPos, pathListB);

                        bValid = true;
                    }
                }
                else
                {
                    //目前粘连区域位于中间一格,暂不处理
                }
            }
        }
        public static bool SegByBaseLine(Point segP, VerPro baseArr, Boundary mBoundary, int bThVal, int newPos, bool bLeft)
        {
            bool bValid = false;

            //以交点为起点分别执行向上滴落和向下滴落
            ArrayList pathListA = dropFallUp(segP);

            ArrayList pathListB = dropFallDown(segP);

            SegAreaInfo tmpInfo = new SegAreaInfo();

            int k = 0;

            for (k = 0; k < pathListA.Count; k++)
            {
                pathListB.Add(pathListA[k]);
            }

            //按字符的规则而言,符合该条件的可能是字符y,j,那么分割完成后,左侧区域有一定几率没有有效字符
            //确认按照该规则分割出的左侧区域是否包含有效字符像素
            pathListA.Clear();

            //当前粘连区域左侧竖线作为判断基准
            if (bLeft)
            {
                for (k = mBoundary.leftDownPoint.X; k < mBoundary.rightUpPoint.X; k++)
                {
                    Point tmpP = new Point();

                    tmpP.X = k;
                    tmpP.Y = mBoundary.leftDownPoint.Y;

                    pathListA.Add(tmpP);
                }

                tmpInfo = GetSegInfo(pathListA, pathListB);
            }
            else
            {
                for (k = mBoundary.leftDownPoint.X; k < mBoundary.rightUpPoint.X; k++)
                {
                    Point tmpP = new Point();

                    tmpP.X = k;
                    tmpP.Y = mBoundary.rightUpPoint.Y;

                    pathListA.Add(tmpP);
                }

                tmpInfo = GetSegInfo(pathListB, pathListA);
            }

            if (tmpInfo.blackPixCount > bThVal)//当前分割路径为有效路径
            {
                //SegAreaList.Add(tmpInfo);
                SegPathList.Insert(newPos, pathListB);

                bValid = true;
            }

            return bValid;
        }
        /// <summary>
        ///根据loop分割后的区块判断是否还有粘连字符,若有则根据guideLine原则继续分割
        /// </summary>
        public static void GetMergedArea()//divideInfo divideData, Point guideLine, Byte[,] BinaryArray, ImgBoundary Boundary)
        {
            int areaNum = SegAreaList.Count;

            //记录单个粘连区域内独立有效的竖直投影区域
            ArrayList proLoops = new ArrayList();

            //记录当前粘连区域的Y轴范围
            SegAreaInfo mAreaRange = new SegAreaInfo();
            SegAreaInfo mAreaRange_1 = new SegAreaInfo();
            SegAreaInfo mAreaRange_2 = new SegAreaInfo();
           
            //记录不同区块的黑色像素数,用于辅助判断粘连字符区域
            int blackCount_0 = 0;
            int blackCount_1 = 0;
            int blackCount_2 = 0;

            //记录当前验证码图片中单个字符的平均像素
            int bThVal = bPixSum / 4; 

           // int newPathPos = 0;//记录新的分割路径该插入的位置

            switch (areaNum)
            {
                case 1://当前验证码仍有4个字符粘连

                    mAreaRange = (SegAreaInfo)SegAreaList[0];

                    SegByGuideLine(mAreaRange, 1, 4);

                    break;

                case 2://当前验证码有3个字符粘连与1个分割完成的字符;或者2个字符与2个字符粘连
                    //根据两个区域的黑色像素数来判断哪个区块为粘连区
                    mAreaRange = (SegAreaInfo)SegAreaList[0];

                    blackCount_0 = mAreaRange.blackPixCount;

                    mAreaRange_1 = (SegAreaInfo)SegAreaList[1];

                    blackCount_1 = mAreaRange_1.blackPixCount;

                    if (blackCount_0 > (2 * bThVal + bThVal / 2))//dArray[0]为3个字符粘连区域
                    {
                        SegByGuideLine(mAreaRange, 1, 3);
                    }
                    else if (blackCount_1 > (2 * bThVal + bThVal / 2))//dArray[1]为3个字符粘连区域
                    {
                        SegByGuideLine(mAreaRange_1, 2, 3);
                    }
                    else
                    {
                        SegByGuideLine(mAreaRange, 1, 2);
                    }

                    break;

                case 3://当前验证码有2个字符粘连与2个独立字符,根据区域黑色像素数来找出粘连区
                    mAreaRange = (SegAreaInfo)SegAreaList[0];

                    blackCount_0 = mAreaRange.blackPixCount;

                    mAreaRange_1 = (SegAreaInfo)SegAreaList[1];

                    blackCount_1 = mAreaRange_1.blackPixCount;

                    mAreaRange_2 = (SegAreaInfo)SegAreaList[2];

                    blackCount_2 = mAreaRange_2.blackPixCount;

                    if ((blackCount_0 > blackCount_1) && (blackCount_0 > blackCount_2))//dArray[0]为2个字符粘连区域
                    {
                        SegByGuideLine(mAreaRange,1, 2);
                    }
                    else if ((blackCount_1 > blackCount_0) && (blackCount_1 > blackCount_2))//dArray[1]为2个字符粘连区域
                    {
                        SegByGuideLine(mAreaRange_1, 2, 2);
                    }
                    else
                    {
                        SegByGuideLine(mAreaRange_2, 3, 2);
                    }
                 
                    break;

                default:
                    break;
            }

        }