Advertisement
Guest User

Untitled

a guest
Jun 13th, 2018
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 21.86 KB | None | 0 0
  1. import javax.imageio.ImageIO;
  2. import javax.swing.*;
  3. import javax.swing.filechooser.FileSystemView;
  4.  
  5. import org.opencv.core.Core;
  6. import org.opencv.core.CvType;
  7. import org.opencv.core.Mat;
  8. import org.opencv.core.MatOfByte;
  9. import org.opencv.core.MatOfInt;
  10. import org.opencv.core.MatOfInt4;
  11. import org.opencv.core.MatOfPoint;
  12. import org.opencv.core.MatOfPoint2f;
  13. import org.opencv.core.Point;
  14. import org.opencv.core.RotatedRect;
  15. import org.opencv.core.Scalar;
  16. import org.opencv.core.Size;
  17. import org.opencv.highgui.Highgui;
  18. import org.opencv.highgui.VideoCapture;
  19. import org.opencv.imgproc.Imgproc;
  20. import org.opencv.utils.Converters;
  21.  
  22. import java.awt.*;
  23. import java.awt.event.*;
  24. import java.awt.image.BufferedImage;
  25. import java.io.ByteArrayInputStream;
  26. import java.io.File;
  27. import java.io.IOException;
  28. import java.io.InputStream;
  29. import java.net.URI;
  30. import java.net.URISyntaxException;
  31. import java.util.*;
  32. import java.util.List;
  33.  
  34. import static java.lang.Thread.sleep;
  35.  
  36. public class HandDetector extends JPanel {
  37.     private static final long serialVersionUID = 1L;
  38.  
  39.     private JFrame frame = new JFrame("Hand detector");
  40.     private JLabel label = new JLabel();
  41.     private JButton saveBtn = new JButton("Save one picture");
  42.     private JButton saveSeriesBtn = new JButton("Save series of pictures");
  43.     private JFileChooser fileChooser = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory());
  44.     private String onePictureSavePath;
  45.     private Boolean savedOnePicture = false;
  46.     private Boolean savedPictureSeries = false;
  47.     private JLabel numberOfFingersLabel = new JLabel();
  48.  
  49.     private static boolean start = false;
  50.     public int counter;
  51.     private static boolean close = false;
  52.  
  53.     public HandDetector() {
  54.         counter = 0;
  55.     }
  56.  
  57.     public void setFrame(final org.opencv.highgui.VideoCapture webcam) {
  58.         frame.setSize(1024, 768);
  59.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  60.         frame.setVisible(true);
  61.         frame.getContentPane().add(label);
  62.         saveBtn.setBounds(0,0,200,100);
  63.         saveBtn.setVisible(true);
  64.         label.add(saveBtn);
  65.  
  66.         numberOfFingersLabel.setBounds(500, 0, 300, 100);
  67.         numberOfFingersLabel.setFont(new Font("Courier New", Font.BOLD, 24));
  68.         label.add(numberOfFingersLabel);
  69.  
  70.         saveSeriesBtn.setBounds(250,0,200,100);
  71.         saveSeriesBtn.setVisible(true);
  72.         label.add(saveSeriesBtn);
  73.  
  74.         saveBtn.addActionListener(new ActionListener() {
  75.             public void actionPerformed(ActionEvent e) {
  76.                 int returnValue = fileChooser.showSaveDialog(null);
  77.  
  78.                 if (returnValue == JFileChooser.APPROVE_OPTION) {
  79.                     onePictureSavePath = fileChooser.getSelectedFile().toString();
  80.                     savedOnePicture = false;
  81.                 }
  82.             }
  83.         });
  84.         saveSeriesBtn.addActionListener(new ActionListener() {
  85.             public void actionPerformed(ActionEvent e) {
  86.                 savedPictureSeries = true;
  87.             }
  88.         });
  89.     }
  90.  
  91.     public void frameToLabel(Mat matFrame) {
  92.         MatOfByte cc = new MatOfByte();
  93.         Highgui.imencode(".JPG", matFrame, cc);
  94.         byte[] bytes = cc.toArray();
  95.         InputStream ss = new ByteArrayInputStream(bytes);
  96.  
  97.         try {
  98.             BufferedImage aa = ImageIO.read(ss);
  99.             label.setIcon(new ImageIcon(aa));
  100.  
  101.             if(!savedOnePicture && (onePictureSavePath != null)) {
  102.                 fetchOnePicture(onePictureSavePath, aa);
  103.                 savedOnePicture = true;
  104.             }
  105.             if(savedPictureSeries) {
  106.                 if(counter < 5) {
  107.                     fetchSeriesOfPictures(counter, aa);
  108.                     counter++;
  109.                 } else {
  110.                     savedPictureSeries = false;
  111.                     counter = 0;
  112.                 }
  113.             }
  114.         } catch (IOException e) {
  115.             e.printStackTrace();
  116.         }
  117.     }
  118.  
  119.     public void fetchOnePicture(String path, BufferedImage aa) throws IOException {
  120.         File outputFile = new File(path);
  121.         ImageIO.write(aa, "jpg", outputFile);
  122.     }
  123.  
  124.     public void fetchSeriesOfPictures(int i, BufferedImage aa) throws IOException {
  125.         String filename = "C:\\Users\\pfilipowicz\\Desktop\\images\\image" + String.valueOf(i) + ".jpg";
  126.         fetchOnePicture(filename, aa);
  127.     }
  128.  
  129.     public Mat morphologicalFilter(int kd,int ke,Mat image){
  130.         Mat modified=new Mat();
  131.         Imgproc.erode(image, modified, Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(ke,ke)));
  132.         Imgproc.dilate(modified, modified,  Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(kd,kd)));
  133.         return modified;
  134.     }
  135.  
  136.     public Mat hsvColorFilter(int h,int s,int v,int h1,int s1,int v1,Mat image){
  137.         Mat modified = new Mat();
  138.         if(image!=null){
  139.             Core.inRange(image, new Scalar(h,s,v), new Scalar(h1,s1,v1), modified);
  140.         } else{
  141.             System.out.println("Error image");
  142.         }
  143.         return modified;
  144.     }
  145.  
  146.     public List<Point> inviluppodifetti(Mat image,List<MatOfPoint> contours,boolean draws,int depthThreshold){
  147.         List<Point> defects=new LinkedList<Point>();
  148.  
  149.         for(int i=0;i<contours.size();i++){
  150.             MatOfInt hull_=new MatOfInt();
  151.             MatOfInt4 convexityDefects=new MatOfInt4();
  152.  
  153.             @SuppressWarnings("unused")
  154.             List<Point> outlinePoints = new LinkedList<Point>();
  155.             outlinePoints=contours.get(i).toList();
  156.  
  157.             Imgproc.convexHull(contours.get(i), hull_);
  158.  
  159.             if (hull_.size().height>=4){
  160.                 Imgproc.convexityDefects(contours.get(i), hull_, convexityDefects);
  161.  
  162.                 List<Point> pts=new ArrayList<Point>();
  163.                 MatOfPoint2f pr=new MatOfPoint2f();
  164.                 Converters.Mat_to_vector_Point(contours.get(i), pts);
  165.                 //rectangle
  166.                 pr.create((int)(pts.size()), 1, CvType.CV_32S);
  167.                 pr.fromList(pts);
  168.                 if(pr.height()>10){
  169.                     RotatedRect r=Imgproc.minAreaRect(pr);
  170.                     Point[] rect=new Point[4];
  171.                     r.points(rect);
  172.  
  173.                     Core.line(image, rect[0], rect[1],new Scalar(0,100,0),2);
  174.                     Core.line(image, rect[0], rect[3],new Scalar(0,100,0),2);
  175.                     Core.line(image, rect[1], rect[2],new Scalar(0,100,0),2);
  176.                     Core.line(image, rect[2], rect[3],new Scalar(0,100,0),2);
  177.                     Core.rectangle(image, r.boundingRect().tl(), r.boundingRect().br(), new Scalar(50,50,50));
  178.                 }
  179.                 //fine rectangle
  180.                 int[] buff = new int[4];
  181.                 int[] zx=new int[1];
  182.                 int[] zxx=new int[1];
  183.                 for(int i1=0;i1<hull_.size().height;i1++){
  184.                     if(i1<hull_.size().height-1){
  185.                         hull_.get(i1,0,zx);
  186.                         hull_.get(i1+1,0,zxx);
  187.                     }
  188.                     else {
  189.                         hull_.get(i1,0,zx);
  190.                         hull_.get(0,0,zxx);
  191.                     }
  192.                     if(draws) {
  193.                         Core.line(image, pts.get(zx[0]), pts.get(zxx[0]), new Scalar(140,140,140),2);
  194.                     }
  195.                 }
  196.  
  197.                 for(int i1=0;i1<convexityDefects.size().height;i1++){
  198.                     convexityDefects.get(i1, 0,buff);
  199.                     if(buff[3]/256>depthThreshold){
  200.                         if(pts.get(buff[2]).x>0 && pts.get(buff[2]).x<1024 && pts.get(buff[2]).y>0 && pts.get(buff[2]).y<768){
  201.                             defects.add(pts.get(buff[2]));
  202.                             Core.circle(image, pts.get(buff[2]), 6, new Scalar(0,255,0));
  203.                             if(draws) {
  204.                                 Core.circle(image, pts.get(buff[2]), 6, new Scalar(0,255,0));
  205.                             }
  206.                         }
  207.                     }
  208.                 }
  209.                 if (defects.size()<3){
  210.                     int dim=pts.size();
  211.                     Core.circle(image, pts.get(0), 3, new Scalar(0,255,0),2);
  212.                     Core.circle(image, pts.get(0+dim/4), 3, new Scalar(0,255,0),2);
  213.                     defects.add(pts.get(0));
  214.                     defects.add(pts.get(0+dim/4));
  215.                 }
  216.             }
  217.         }
  218.         return defects;
  219.     }
  220.  
  221.     public List<MatOfPoint> searchOutline(Mat original, Mat image,boolean draws, boolean drawEverything, int pixelFilter){
  222.         List<MatOfPoint> contours = new LinkedList<MatOfPoint>();
  223.         List<MatOfPoint> contoursBig = new LinkedList<MatOfPoint>();
  224.         Mat hierarchy= new Mat();
  225.  
  226.         Imgproc.findContours(image,contours , hierarchy ,Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_NONE,new Point(0,0));
  227.  
  228.         for(int i=0;i<contours.size();i++) {
  229.             if(contours.get(i).size().height>pixelFilter){
  230.                 contoursBig.add(contours.get(i));
  231.                 if(draws && !drawEverything)
  232.                     Imgproc.drawContours(original, contours,i,new Scalar(0,255,0),2,8,hierarchy,0,new Point());
  233.             }
  234.             if(drawEverything && !draws)
  235.                 Imgproc.drawContours(original, contours,i,new Scalar(0,255,255),2,8,hierarchy,0,new Point());
  236.         }
  237.         return contoursBig;
  238.     }
  239.  
  240.     public Point centerPalm(Mat image,List<Point> defects){
  241.         MatOfPoint2f pr=new MatOfPoint2f();
  242.         Point center=new Point();
  243.         float[] radius=new float[1];
  244.         pr.create((int)(defects.size()), 1, CvType.CV_32S);
  245.         pr.fromList(defects);
  246.  
  247.         if (pr.size().height>0){
  248.             start=true;
  249.             Imgproc.minEnclosingCircle(pr, center, radius);
  250.         } else {
  251.             start=false;
  252.         }
  253.         return center;
  254.     }
  255.  
  256.     public Point movingAverageFilter(List<Point> buffer, Point current){
  257.         Point media=new Point();
  258.         media.x=0;
  259.         media.y=0;
  260.         for(int i=buffer.size()-1;i>0;i--){
  261.             buffer.set(i, buffer.get(i-1));
  262.             media.x=media.x+buffer.get(i).x;
  263.             media.y=media.y+buffer.get(i).y;
  264.         }
  265.         buffer.set(0, current);
  266.         media.x=(media.x+buffer.get(0).x)/buffer.size();
  267.         media.y=(media.y+buffer.get(0).y)/buffer.size();
  268.         return media;
  269.     }
  270.  
  271.     public List<Point> fingers(Mat image,List<Point> outlinePoints,Point center){
  272.         List<Point> fingerPoints=new LinkedList<Point>();
  273.         List<Point> fingers=new LinkedList<Point>();
  274.         int interval=55;
  275.         for(int j=0;j<outlinePoints.size();j++){
  276.             Point prec=new Point();
  277.             Point vertice=new Point();
  278.             Point next=new Point();
  279.             vertice=outlinePoints.get(j);
  280.             if(j-interval>0){
  281.  
  282.                 prec=outlinePoints.get(j-interval);
  283.             } else {
  284.                 int a=interval-j;
  285.                 prec=outlinePoints.get(outlinePoints.size()-a-1);
  286.             }
  287.             if(j+interval<outlinePoints.size()){
  288.                 next=outlinePoints.get(j+interval);
  289.             } else {
  290.                 int a=j+interval-outlinePoints.size();
  291.                 next=outlinePoints.get(a);
  292.             }
  293.  
  294.             Point v1= new Point();
  295.             Point v2= new Point();
  296.             v1.x=vertice.x-next.x;
  297.             v1.y=vertice.y-next.y;
  298.             v2.x=vertice.x-prec.x;
  299.             v2.y=vertice.y-prec.y;
  300.             double dotproduct = (v1.x*v2.x) + (v1.y*v2.y);
  301.             double length1 = Math.sqrt((v1.x*v1.x)+(v1.y*v1.y));
  302.             double length2 = Math.sqrt((v2.x*v2.x)+(v2.y*v2.y));
  303.             double angle = Math.acos(dotproduct/(length1*length2));
  304.             angle=angle*180/Math.PI;
  305.             if(angle<60) {
  306.                 double centroprec=Math.sqrt(((prec.x-center.x)*(prec.x-center.x))+((prec.y-center.y)*(prec.y-center.y)));
  307.                 double centrovert=Math.sqrt(((vertice.x-center.x)*(vertice.x-center.x))+((vertice.y-center.y)*(vertice.y-center.y)));
  308.                 double centronext=Math.sqrt(((next.x-center.x)*(next.x-center.x))+((next.y-center.y)*(next.y-center.y)));
  309.                 if(centroprec<centrovert && centronext<centrovert){
  310.                     fingerPoints.add(vertice);
  311.                     //Core.circle(image, vertice, 2, new Scalar(200,0,230));
  312.                     //Core.line(image, vertice, center, new Scalar(0,255,255));
  313.                 }
  314.             }
  315.         }
  316.  
  317.         Point media=new Point();
  318.         media.x=0;
  319.         media.y=0;
  320.         int med=0;
  321.         boolean t=false;
  322.         if (fingerPoints.size()>0){
  323.             double dif=Math.sqrt(((fingerPoints.get(0).x-fingerPoints.get(fingerPoints.size()-1).x)*(fingerPoints.get(0).x-fingerPoints.get(fingerPoints.size()-1).x))+((fingerPoints.get(0).y-fingerPoints.get(fingerPoints.size()-1).y)*(fingerPoints.get(0).y-fingerPoints.get(fingerPoints.size()-1).y)));
  324.             if(dif<=20){
  325.                 t=true;
  326.             }
  327.         }
  328.         for (int i=0;i<fingerPoints.size()-1;i++){
  329.             double d=Math.sqrt(((fingerPoints.get(i).x-fingerPoints.get(i+1).x)*(fingerPoints.get(i).x-fingerPoints.get(i+1).x))+((fingerPoints.get(i).y-fingerPoints.get(i+1).y)*(fingerPoints.get(i).y-fingerPoints.get(i+1).y)));
  330.  
  331.             if (d>20 || i+1==fingerPoints.size()-1){
  332.                 Point p=new Point();
  333.                 p.x=(int)(media.x/med);
  334.                 p.y=(int)(media.y/med);
  335.  
  336.                 fingers.add(p);
  337.  
  338.                 if(t && i+1==fingerPoints.size()-1){
  339.                     Point ult=new Point();
  340.                     if(fingers.size()>1){
  341.                         ult.x=(fingers.get(0).x+fingers.get(fingers.size()-1).x)/2;
  342.                         ult.y=(fingers.get(0).y+fingers.get(fingers.size()-1).y)/2;
  343.                         fingers.set(0, ult);
  344.                         fingers.remove(fingers.size()-1);
  345.                     }
  346.                 }
  347.                 med=0;
  348.                 media.x=0;
  349.                 media.y=0;
  350.             } else {
  351.                 media.x=(media.x+fingerPoints.get(i).x);
  352.                 media.y=(media.y+fingerPoints.get(i).y);
  353.                 med++;
  354.             }
  355.         }
  356.         return fingers;
  357.     }
  358.  
  359.     public List<Point> outlineList(Mat image,int pixelFilter){
  360.         List<MatOfPoint> contours = new LinkedList<MatOfPoint>();
  361.         List<MatOfPoint> contoursBig = new LinkedList<MatOfPoint>();
  362.         List<Point> pointsList=new LinkedList<Point>();
  363.         Mat hierarchy= new Mat();
  364.  
  365.         Imgproc.findContours(image,contours , hierarchy ,Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_NONE,new Point(0,0));
  366.  
  367.         for(int i=0;i<contours.size();i++) {
  368.             if(contours.get(i).size().height>pixelFilter){
  369.                 contoursBig.add(contours.get(i));
  370.             }
  371.         }
  372.         if(contoursBig.size()>0){
  373.             pointsList=contoursBig.get(0).toList();
  374.         }
  375.         return pointsList;
  376.     }
  377.  
  378.     public int drawPalmsCenterFingers(Mat image,Point center,Point finger,List<Point> fingers) throws URISyntaxException {
  379.         Core.line(image,new Point(150,50),new Point(730,50), new Scalar(255,0,0),2);
  380.         Core.line(image,new Point(150,380),new Point(730,380), new Scalar(255,0,0),2);
  381.         Core.line(image,new Point(150,50),new Point(150,380), new Scalar(255,0,0),2);
  382.         Core.line(image,new Point(730,50),new Point(730,380), new Scalar(255,0,0),2);
  383.  
  384.  
  385.         if (fingers.size()==1){
  386.             Core.line(image, center, finger, new Scalar(0, 255, 255),4);
  387.             Core.circle(image, finger, 3, new Scalar(255,0,255),3);
  388.         }
  389.         else {
  390.             for (int i=0;i<fingers.size();i++){
  391.                 Core.line(image, center, fingers.get(i), new Scalar(0, 255, 255),4);
  392.                 Core.circle(image, fingers.get(i), 3, new Scalar(255,0,255),3);
  393.             }
  394.             numberOfFingersLabel.setText("Number of fingers: " + Integer.toString(fingers.size()));
  395.         }
  396.         Core.circle(image, center, 3, new Scalar(0,0,255),3);
  397.  
  398.         return fingers.size();
  399.     }
  400.  
  401.     public static <T> T mostCommon(List<T> list) {
  402.         Map<T, Integer> map = new HashMap<>();
  403.  
  404.         for (T t : list) {
  405.             Integer val = map.get(t);
  406.             map.put(t, val == null ? 1 : val + 1);
  407.         }
  408.  
  409.         Map.Entry<T, Integer> max = null;
  410.  
  411.         for (Map.Entry<T, Integer> e : map.entrySet()) {
  412.             if (max == null || e.getValue() > max.getValue())
  413.                 max = e;
  414.         }
  415.  
  416.         return max.getKey();
  417.     }
  418.  
  419.     public void frametolabel(Mat matframe){
  420.         MatOfByte cc=new MatOfByte();
  421.         Highgui.imencode(".JPG", matframe, cc);
  422.         byte[] bytes= cc.toArray();
  423.         InputStream ss=new ByteArrayInputStream(bytes);
  424.         try {
  425.             BufferedImage aa= ImageIO.read(ss);
  426.             label.setIcon(new ImageIcon(aa));
  427.         } catch (IOException e) {
  428.             e.printStackTrace();
  429.         }
  430.     }
  431.  
  432.     public static void main(String[] args) throws URISyntaxException, InterruptedException {
  433.         System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
  434.         HandDetector handDetector = new HandDetector();
  435.         VideoCapture webcam = new VideoCapture(0);
  436.         webcam.set(Highgui.CV_CAP_PROP_FRAME_HEIGHT, 500);
  437.         webcam.set(Highgui.CV_CAP_PROP_FRAME_WIDTH, 700);
  438.         handDetector.setFrame(webcam);
  439.         Mat mimm = new Mat();
  440.         Mat modified;
  441.         List<Point> buffer=new LinkedList<Point>();
  442.         Point center=new Point();
  443.         List<Point> fingers;
  444.         List<Point> bufferFingers=new LinkedList<Point>();
  445.         Point finger=new Point();
  446.         List<Integer> listOfMeasurment = new ArrayList<>();
  447.  
  448.         while (true && !close) {
  449.             if (!webcam.isOpened() && !close) {
  450.                 System.out.println("Camera Error");
  451.             } else {
  452.                 List<Point> defects;
  453.                 if (!close) {
  454.                     webcam.retrieve(mimm);
  455.                     handDetector.frameToLabel(mimm);
  456.                     // H(0-180), S(0-255), V(0-255)
  457.                     // do zmiany tylko V - jasność
  458.                     // czarna rękawiczka 0-40
  459.                     modified = handDetector.morphologicalFilter(2, 7, handDetector.hsvColorFilter(0, 0, 0, 180, 255, 40, mimm));
  460.                     defects= handDetector.inviluppodifetti(mimm,handDetector.searchOutline(mimm, modified, false, false, 450), false, 5);
  461.  
  462.                     if(buffer.size()<7){
  463.                         buffer.add(handDetector.centerPalm(mimm,defects));
  464.                     }
  465.                     else {
  466.                         center=handDetector.movingAverageFilter(buffer, handDetector.centerPalm(mimm,defects));
  467.                     }
  468.  
  469.                     fingers=handDetector.fingers(mimm, handDetector.outlineList(modified, 200), center);
  470.  
  471.                     if(fingers.size()==1 && bufferFingers.size()<5){
  472.                         bufferFingers.add(fingers.get(0));
  473.                         finger=fingers.get(0);
  474.                     }
  475.                     else {
  476.                         if(fingers.size()==1){
  477.                             finger=handDetector.movingAverageFilter(bufferFingers, fingers.get(0));
  478.                         }
  479.                     }
  480.  
  481.  
  482.                     int a = handDetector.drawPalmsCenterFingers(mimm, center, finger, fingers);
  483.  
  484.                     listOfMeasurment.add(a);
  485.  
  486.                     if (listOfMeasurment.size() == 50) {
  487.                         int ints = mostCommon(listOfMeasurment);
  488.                         switch (ints) {
  489.                             case 0:
  490.                                 System.out.println("0 fingers!");
  491.                                 break;
  492.                             case 1:
  493.                                 ProcessBuilder pb = new ProcessBuilder("Notepad.exe", "myfile.txt");
  494.                                 try {
  495.                                     pb.start();
  496.                                 } catch (IOException e) {
  497.                                     e.printStackTrace();
  498.                                 }
  499.                                 break;
  500.                             case 2:
  501.                                 URI uri = new URI("www.onet.pl");
  502.                                 try {
  503.                                     Desktop.getDesktop().browse(uri);
  504.                                 } catch (IOException e) {
  505.                                     e.printStackTrace();
  506.                                 }
  507.                                 break;
  508.                             case 3:
  509.                                 try {
  510.                                     Runtime.getRuntime().exec("calc");
  511.                                 } catch (IOException e) {
  512.                                     e.printStackTrace();
  513.                                 }
  514.                             case 4:
  515.                                 URI uri2 = new URI("www.pudelek.pl");
  516.                                 try {
  517.                                     Desktop.getDesktop().browse(uri2);
  518.                                 } catch (IOException e) {
  519.                                     e.printStackTrace();
  520.                                 }
  521.                                 break;
  522.                             case 5:
  523.                                 URI uri3 = new URI("www.agh.pl");
  524.                                 try {
  525.                                     Desktop.getDesktop().browse(uri3);
  526.                                 } catch (IOException e) {
  527.                                     e.printStackTrace();
  528.                                 }
  529.                                 break;
  530.                             default:
  531.                                 System.out.println("Amount of fingers is not defined!");
  532.                         }
  533.                         listOfMeasurment.clear();
  534.                         sleep(2000);
  535.                     }
  536.                     handDetector.frametolabel(mimm);
  537.                 }
  538.             }
  539.         }
  540.     }
  541. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement