public IList<RecoResult> Recognize(TraceGroup testTraceGroup) { var testPreProcTraceGroup = _preProc.PreProcess(testTraceGroup); var testFeature = _featureExtractor.ExtractFeature(testPreProcTraceGroup); var distanceList = new List<KeyValuePair<int, float>>(); foreach (var train in _trainList) { var d = _featureExtractor.ComputeEuclideanDistance(train.ShapeFeatures, testFeature); distanceList.Add(new KeyValuePair<int, float>(train.ClassId, d)); } distanceList.Sort((f1, f2) => f1.Value.CompareTo(f2.Value)); var tempRecoResult = new List<RecoResult>(); var sumSimiliarity = 0f; for (var i = 0; i < distanceList.Count; i++) { var foundDuplicated = tempRecoResult.Find(c => c.ShapeId == distanceList[i].Key); if (foundDuplicated == null) { sumSimiliarity += distanceList[i].Value; tempRecoResult.Add(new RecoResult { ShapeId = distanceList[i].Key, ConfidenceLevel = distanceList[i].Value }); if (tempRecoResult.Count == _numOfChoice) break; } } for (var i = 0; i < _numOfChoice; i++) { tempRecoResult[i].ConfidenceLevel = (sumSimiliarity - tempRecoResult[i].ConfidenceLevel) / sumSimiliarity; } return tempRecoResult; }
public ActionResult Recognize(TraceGroup strokes) { //var aa = strokes.ToString(); //var serializer = new JavaScriptSerializer(); //var originalObject = serializer.Deserialize<TraceGroup>(strokes.ToString()); var recognizer = RecognizerContext.GetNNRecognizer; var result = recognizer.Recognize(strokes); return Json(result, JsonRequestBehavior.AllowGet); }
public TraceGroup ReadFromInkFile(string path) { var outTraceGroup = new TraceGroup(); var input = new FileStream(path, FileMode.Open, FileAccess.Read); var fileReader = new StreamReader(input); var strLine = ""; char[] splitter = { ' ' }; var captureDevice = new CaptureDevice {SamplingRate = 100, Latency = 0f}; while (!fileReader.EndOfStream) { strLine = fileReader.ReadLine(); if (strLine == null) continue; //Read header info if (strLine.Contains(".X_POINTS_PER_INCH")) { var strToken = strLine.Split(splitter, StringSplitOptions.None); captureDevice.XDpi = Convert.ToInt32(strToken[1]); } if (strLine.Contains(".Y_POINTS_PER_INCH")) { var strToken = strLine.Split(splitter, StringSplitOptions.None); captureDevice.YDpi = Convert.ToInt32(strToken[1]); } if (strLine.Contains(".POINTS_PER_SECOND")) { var strToken = strLine.Split(splitter, StringSplitOptions.None); //use later } if (!strLine.Trim().Equals(".PEN_DOWN")) continue; var strCoord = ""; var trace = new Trace(); while (!(strCoord = fileReader.ReadLine() ?? "").Trim().Equals(".PEN_UP") && !fileReader.EndOfStream) { var strToken = strCoord.Split(splitter, StringSplitOptions.None); var x = Convert.ToInt32(strToken[0]); var y = Convert.ToInt32(strToken[1]); trace.Points.Add(new PenPoint { X = x, Y = y }); } outTraceGroup.Traces.Add(trace); } fileReader.Close(); input.Close(); outTraceGroup.CaptureDevice = captureDevice; return outTraceGroup; }
public TraceGroup NormalizeSize(TraceGroup inTraceGroup) { var outTraceGroup = new TraceGroup(); var xScale = 0f; var yScale = 0f; var aspectRatio = 0f; float scaleX, scaleY, offsetX, offsetY; var xVec = new List<float>(); var yVec = new List<float>(); var box = inTraceGroup.GetBoundingBox(); outTraceGroup = inTraceGroup; xScale = Math.Abs(box.XMax - box.XMin) / outTraceGroup.XScaleFactor; yScale = Math.Abs(box.YMax - box.YMin) / outTraceGroup.YScaleFactor; if (_preserveAspectRatio) { if (yScale > xScale) { aspectRatio = (xScale > _eps) ? (yScale / xScale) : _aspectRatioThreshold + _eps; } else { aspectRatio = (yScale > _eps) ? (xScale / yScale) : _aspectRatioThreshold + _eps; } if (aspectRatio > _aspectRatioThreshold) { if (yScale > xScale) xScale = yScale; else yScale = xScale; } } offsetY = 0.0f; if (_preserveRelativeYPosition) offsetY = (box.YMin + box.YMax) / 2.0f; if (xScale <= (_dotThreshold * _captureDevice.XDpi) && yScale <= (_dotThreshold * _captureDevice.YDpi)) { offsetX = _preprocNormalizeSize / 2; offsetY += _preprocNormalizeSize / 2; outTraceGroup.Traces.Clear(); foreach (var trace in inTraceGroup.Traces) { var normalizedTrace = new Trace(); foreach (var point in trace.Points) { normalizedTrace.Points.Add(new PenPoint { X = offsetX, Y = offsetY }); } outTraceGroup.Traces.Add(normalizedTrace); } } //finding the final scale and offset values for the x channel if ((!_preserveAspectRatio) && (xScale < (_sizeThreshold * _captureDevice.XDpi))) { scaleX = 1.0f; offsetX = (float)(_preprocNormalizeSize / 2.0); } else { scaleX = (float)(_preprocNormalizeSize / xScale); offsetX = 0.0f; } // finding the final scale and offset values for the y channel if ((!_preserveAspectRatio) && (yScale < _sizeThreshold * _captureDevice.YDpi)) { offsetY += _preprocNormalizeSize / 2; scaleY = 1.0f; } else { scaleY = (float)(_preprocNormalizeSize / yScale); } outTraceGroup.AffineTransform(scaleX, scaleY, offsetX, offsetY, TraceGroupCornerEnum.XMin_YMin); return outTraceGroup; }
public TraceGroup SmoothenTraceGroup(TraceGroup traceGroup) { var filterLength = 5; var newTraceGroup = new TraceGroup(); var sumX = 0f; var sumY = 0f; var actualIndex = 0; foreach (var trace in traceGroup.Traces) { var newTrace = new Trace(); var numPoints = trace.Points.Count; var channelX = trace.ChannelX; var channelY = trace.ChannelY; for (var pointIndex = 0; pointIndex < numPoints; pointIndex++) { sumX = sumY = 0f; for (var loopIdex = 0; loopIdex < filterLength; loopIdex++) { actualIndex = (pointIndex - loopIdex); if (actualIndex < 0) { actualIndex = 0; } else if (actualIndex >= numPoints) { actualIndex = numPoints - 1; } //accumulate sum sumX += channelX[actualIndex]; sumY += channelY[actualIndex]; } sumX /= filterLength; sumY /= filterLength; newTrace.Points.Add(new PenPoint { X = sumX, Y = sumY }); } newTraceGroup.Traces.Add(newTrace); } return newTraceGroup; }
//public TraceGroup ResampleTraceGroup(TraceGroup inTraceGroup) //{ // var outTraceGroup = new TraceGroup(); // foreach(var trace in inTraceGroup.Traces) // { // var outTrace = ResampleTrace(trace, 60); // outTraceGroup.Traces.Add(outTrace); // } // return outTraceGroup; //} public TraceGroup ResampleTraceGroup(TraceGroup inTraceGroup) { var total = 0; var totalLength = 0f; var totalPoints = 0; var numOfTraces = inTraceGroup.Traces.Count; //Implement length base scheme var maxIndex = 0; float maxLength = 0f; var lengthsVec = new List<float>(); for (var j = 0; j < numOfTraces; j++) { var trace = inTraceGroup.Traces[j]; var length = ComputeTraceLength(trace, 0, trace.Points.Count - 1); lengthsVec.Add(length); if (Math.Abs(lengthsVec[j]) < _eps) lengthsVec[j] = _eps; totalLength += lengthsVec[j]; if (lengthsVec[j] > maxLength) { maxLength = lengthsVec[j]; maxIndex = j; } } var pointsPerTrace = new List<int>(); for (int i = 0; i < numOfTraces; i++) { pointsPerTrace.Add(0); if (i != maxIndex) { var tempPoints = _quantizationStep * (int)(Math.Floor(_traceDimension * lengthsVec[i] / (_quantizationStep * totalLength)) + 0.5f); pointsPerTrace[i] = tempPoints; if (pointsPerTrace[i] <= 0) pointsPerTrace[i] = 1; total += pointsPerTrace[i]; } } pointsPerTrace[maxIndex] = _traceDimension - total; int sum = 0; for (int temp = 0; temp < pointsPerTrace.Count; temp++) { sum += pointsPerTrace[temp]; } var outTraceGroup = new TraceGroup(); for (int i = 0; i < numOfTraces; i++) { var trace = inTraceGroup.Traces[i]; var newTrace = ResampleTrace(trace, pointsPerTrace[i]); outTraceGroup.Traces.Add(newTrace); } outTraceGroup.XScaleFactor = inTraceGroup.XScaleFactor; outTraceGroup.YScaleFactor = inTraceGroup.YScaleFactor; return outTraceGroup; }
public TraceGroup PreProcess(TraceGroup inTraceGroup) { CaptureDevice = inTraceGroup.CaptureDevice; var norm1 = NormalizeSize(inTraceGroup); var sampling1 = ResampleTraceGroup(norm1); var norm2 = NormalizeSize(sampling1); return norm2; }
public IList<PointFloatShapeFeature> ExtractFeature(TraceGroup inTraceGroup) { var outVector = new List<PointFloatShapeFeature>(); float x, y, deltaX; float sinTheta, cosTheta, sqSum; var numPoints = 0; foreach (var trace in inTraceGroup.Traces) { numPoints += trace.ChannelX.Count; } var xVec = new List<float>(numPoints); var yVec = new List<float>(numPoints); var penUpVec = new List<bool>(); foreach (var trace in inTraceGroup.Traces) { var tempxVec = trace.ChannelX; var tempyVec = trace.ChannelY; var currentStrokeSize = tempxVec.Count; for (var point = 0; point < currentStrokeSize; point++) { xVec.Add(tempxVec[point]); yVec.Add(tempyVec[point]); if (point == currentStrokeSize - 1) { penUpVec.Add(true); } else { penUpVec.Add(false); } } } //Concatenating the strokes var theta = new List<float>(numPoints); var delta_x = new List<float>(numPoints); var delta_y = new List<float>(numPoints); for (var i = 0; i < numPoints - 1; i++) { delta_x.Add(xVec[i + 1] - xVec[i]); delta_y.Add(yVec[i + 1] - yVec[i]); } //Add the control info here sqSum = (float)Math.Sqrt(Math.Pow(xVec[0], 2) + Math.Pow(yVec[0], 2)) + _eps; sinTheta = (1 + yVec[0] / sqSum) * _preprocNormalizeSize / 2; cosTheta = (1 + xVec[0] / sqSum) * _preprocNormalizeSize / 2; var feature = new PointFloatShapeFeature { X = xVec[0], Y = yVec[0], SinTheta = sinTheta, CosTheta = cosTheta, IsPenUp = penUpVec[0] }; outVector.Add(feature); for (var i = 1; i < numPoints; i++) { sqSum = (float)Math.Sqrt(Math.Pow(delta_x[i - 1], 2) + Math.Pow(delta_y[i - 1], 2)) + _eps; sinTheta = (1 + delta_y[i - 1] / sqSum) * _preprocNormalizeSize / 2; cosTheta = (1 + delta_x[i - 1] / sqSum) * _preprocNormalizeSize / 2; feature = new PointFloatShapeFeature { X = xVec[i], Y = yVec[i], SinTheta = sinTheta, CosTheta = cosTheta, IsPenUp = penUpVec[i] }; outVector.Add(feature); } return outVector; }
public void AffineTransform(float xScaleFactor, float yScaleFactor, float translateToX, float translateToY, TraceGroupCornerEnum referenceCorner) { var outTraceGroup = new TraceGroup(); float xReference = 0f, yReference = 0f; float x, y; if (xScaleFactor <= 0) //invalid { } if (yScaleFactor <= 0) { //invalid } var box = GetBoundingBox(); switch (referenceCorner) { case TraceGroupCornerEnum.XMin_YMin: xReference = box.XMin; yReference = box.YMin; break; case TraceGroupCornerEnum.XMin_YMax: xReference = box.XMin; yReference = box.YMax; break; case TraceGroupCornerEnum.XMax_YMin: xReference = box.XMax; yReference = box.YMin; break; case TraceGroupCornerEnum.XMax_YMax: xReference = box.XMax; yReference = box.YMax; break; default: break; } foreach (var trace in Traces) { var scaleTrace = new Trace(); foreach (var point in trace.Points) { //the additive term is to translate back the scaled tracegroup //so that the corner asked for is preserved at the destination //(translateToX,translateToY) x = (point.X * xScaleFactor) / XScaleFactor + (translateToX - (xReference * (xScaleFactor / XScaleFactor))); //the additive term is to translate back the scaled tracegroup //so that the corner asked for is preserved at the destination //(translateToX,translateToY) y = (point.Y * yScaleFactor) / YScaleFactor + (translateToY - (yReference * (yScaleFactor / YScaleFactor))); scaleTrace.Points.Add(new PenPoint { X = x, Y = y }); } outTraceGroup.Traces.Add(scaleTrace); } Traces = outTraceGroup.Traces; XScaleFactor = xScaleFactor; YScaleFactor = yScaleFactor; //return outTraceGroup; }