123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Drawing;
- using Emgu.CV;
- using Emgu.CV.Structure;
- using bbiwarg.Images;
- using bbiwarg.Utility;
- namespace bbiwarg.Detectors.Fingers
- {
- class FingerDetector
- {
- private DepthImage depthImage;
- private EdgeImage edgeImage;
- private FingerImage fingerImage;
- private List<Finger> possibleFingers;
- private List<Finger> fingers;
- public FingerDetector(DepthImage depthImage, EdgeImage edgeImage, FingerImage fingerImage) {
- this.depthImage = depthImage;
- this.edgeImage = edgeImage;
- this.fingerImage = fingerImage;
- findPossibleFingerPoints();
- findPossibleFingers();
- setFingers();
- setFingerPoints();
- }
- public List<Finger> getFingers() {
- return fingers;
- }
- private void findPossibleFingerPoints()
- {
- int width = depthImage.getWidth();
- int height = depthImage.getHeight();
- int maxFingerSize = 30;
- int minFingerSize = 10;
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- if (edgeImage.isEdgeAt(x,y)) {
- //search horizontal
- bool edgeRightFound = false;
- int edgeRightX = x + minFingerSize;
- while (!edgeRightFound && edgeRightX < width) {
- if (edgeImage.isEdgeAt(edgeRightX,y))
- edgeRightFound = true;
- else
- edgeRightX++;
- }
- if (edgeRightFound){
- int midX = (edgeRightX + x) / 2;
- Int16 depthLeft = depthImage.getDepthAt(x, y);
- Int16 depthMid = depthImage.getDepthAt(midX, y);
- Int16 depthRight = depthImage.getDepthAt(edgeRightX, y);
- if ((edgeRightX - x) < maxFingerSize && depthLeft > depthMid && depthMid < depthRight) {
- fingerImage.setFingerAt(midX, y, FingerImageState.possibleFinger);
- }
- }
- //search vertical
- bool edgeBottomFound = false;
- int edgeBottomY = y + minFingerSize;
- while (!edgeBottomFound && edgeBottomY < height) {
- if (edgeImage.isEdgeAt(x, edgeBottomY))
- edgeBottomFound = true;
- else
- edgeBottomY++;
- }
- if (edgeBottomFound) {
- int midY = (edgeBottomY + y) / 2;
- Int16 depthTop = depthImage.getDepthAt(x, y);
- Int16 depthMid = depthImage.getDepthAt(x, midY);
- Int16 depthBottom = depthImage.getDepthAt(x, edgeBottomY);
- if ((edgeBottomY - y) < maxFingerSize && depthTop > depthMid && depthMid < depthBottom) {
- fingerImage.setFingerAt(x, midY, FingerImageState.possibleFinger);
- }
- }
- }
- }
- }
- }
- private void findPossibleFingers()
- {
- int width = depthImage.getWidth();
- int height = depthImage.getHeight();
- float maxDistanceTogether = 5.0f;
- possibleFingers = new List<Finger>();
- for (int y = 0; y < height; y++)
- {
- for (int x = 0; x < width; x++)
- {
- if (fingerImage.getStateAt(x,y) == FingerImageState.possibleFinger)
- {
- Int16 depth = depthImage.getDepthAt(x, y);
- Vector<int> fingerPoint = new Vector<int>(new int[3]{x,y,depth});
- float minDistanceValue = float.MaxValue;
- int minDistanceIndex = 0;
- for (int i = 0; i < possibleFingers.Count; i++)
- {
- float distance = possibleFingers[i].getMinDistance(fingerPoint);
- if (distance < minDistanceValue)
- {
- minDistanceValue = distance;
- minDistanceIndex = i;
- }
- }
- if (minDistanceValue < maxDistanceTogether)
- {
- possibleFingers[minDistanceIndex].addFingerPoint(fingerPoint);
- }
- else
- {
- possibleFingers.Add(new Finger(fingerPoint));
- }
- }
- }
- }
- }
- private void setFingers()
- {
- int width = depthImage.getWidth();
- int height = depthImage.getHeight();
- float minFingerLength = 20.0f;
- fingers = new List<Finger>();
- foreach (Finger finger in possibleFingers)
- {
- float length = finger.getLength();
- if (length > minFingerLength)
- {
- fingers.Add(finger);
- }
- }
- }
- private void setFingerPoints() {
- int width = depthImage.getWidth();
- int height = depthImage.getHeight();
- foreach (Finger finger in fingers) {
- Vector<float> lineEndPoint1 = finger.getLineEndPoint1();
- Vector<float> lineEndPoint2 = finger.getLineEndPoint2();
- fingerImage.drawLine(lineEndPoint1, lineEndPoint2, FingerImageState.fingerDetected);
- }
- }
- }
- }
|