|
@@ -7,48 +7,50 @@ using System.Threading.Tasks;
|
|
|
using Emgu.CV;
|
|
|
using Emgu.CV.Structure;
|
|
|
using bbiwarg.Images;
|
|
|
+using bbiwarg.Utility;
|
|
|
|
|
|
namespace bbiwarg.Detectors.Fingers
|
|
|
{
|
|
|
class Finger
|
|
|
{
|
|
|
- private List<FingerPoint> fingerPoints;
|
|
|
+ private List<Vector<int>> fingerPoints;
|
|
|
private bool lineUpToDate = false;
|
|
|
- private PointF direction;
|
|
|
- private PointF pointOnLine;
|
|
|
- private PointF lineEndPoint1;
|
|
|
- private PointF lineEndPoint2;
|
|
|
- private FingerPoint tipPoint;
|
|
|
- private FingerPoint handPoint;
|
|
|
+ private Vector<float> direction;
|
|
|
+ private Vector<float> pointOnLine;
|
|
|
+ private Vector<float> lineEndPoint1;
|
|
|
+ private Vector<float> lineEndPoint2;
|
|
|
+ private Vector<int> tipPoint;
|
|
|
+ private Vector<int> handPoint;
|
|
|
private float length;
|
|
|
|
|
|
- public Finger(FingerPoint fingerPoint)
|
|
|
+ public Finger(Vector<int> fingerPoint)
|
|
|
{
|
|
|
- fingerPoints = new List<FingerPoint>();
|
|
|
+ fingerPoints = new List<Vector<int>>();
|
|
|
addFingerPoint(fingerPoint);
|
|
|
}
|
|
|
|
|
|
- public PointF getLineEndPoint1()
|
|
|
+ public Vector<float> getLineEndPoint1()
|
|
|
{
|
|
|
if (!lineUpToDate) updateLine();
|
|
|
return lineEndPoint1;
|
|
|
}
|
|
|
|
|
|
- public PointF getLineEndPoint2()
|
|
|
+ public Vector<float> getLineEndPoint2()
|
|
|
{
|
|
|
if (!lineUpToDate) updateLine();
|
|
|
return lineEndPoint2;
|
|
|
}
|
|
|
|
|
|
- public FingerPoint getTipPoint()
|
|
|
+ public Vector<float> getDirection()
|
|
|
{
|
|
|
if (!lineUpToDate) updateLine();
|
|
|
- return tipPoint;
|
|
|
+ return direction;
|
|
|
}
|
|
|
|
|
|
- public PointF getDirection() {
|
|
|
+ public Vector<int> getTipPoint()
|
|
|
+ {
|
|
|
if (!lineUpToDate) updateLine();
|
|
|
- return direction;
|
|
|
+ return tipPoint;
|
|
|
}
|
|
|
|
|
|
public float getLength()
|
|
@@ -57,18 +59,18 @@ namespace bbiwarg.Detectors.Fingers
|
|
|
return length;
|
|
|
}
|
|
|
|
|
|
- public void addFingerPoint(FingerPoint fingerPoint)
|
|
|
+ public void addFingerPoint(Vector<int> fingerPoint)
|
|
|
{
|
|
|
fingerPoints.Add(fingerPoint);
|
|
|
lineUpToDate = false;
|
|
|
}
|
|
|
|
|
|
- public float getMinDistance(FingerPoint fingerPoint)
|
|
|
+ public float getMinDistance(Vector<int> fingerPoint)
|
|
|
{
|
|
|
float minDinstance = float.MaxValue;
|
|
|
- foreach (FingerPoint fp in fingerPoints)
|
|
|
+ foreach (Vector<int> fp in fingerPoints)
|
|
|
{
|
|
|
- float distance = fp.getDistanceTo(fingerPoint);
|
|
|
+ float distance = fingerPoint.subDistance(fp, 2);
|
|
|
if (distance < minDinstance)
|
|
|
{
|
|
|
minDinstance = distance;
|
|
@@ -81,23 +83,27 @@ namespace bbiwarg.Detectors.Fingers
|
|
|
public float getSimilarity(Finger compareFinger) {
|
|
|
//startDistance
|
|
|
float maxStartDistance = 100;
|
|
|
- float xDiffStart = lineEndPoint1.X - compareFinger.getLineEndPoint1().X;
|
|
|
- float yDiffStart = lineEndPoint1.X - compareFinger.getLineEndPoint1().Y;
|
|
|
+ float xDiffStart = lineEndPoint1.x - compareFinger.getLineEndPoint1().x;
|
|
|
+ float yDiffStart = lineEndPoint1.y - compareFinger.getLineEndPoint1().y;
|
|
|
float startDistance = (float)Math.Sqrt(xDiffStart * xDiffStart + yDiffStart * yDiffStart);
|
|
|
float startSimilarity = Math.Max(1 - (startDistance / maxStartDistance), 0);
|
|
|
|
|
|
//endDistance
|
|
|
- float maxEndDistance = 50;
|
|
|
- float xDiffEnd = lineEndPoint2.X - compareFinger.getLineEndPoint2().X;
|
|
|
- float yDiffEnd = lineEndPoint2.X - compareFinger.getLineEndPoint2().Y;
|
|
|
+ float maxEndDistance = 100;
|
|
|
+ float xDiffEnd = lineEndPoint2.x - compareFinger.getLineEndPoint2().x;
|
|
|
+ float yDiffEnd = lineEndPoint2.y - compareFinger.getLineEndPoint2().y;
|
|
|
float endDistance = (float)Math.Sqrt(xDiffEnd * xDiffEnd + yDiffEnd * yDiffEnd);
|
|
|
float endSimilarity = Math.Max(1 - (endDistance / maxEndDistance), 0);
|
|
|
|
|
|
//direction
|
|
|
+ float scalaProduct = direction * compareFinger.getDirection();
|
|
|
+ float lengthDirection = direction.norm();
|
|
|
+ float lengthCompareDirection = compareFinger.getDirection().norm();
|
|
|
+ float directionSimilarity = Math.Abs(scalaProduct / (lengthDirection * lengthCompareDirection));
|
|
|
|
|
|
+ //Console.WriteLine(Math.Round(directionSimilarity, 2) + "###" + Math.Round(startSimilarity, 2) + "###" + Math.Round(endSimilarity, 2));
|
|
|
|
|
|
-
|
|
|
- return (0.2f*startSimilarity + 0.8f*endSimilarity);
|
|
|
+ return (startSimilarity + endSimilarity + directionSimilarity) / 3;
|
|
|
|
|
|
}
|
|
|
|
|
@@ -105,19 +111,23 @@ namespace bbiwarg.Detectors.Fingers
|
|
|
//update direction+pointonline
|
|
|
PointF[] pointArray = new PointF[fingerPoints.Count];
|
|
|
int i = 0;
|
|
|
- foreach (FingerPoint fp in fingerPoints)
|
|
|
+ foreach (Vector<int> fp in fingerPoints)
|
|
|
{
|
|
|
- pointArray[i] = new PointF(fp.getX(), fp.getY());
|
|
|
+ pointArray[i] = new PointF(fp.x, fp.y);
|
|
|
++i;
|
|
|
}
|
|
|
- PointCollection.Line2DFitting(pointArray, Emgu.CV.CvEnum.DIST_TYPE.CV_DIST_L2, out direction, out pointOnLine);
|
|
|
-
|
|
|
- FingerPoint fp1 = fingerPoints[0];
|
|
|
- FingerPoint fp2 = fingerPoints[0];
|
|
|
+ PointF tempDirection;
|
|
|
+ PointF tempPointOnLine;
|
|
|
+ PointCollection.Line2DFitting(pointArray, Emgu.CV.CvEnum.DIST_TYPE.CV_DIST_L2, out tempDirection, out tempPointOnLine);
|
|
|
+ direction = new Vector<float>(new float[2]{tempDirection.X, tempDirection.Y});
|
|
|
+ pointOnLine = new Vector<float>(new float[2] { tempPointOnLine.X, tempPointOnLine.Y });
|
|
|
+
|
|
|
+ Vector<int> fp1 = fingerPoints[0];
|
|
|
+ Vector<int> fp2 = fingerPoints[0];
|
|
|
length = 0.0f;
|
|
|
- foreach (FingerPoint fp in fingerPoints) {
|
|
|
- float distanceToFP1 = fp.getDistanceTo(fp1);
|
|
|
- float distanceToFP2 = fp.getDistanceTo(fp2);
|
|
|
+ foreach (Vector<int> fp in fingerPoints) {
|
|
|
+ float distanceToFP1 = fp.subDistance(fp1,2);
|
|
|
+ float distanceToFP2 = fp.subDistance(fp2,2);
|
|
|
if (length < distanceToFP1 && distanceToFP1 >= distanceToFP2)
|
|
|
{
|
|
|
fp2 = fp;
|
|
@@ -130,7 +140,7 @@ namespace bbiwarg.Detectors.Fingers
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (fp1.getY() < fp2.getY())
|
|
|
+ if (fp1.y < fp2.y)
|
|
|
{
|
|
|
tipPoint = fp1;
|
|
|
handPoint = fp2;
|
|
@@ -142,15 +152,15 @@ namespace bbiwarg.Detectors.Fingers
|
|
|
}
|
|
|
|
|
|
//update start+end
|
|
|
- lineEndPoint1 = projectToLine(new PointF(tipPoint.getX(), tipPoint.getY()));
|
|
|
- lineEndPoint2 = projectToLine(new PointF(handPoint.getX(), handPoint.getY()));
|
|
|
+ lineEndPoint1 = projectToLine(tipPoint);
|
|
|
+ lineEndPoint2 = projectToLine(handPoint);
|
|
|
|
|
|
lineUpToDate = true;
|
|
|
}
|
|
|
|
|
|
- private PointF projectToLine(PointF p)
|
|
|
+ private Vector<float> projectToLine(Vector<int> p)
|
|
|
{
|
|
|
- float px = p.X, py = p.Y, dx = direction.X, dy = direction.Y, ox = pointOnLine.X, oy = pointOnLine.Y;
|
|
|
+ float px = p.x, py = p.y, dx = direction.x, dy = direction.y, ox = pointOnLine.x, oy = pointOnLine.y;
|
|
|
float diffx = px - ox;
|
|
|
float diffy = py - oy;
|
|
|
|
|
@@ -158,7 +168,10 @@ namespace bbiwarg.Detectors.Fingers
|
|
|
float d_d = (dx * dx + dy * dy);
|
|
|
float q = diff_d / d_d;
|
|
|
|
|
|
- return new PointF(ox + q * dx, oy + q * dy);
|
|
|
+ float newX = ox + q * dx;
|
|
|
+ float newY = oy + q * dy;
|
|
|
+
|
|
|
+ return new Vector<float>(new float[2]{newX, newY});
|
|
|
}
|
|
|
}
|
|
|
}
|