Exemplo n.º 1
0
        public void run(List <SketchStroke> sample)
        {
            List <Tuple <string, double> > results = new List <Tuple <string, double> >();

            List <SketchStroke> normalizedSample = SketchPreprocessing.Normalize(sample, N, Size, Origin);

            foreach (KeyValuePair <string, Sketch> entry in this.Templates)
            {
                List <SketchStroke> templateStrokes    = entry.Value.Strokes;
                List <SketchStroke> normalizedTemplate = SketchPreprocessing.Normalize(templateStrokes, N, Size, Origin);

                double d1       = SketchTools.HausdorffDistance(normalizedSample, normalizedTemplate);
                double d2       = SketchTools.Distance(normalizedTemplate, normalizedSample);
                double distance = d1 < d2 ? d1 : d2;

                results.Add(new Tuple <string, double>(entry.Key, distance));
            }

            results.Sort((x, y) => y.Item2.CompareTo(x.Item2));

            labels = new List <string>();
            scores = new List <double>();

            for (int i = 0; i < results.Count; i++)
            {
                string label = results[i].Item1;
                double score = results[i].Item2;

                labels.Add(label);
                scores.Add(score);
            }
        }
Exemplo n.º 2
0
 private void LoadQuestion(int questionIndex)
 {
     this.currentQuestion              = this.questions[questionIndex];
     this.InstructionTextBlock.Text    = this.currentQuestion.Text;
     this.currentTemplateSketch        = this.strokeTemplates[this.currentQuestion.Answer];
     this.currentTemplateSketchStrokes = SketchPreprocessing.ScaleToFrame(currentTemplateSketch, writingFrameLength);
     this.LoadTemplateImage(this.currentQuestion.Answer);
     InteractionTools.ShowTemplateImage(this.SmallTemplateImage, this.currentImageTemplate);
 }
        /// <summary>
        /// When sample and template have same numbers of strokes
        /// </summary>
        /// <param name="sample">sample strokes</param>
        /// <param name="template">template strokes</param>
        /// <returns>An array where corr[i] = j denotes the ith stroke from the sample corresponds to the jth stroke from the template.</returns>
        public static int[] StrokeToStrokeCorrespondenceSameCount(List <SketchStroke> sample, List <SketchStroke> template)
        {
            int numStroke = sample.Count;

            int[]  correspondence = new int[numStroke];
            bool[] hasCompared    = new bool[numStroke];

            List <SketchStroke> sampleNormalized   = SketchPreprocessing.Normalize(sample, 128, 500, new SketchPoint(0.0, 0.0));
            List <SketchStroke> templateNormalized = SketchPreprocessing.Normalize(template, 128, 500, new SketchPoint(0.0, 0.0));

            for (int i = 0; i < numStroke; i++)
            {
                double minDis     = double.MaxValue;
                int    matchedIdx = -1;

                for (int j = 0; j < numStroke; j++)
                {
                    if (hasCompared[j])
                    {
                        continue;
                    }

                    double dis = SketchTools.HausdorffDistance(sampleNormalized[i], templateNormalized[j]);

                    if (dis < minDis)
                    {
                        minDis     = dis;
                        matchedIdx = j;
                    }
                }

                correspondence[i]       = matchedIdx;
                hasCompared[matchedIdx] = true;
            }

            return(correspondence);
        }
        /// <summary>
        /// one to one, one to many, or many to one, result is from template to sample strokes
        /// </summary>
        /// <param name="sample"></param>
        /// <param name="template"></param>
        /// <returns></returns>
        public static List <List <int>[]> StrokeToStrokeCorrespondenceDifferentCountStartFromSample(List <SketchStroke> sample, List <SketchStroke> template)
        {
            List <List <int>[]> result              = new List <List <int>[]>();
            HashSet <int>       usedSampleIndices   = new HashSet <int>();
            HashSet <int>       usedTemplateIndices = new HashSet <int>();

            List <SketchStroke> sampleNormalized   = SketchPreprocessing.Normalize(sample, 128, 500, new SketchPoint(0.0, 0.0));
            List <SketchStroke> templateNormalized = SketchPreprocessing.Normalize(template, 128, 500, new SketchPoint(0.0, 0.0));

            int si = 0;

            while (si < sample.Count && usedTemplateIndices.Count < template.Count)
            {
                Debug.WriteLine("si = " + si);

                if (usedSampleIndices.Contains(si))
                {
                    si++;
                    continue;
                }

                double oneToOneDis = double.MaxValue;
                int    matchedIdx  = -1;
                for (int ti = 0; ti < template.Count; ti++)
                {
                    if (usedTemplateIndices.Contains(ti))
                    {
                        continue;
                    }

                    double dis = SketchTools.HausdorffDistance(sampleNormalized[si], templateNormalized[ti]);

                    if (dis < oneToOneDis)
                    {
                        oneToOneDis = dis;
                        matchedIdx  = ti;
                    }
                }

                usedSampleIndices.Add(si);
                usedTemplateIndices.Add(matchedIdx);

                List <int> oneToManyIndices = new List <int>();
                oneToManyIndices.Add(matchedIdx);
                List <int> manyToOneIndices = new List <int>();
                manyToOneIndices.Add(si);

                SketchStroke currSampleStroke = sampleNormalized[si];
                double       oneToManyDis     = oneToOneDis;

                int preSample  = si - 1;
                int postSample = si + 1;
                while (preSample >= 0)
                {
                    if (usedSampleIndices.Contains(preSample))
                    {
                        break;
                    }

                    SketchStroke concatenatedStroke = SketchStroke.ConcatenateStrokes(sampleNormalized[preSample], currSampleStroke);
                    double       dis = SketchTools.HausdorffDistance(concatenatedStroke, templateNormalized[matchedIdx]);

                    if (dis < oneToManyDis)
                    {
                        oneToManyDis = dis;
                        oneToManyIndices.Insert(0, preSample);
                        currSampleStroke = concatenatedStroke;
                    }
                    else
                    {
                        break;
                    }

                    preSample--;
                }
                while (postSample < sample.Count)
                {
                    if (usedSampleIndices.Contains(postSample))
                    {
                        break;
                    }

                    SketchStroke concatenatedStroke = SketchStroke.ConcatenateStrokes(currSampleStroke, sampleNormalized[postSample]);
                    double       dis = SketchTools.HausdorffDistance(concatenatedStroke, templateNormalized[matchedIdx]);

                    if (dis < oneToManyDis)
                    {
                        oneToManyDis = dis;
                        oneToManyIndices.Add(postSample);
                        currSampleStroke = concatenatedStroke;
                    }
                    else
                    {
                        break;
                    }

                    postSample++;
                }

                SketchStroke currTemplateStroke = templateNormalized[matchedIdx];
                double       manyToOneDis       = oneToOneDis;

                int preTemplate  = matchedIdx - 1;
                int postTemplate = matchedIdx + 1;
                while (preTemplate >= 0)
                {
                    if (usedTemplateIndices.Contains(preTemplate))
                    {
                        break;
                    }

                    SketchStroke concatenatedStroke = SketchStroke.ConcatenateStrokes(templateNormalized[preTemplate], currTemplateStroke);
                    double       dis = SketchTools.HausdorffDistance(concatenatedStroke, sampleNormalized[si]);

                    if (dis < manyToOneDis)
                    {
                        manyToOneDis = dis;
                        manyToOneIndices.Insert(0, preTemplate);
                        currTemplateStroke = concatenatedStroke;
                    }
                    else
                    {
                        break;
                    }

                    preTemplate--;
                }
                while (postTemplate < template.Count)
                {
                    if (usedTemplateIndices.Contains(postTemplate))
                    {
                        break;
                    }

                    SketchStroke concatenatedStroke = SketchStroke.ConcatenateStrokes(currTemplateStroke, templateNormalized[postTemplate]);
                    double       dis = SketchTools.HausdorffDistance(concatenatedStroke, sampleNormalized[si]);

                    if (dis < manyToOneDis)
                    {
                        manyToOneDis = dis;
                        manyToOneIndices.Add(postTemplate);
                        currTemplateStroke = concatenatedStroke;
                    }
                    else
                    {
                        break;
                    }

                    postTemplate++;
                }

                Debug.WriteLine("matched index = " + matchedIdx);

                int flag = -2; // -1 for oneToMany, 0 for oneToOne, 1 for manyToOne
                if (oneToManyDis < oneToOneDis && manyToOneDis < oneToOneDis)
                {
                    if (oneToManyDis < manyToOneDis)
                    {
                        flag = -1;
                    }
                    else
                    {
                        flag = 1;
                    }
                }
                else if (oneToManyDis < oneToOneDis)
                {
                    flag = -1;
                }
                else if (manyToOneDis < oneToOneDis)
                {
                    flag = 1;
                }
                else
                {
                    flag = 0;
                }

                if (flag == 0)
                {
                    List <int> oneTemplate = new List <int>();
                    List <int> oneSample   = new List <int>();
                    oneTemplate.Add(matchedIdx);
                    oneSample.Add(si);
                    result.Add(new List <int>[] { oneTemplate, oneSample });
                    usedTemplateIndices.Add(matchedIdx);
                    usedSampleIndices.Add(matchedIdx);
                    si++;
                }
                else if (flag == -1) // one to many
                {
                    List <int> one  = new List <int>();
                    List <int> many = new List <int>();
                    one.Add(matchedIdx);
                    usedTemplateIndices.Add(matchedIdx);
                    foreach (int index in oneToManyIndices)
                    {
                        usedSampleIndices.Add(index);
                        many.Add(index);
                    }
                    result.Add(new List <int>[] { one, many });
                    si = many[many.Count - 1] + 1;
                }
                else if (flag == 1) // many to one
                {
                    List <int> many = new List <int>();
                    List <int> one  = new List <int>();
                    foreach (int index in manyToOneIndices)
                    {
                        usedTemplateIndices.Add(index);
                        many.Add(index);
                    }
                    one.Add(si);
                    result.Add(new List <int>[] { many, one });
                    usedSampleIndices.Add(matchedIdx);
                    si++;
                }
            }

            return(result);
        }