コード例 #1
0
        /// <summary>
        /// This function checks all sentences if there are components which have an angle
        /// of 90 degrees, if so they will be merged
        /// </summary>
        public static void MergeComponentsInSentences(PageImage Image)
        {
            int           index;
            double        Angle;
            PageComponent Left, Right;

            foreach (Sentence Sentence in Image.Sentences)
            {
                for (index = 0; index < Sentence.Count - 1; index++)
                {
                    Left  = Sentence.Components[index];
                    Right = Sentence.Components[index + 1];

                    if (Left.Type == ePageComponentType.eCharacter &&
                        Right.Type == ePageComponentType.eCharacter)
                    {
                        Angle = PageComponent.AngleBetweenComponents(Left, Right);

                        if (Angle > 88 && Angle < 92)
                        {
                            Left.Merge(Right);
                            Sentence.Delete(index + 1);
                        }
                    }
                }
            }
        }
コード例 #2
0
        /// <summary>
        ///This function takes a to be deleted component and sees whether it could
        ///be a part of another component in the outer sentence. It could be a
        ///dot for example. If so, it will merged.
        /// </summary>
        /// <param name="InnerSentence"></param>
        /// <param name="OuterSentence"></param>
        public static void MergeRectangles(Sentence InnerSentence, Sentence OuterSentence)
        {
            int    MinDistance = 1000;
            int    Distance;
            double BestAngle = 90;
            double Angle;
            double AverageAngle;

            PageComponent InnerComponent;
            PageComponent MergeComponent = null;

            InnerComponent = InnerSentence.Components[0];

            if (InnerComponent.Type != ePageComponentType.eCharacter)
            {
                return;
            }

            AverageAngle = OuterSentence.AverageAngle();

            //we merge two rectangles if:
            //1. the distance between them is the minimum in comparing to other pairs in the sentence
            //2. if the angle between them is the best 90 degress angle in comparision to the average angle

            foreach (PageComponent OuterComponent in OuterSentence.Components)
            {
                Distance = PageComponent.DistanceBetweenComponents(OuterComponent, InnerComponent);

                if (Distance < MinDistance && OuterComponent.Type == ePageComponentType.eCharacter)
                {
                    Angle = PageComponent.AngleBetweenComponents(OuterComponent, InnerComponent);
                    Angle = (Angle % 180) - 90 + AverageAngle;

                    if (Math.Abs(Angle) <= 10)
                    {
                        if (Math.Abs(Angle) <= BestAngle)
                        {
                            //Check if the distance isn't to great, but if the angle is exact 90 degrees always
                            //do a merge.
                            if (Distance <= 3 * Math.Max(OuterComponent.Width, OuterComponent.Height) ||
                                Angle == 0)
                            {
                                BestAngle      = Math.Abs(Angle);
                                MergeComponent = OuterComponent;
                                MinDistance    = Distance;
                            }
                        }
                    }
                }
            }

            if (MergeComponent != null)
            {
                //we found a rectangle with which we can merge
                MergeComponent.Merge(InnerComponent);
            }
        }
コード例 #3
0
ファイル: Sentence.cs プロジェクト: Meusesoft/OCR
        /// <summary>
        /// Returns the average angle between the components in the sentence
        /// </summary>
        /// <returns></returns>
        public double AverageAngle()
        {
            if (m_AverageAngle == -1)
            {
                if (Components.Count > 0)
                {
                    m_AverageAngle = PageComponent.AngleBetweenComponents(Components.First(), Components.Last());
                }
            }

            //int PointerFrom, PointerTo, ComponentCount;

            //if (m_AverageAngle == -1) {

            //    ComponentCount = 0;
            //    m_AverageAngle = 0;

            //    PointerFrom = 0;
            //    PointerTo = 0;

            //    do
            //    {
            //        while (Components[PointerTo].Type == eRectangleType.eSpace && PointerTo < Components.Count)
            //        {
            //            PointerTo++;
            //        }

            //        if (PointerTo < Components.Count)
            //        {
            //            m_AverageAngle += PageComponent.AngleBetweenComponents(Components[PointerFrom], Components[PointerTo]);
            //            ComponentCount++;
            //        }

            //        PointerFrom = PointerTo;
            //        PointerTo++;

            //    } while (PointerTo < Components.Count);

            //    if (ComponentCount > 0)
            //    {
            //        m_AverageAngle = m_AverageAngle / ComponentCount;
            //    }
            //}

            return(m_AverageAngle);
        }
コード例 #4
0
        /// <summary>
        ///This function searches the distance matrix for the closest component
        ///to the given rectangle. The closest component must comply to
        ///the following rules:
        /// * Different from the given component
        /// * Component must not be a part of another sentence
        /// * Must be on the left side of given rectangle (if bLeft is true)
        /// * Must be on the right side of given rectangle (if bLeft is false)
        /// * Angle between rectangle and given rectangle must be less than 5 degrees
        /// </summary>
        /// <param name="Sentence"></param>
        /// <param name="CurrentComponent"></param>
        /// <param name="m_Areas"></param>
        /// <param name="Angle"></param>
        /// <param name="Left"></param>
        /// <returns></returns>

        public static PageComponent FindNearestComponent(Sentence Sentence, PageComponent CurrentComponent, List <DetectionArea> m_Areas, float Angle, bool Left)
        {
            int MinDistance;
            int Distance;

            MinDistance = 2000;

            PageComponent BestCandidate = null;

            int           CurrentAreaIndex;
            DetectionArea Area;


            double AverageAngle       = Sentence.AverageAngle();
            int    MaxAllowedDistance = (int)(Sentence.AverageHeight() * 1.5);
            int    AreaIndex          = CurrentComponent.DetectionAreaIndex;

            for (int Index = 0; Index < 6; Index++)
            {
                //the Index is converted to an area number according to the
                //matrix below. The start point is the center area (lIndex = 2).
                //lIndex 3 is on the left when bleft = true or on the right when bleft = false

                //  *************
                //  * 1 * 0 * 1 *
                //  *************
                //  * 3 * 2 * 3 *
                //  *************
                //  * 5 * 4 * 5 *
                //  *************

                CurrentAreaIndex = AreaIndex;

                //translate the lIndex to the x axis of the areas
                if ((Index & 1) != 0)
                {
                    if (Left)
                    {
                        CurrentAreaIndex--;
                    }
                    else
                    {
                        CurrentAreaIndex++;
                    }
                }

                //translate the Index to the y axis of the areas
                CurrentAreaIndex += ((Index / 2) - 1) * NumberAreasX;

                //the current area number must ly within boundaries (0, number areas)
                //no throw here if it is outside the boundaries because when the area
                //lies on the edge of the image this algorithm will try to go further
                if (CurrentAreaIndex >= 0 && CurrentAreaIndex < m_Areas.Count)
                {
                    Area = m_Areas[CurrentAreaIndex];

                    //loop through all the rectangles in the area
                    foreach (PageComponent Candidate in Area.Components)
                    {
                        if (Candidate.Type == ePageComponentType.eCharacter)
                        {
                            //Candidate neighbour must be on left/right side
                            if ((Left && Candidate.Area.X < CurrentComponent.Area.X) ||
                                (!Left && Candidate.Area.X > CurrentComponent.Area.X))
                            {
                                Distance = PageComponent.DistanceBetweenComponents(CurrentComponent, Candidate);

                                //Distance must be between current minimum and Maximum allowed
                                if (MinDistance > Distance && MaxAllowedDistance > Distance)
                                {
                                    //Angle between rectangle and sentence must be less than 5 degrees
                                    if (PageComponent.AngleBetweenComponents(CurrentComponent, Candidate) < 5 ||
                                        (Sentence.Area.Bottom > Candidate.Area.Top && Sentence.Area.Top < Candidate.Area.Top) ||
                                        (Sentence.Area.Bottom > Candidate.Area.Bottom && Sentence.Area.Top > Candidate.Area.Bottom))
                                    {
                                        BestCandidate = Candidate;
                                        MinDistance   = Distance;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (BestCandidate != null)
            {
                m_Areas[BestCandidate.DetectionAreaIndex].Components.Remove(BestCandidate);
            }


            return(BestCandidate);
        }