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; } } }
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; } } } }
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(); }
/// <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(); }
/// <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); } }