123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using Emgu.CV;
- using Emgu.CV.Structure;
- using bbiwarg.Images;
- namespace bbiwarg.Detectors.Fingers
- {
- class Finger
- {
- private List<FingerPoint> fingerPoints;
- private bool lineUpToDate = false;
- private PointF direction;
- private PointF pointOnLine;
- private PointF lineEndPoint1;
- private PointF lineEndPoint2;
- private FingerPoint tipPoint;
- private FingerPoint handPoint;
- private float length;
-
- public Finger(FingerPoint fingerPoint)
- {
- fingerPoints = new List<FingerPoint>();
- addFingerPoint(fingerPoint);
- }
- public PointF getLineEndPoint1()
- {
- if (!lineUpToDate) updateLine();
- return lineEndPoint1;
- }
- public PointF getLineEndPoint2()
- {
- if (!lineUpToDate) updateLine();
- return lineEndPoint2;
- }
- public FingerPoint getTipPoint()
- {
- if (!lineUpToDate) updateLine();
- return tipPoint;
- }
- public PointF getDirection() {
- if (!lineUpToDate) updateLine();
- return direction;
- }
- public float getLength()
- {
- if (!lineUpToDate) updateLine();
- return length;
- }
- public void addFingerPoint(FingerPoint fingerPoint)
- {
- fingerPoints.Add(fingerPoint);
- lineUpToDate = false;
- }
- public float getMinDistance(FingerPoint fingerPoint)
- {
- float minDinstance = float.MaxValue;
- foreach (FingerPoint fp in fingerPoints)
- {
- float distance = fp.getDistanceTo(fingerPoint);
- if (distance < minDinstance)
- {
- minDinstance = distance;
- }
- }
- return minDinstance;
- }
- public bool isSimilarTo(Finger compareFinger) {
- PointF center = new PointF((lineEndPoint1.X + lineEndPoint2.X) / 2, (lineEndPoint1.Y + lineEndPoint2.Y) / 2);
- PointF compareCenter = new PointF((compareFinger.getLineEndPoint1().X+compareFinger.getLineEndPoint2().X)/2, (compareFinger.getLineEndPoint1().Y+compareFinger.getLineEndPoint2().Y)/2);
- float xDiff = center.X - compareCenter.X;
- float yDiff = center.Y - compareCenter.Y;
- float centerDistance = (float)Math.Sqrt(xDiff * xDiff + yDiff * yDiff);
- float maxCenterDistance = 40;
- if (centerDistance > maxCenterDistance)
- return false;
- return true;
-
- }
- private void updateLine() {
- //update direction+pointonline
- PointF[] pointArray = new PointF[fingerPoints.Count];
- int i = 0;
- foreach (FingerPoint fp in fingerPoints)
- {
- pointArray[i] = new PointF(fp.getX(), fp.getY());
- ++i;
- }
- PointCollection.Line2DFitting(pointArray, Emgu.CV.CvEnum.DIST_TYPE.CV_DIST_L2, out direction, out pointOnLine);
- FingerPoint fp1 = fingerPoints[0];
- FingerPoint fp2 = fingerPoints[0];
- length = 0.0f;
- foreach (FingerPoint fp in fingerPoints) {
- float distanceToFP1 = fp.getDistanceTo(fp1);
- float distanceToFP2 = fp.getDistanceTo(fp2);
- if (length < distanceToFP1 && distanceToFP1 >= distanceToFP2)
- {
- fp2 = fp;
- length = distanceToFP1;
- }
- else if (length < distanceToFP2 && distanceToFP2 > distanceToFP1)
- {
- fp1 = fp;
- length = distanceToFP2;
- }
- }
- if (fp1.getY() < fp2.getY())
- {
- tipPoint = fp1;
- handPoint = fp2;
- }
- else
- {
- tipPoint = fp2;
- handPoint = fp1;
- }
- //update start+end
- lineEndPoint1 = projectToLine(new PointF(tipPoint.getX(), tipPoint.getY()));
- lineEndPoint2 = projectToLine(new PointF(handPoint.getX(), handPoint.getY()));
- lineUpToDate = true;
- }
- private PointF projectToLine(PointF p)
- {
- 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;
- float diff_d = (diffx * dx + diffy * dy);
- float d_d = (dx * dx + dy * dy);
- float q = diff_d / d_d;
- return new PointF(ox + q * dx, oy + q * dy);
- }
- }
- }
|