예제 #1
0
        static void Mark_ShortBones(List <BoneGroup> boneGroups)
        {
            int boneGroupsCount = boneGroups.Count;

            if (boneGroupsCount < 2)
            {
                return;
            }
            //----------------------
            //use median ?,
            boneGroups.Sort((bg0, bg1) => bg0.approxLength.CompareTo(bg1.approxLength));
            int groupCount = boneGroups.Count;
            //median
            int       mid_index   = groupCount / 2;
            BoneGroup bonegroup   = boneGroups[mid_index];
            float     lower_limit = bonegroup.approxLength / 2;

            for (int i = 0; i < mid_index; ++i)
            {
                //from start to mid_index => since the list is sorted

                bonegroup = boneGroups[i];
                if (bonegroup.approxLength < lower_limit)
                {
                    bonegroup._lengKind = BoneGroupSumLengthKind.Short;
                }
                else
                {
                    //since to list is sorted
                    break;
                }
            }
        }
예제 #2
0
        static void Mark_LongBones(List <BoneGroup> boneGroups)
        {
            int boneGroupsCount = boneGroups.Count;

            if (boneGroupsCount == 0)
            {
                return;
            }
            else if (boneGroupsCount == 1)
            {
                //eg 1 group
                //makr this long bone
                boneGroups[0]._lengKind = BoneGroupSumLengthKind.Long;
                return;
            }
            else
            {
                //----------------------
                //use median ?,
                boneGroups.Sort((bg0, bg1) => bg0.approxLength.CompareTo(bg1.approxLength));
                int groupCount = boneGroups.Count;
                //median
                int       mid_index         = groupCount / 2;
                BoneGroup bonegroup         = boneGroups[mid_index];
                float     upper_limit       = bonegroup.approxLength * 2;
                bool      foundSomeLongBone = false;
                for (int i = groupCount - 1; i >= mid_index; --i)
                {
                    //from end to mid_index => since the list is sorted
                    bonegroup = boneGroups[i];
                    if (bonegroup.approxLength > upper_limit)
                    {
                        foundSomeLongBone   = true;
                        bonegroup._lengKind = BoneGroupSumLengthKind.Long;
                    }
                    else
                    {
                        //since to list is sorted
                        break;
                    }
                }
                //----------------------
                if (!foundSomeLongBone)
                {
                    for (int i = groupCount - 1; i >= mid_index; --i)
                    {
                        boneGroups[i]._lengKind = BoneGroupSumLengthKind.Long;
                    }
                }
            }
        }
예제 #3
0
        public void CollectBoneGroups(CentroidLine line)
        {
            //
            _tmpBoneGroups.Clear();
            line.ApplyGridBox(_tmpBoneGroups, _gridBoxW, _gridBoxH);
            //
            for (int i = _tmpBoneGroups.Count - 1; i >= 0; --i)
            {
                //this version, we focus on horizontal bone group
                BoneGroup boneGroup = _tmpBoneGroups[i];
                switch (boneGroup.slopeKind)
                {
                case LineSlopeKind.Horizontal:
                    _selectedHorizontalBoneGroups.Add(boneGroup);
                    break;

                case LineSlopeKind.Vertical:
                    _selectedVerticalBoneGroups.Add(boneGroup);
                    break;
                }
            }
            _tmpBoneGroups.Clear();
        }
예제 #4
0
        /// <summary>
        /// adjust vertical fitting value
        /// </summary>
        void ReCalculateFittingValues()
        {
            //(1)
            //clear all prev adjust value
            for (int i = _contours.Count - 1; i >= 0; --i)
            {
                List <Vertex> pnts = _contours[i].flattenPoints;
                for (int m = pnts.Count - 1; m >= 0; --m)
                {
                    pnts[m].ResetFitAdjustValues();
                }
            }

            //adjust the value when we move to new pixel scale (pxscale)
            //if we known adjust values for that pxscale before( and cache it)
            //we can use that without recalculation

            //--------------------
            //(2)
            //select Horizontal BoneGroups for Vertical fitting:
            //for veritical fitting, we apply fitting value to each group.
            //each group may not need the same value.
            //--------------------
            List <BoneGroup> selectedHBoneGroups = _groupingHelper.SelectedHorizontalBoneGroups;

            for (int i = selectedHBoneGroups.Count - 1; i >= 0; --i)
            {
                BoneGroup boneGroup = selectedHBoneGroups[i];
                if (boneGroup._lengKind == BoneGroupSumLengthKind.Short)
                {
                    continue;
                }
                EdgeLine[] h_edges = boneGroup.edges;
                if (h_edges == null)
                {
                    continue;
                }
                //
                int edgeCount = h_edges.Length;
                //we need to calculate the avg of the glyph point
                //and add a total summary to this
                FitDiffCollector y_fitDiffCollector = new FitDiffCollector();
                float            groupLen           = boneGroup.approxLength;
                //
                for (int e = edgeCount - 1; e >= 0; --e)
                {
                    EdgeLine ee = h_edges[e];
                    //p
                    y_fitDiffCollector.Collect(MyMath.CalculateDiffToFit(ee.P.Y * _pxScale), groupLen);
                    //q
                    y_fitDiffCollector.Collect(MyMath.CalculateDiffToFit(ee.Q.Y * _pxScale), groupLen);
                }

                float avg_ydiff = y_fitDiffCollector.CalculateProperDiff();

                for (int e = edgeCount - 1; e >= 0; --e)
                {
                    //TODO: review here again
                    EdgeLine ee = h_edges[e];
                    ee.P.FitAdjustY = avg_ydiff; //assign px scale specific fit value
                    ee.Q.FitAdjustY = avg_ydiff; //assign px scale specific fit value
                }
            }
            //---------------------------------------------------------
            //(3)
            //vertical group for horizontal fit:
            //this different from the vertical fitting.
            //we calculate the value as a whole.
            //and apply it as a whole in later state
            List <BoneGroup> verticalGroups     = _groupingHelper.SelectedVerticalBoneGroups;
            FitDiffCollector x_fitDiffCollector = new FitDiffCollector();

            int j = verticalGroups.Count;

            for (int i = 0; i < j; ++i)
            {
                //1. the verticalGroup list is sorted, left to right
                //2. analyze in order left-> right

                BoneGroup boneGroup = verticalGroups[i];
                if (boneGroup._lengKind != BoneGroupSumLengthKind.Long)
                {
                    //in this case we focus on long-length bone group only
                    continue;
                }
                EdgeLine[] v_edges = boneGroup.edges;
                if (v_edges == null)
                {
                    continue;
                }

                int edgeCount = v_edges.Length;
                //we need to calculate the avg of the glyph point
                //and add a total summary to this
                float groupLen = boneGroup.approxLength;
                for (int e = 0; e < edgeCount; ++e)
                {
                    EdgeLine ee = v_edges[e];
                    //TODO: review this
                    //if (ee.IsLeftSide)
                    //{
                    //focus on leftside edge
                    //p
                    x_fitDiffCollector.Collect(MyMath.CalculateDiffToFit(ee.P.X * _pxScale), groupLen);
                    //q
                    x_fitDiffCollector.Collect(MyMath.CalculateDiffToFit(ee.Q.X * _pxScale), groupLen);
                    //}
                }
                //TODO: review here ***
                break; //only left most first long group ?
            }
            //(4)
            _avg_x_fitOffset = x_fitDiffCollector.CalculateProperDiff();
        }
예제 #5
0
        /// <summary>
        /// apply grid box to all bones in this line
        /// </summary>
        /// <param name="gridW"></param>
        /// <param name="gridH"></param>
        public void ApplyGridBox(List <BoneGroup> boneGroups, int gridW, int gridH)
        {
            //1. apply grid box to each joint
            for (int i = _joints.Count - 1; i >= 0; --i)
            {
                _joints[i].AdjustFitXY(gridW, gridH);
            }
            //2. (re) calculate slope for all bones.
            for (int i = bones.Count - 1; i >= 0; --i)
            {
                bones[i].EvaluateSlope();
            }
            //3. re-grouping
            int       j         = bones.Count;
            BoneGroup boneGroup = new BoneGroup(this); //new group

            boneGroup.slopeKind = LineSlopeKind.Other;
            //
            float approxLen = 0;
            float ypos_sum  = 0;
            float xpos_sum  = 0;

            for (int i = 0; i < j; ++i)
            {
                Bone          bone    = bones[i];
                LineSlopeKind slope   = bone.SlopeKind;
                Vector2f      mid_pos = bone.GetMidPoint();

                if (slope != boneGroup.slopeKind)
                {
                    //add existing to list and create a new group
                    if (boneGroup.count > 0)
                    {
                        //add existing bone group to bone-group list
                        boneGroup.approxLength = approxLen;
                        boneGroup.avg_x        = xpos_sum / boneGroup.count;
                        boneGroup.avg_y        = ypos_sum / boneGroup.count;
                        //
                        boneGroups.Add(boneGroup);
                    }
                    //
                    boneGroup            = new BoneGroup(this);
                    boneGroup.startIndex = i;
                    boneGroup.slopeKind  = slope;
                    //
                    boneGroup.count++;
                    approxLen = bone.EvaluateFitLength(); //reset
                    //
                    xpos_sum = mid_pos.X;
                    ypos_sum = mid_pos.Y;
                }
                else
                {
                    boneGroup.count++;
                    approxLen += bone.EvaluateFitLength(); //append
                    //
                    xpos_sum += mid_pos.X;
                    ypos_sum += mid_pos.Y;
                }
            }
            //
            if (boneGroup.count > 0)
            {
                boneGroup.approxLength = approxLen;
                boneGroup.avg_x        = xpos_sum / boneGroup.count;
                boneGroup.avg_y        = ypos_sum / boneGroup.count;
                boneGroups.Add(boneGroup);
            }
        }