Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import javax.imageio.ImageIO;
- import javax.swing.*;
- import javax.swing.filechooser.FileSystemView;
- import org.opencv.core.Core;
- import org.opencv.core.CvType;
- import org.opencv.core.Mat;
- import org.opencv.core.MatOfByte;
- import org.opencv.core.MatOfInt;
- import org.opencv.core.MatOfInt4;
- import org.opencv.core.MatOfPoint;
- import org.opencv.core.MatOfPoint2f;
- import org.opencv.core.Point;
- import org.opencv.core.RotatedRect;
- import org.opencv.core.Scalar;
- import org.opencv.core.Size;
- import org.opencv.highgui.Highgui;
- import org.opencv.highgui.VideoCapture;
- import org.opencv.imgproc.Imgproc;
- import org.opencv.utils.Converters;
- import java.awt.*;
- import java.awt.event.*;
- import java.awt.image.BufferedImage;
- import java.io.ByteArrayInputStream;
- import java.io.File;
- import java.io.IOException;
- import java.io.InputStream;
- import java.net.URI;
- import java.net.URISyntaxException;
- import java.util.*;
- import java.util.List;
- import static java.lang.Thread.sleep;
- public class HandDetector extends JPanel {
- private static final long serialVersionUID = 1L;
- private JFrame frame = new JFrame("Hand detector");
- private JLabel label = new JLabel();
- private JButton saveBtn = new JButton("Save one picture");
- private JButton saveSeriesBtn = new JButton("Save series of pictures");
- private JFileChooser fileChooser = new JFileChooser(FileSystemView.getFileSystemView().getHomeDirectory());
- private String onePictureSavePath;
- private Boolean savedOnePicture = false;
- private Boolean savedPictureSeries = false;
- private JLabel numberOfFingersLabel = new JLabel();
- private static boolean start = false;
- public int counter;
- private static boolean close = false;
- public HandDetector() {
- counter = 0;
- }
- public void setFrame(final org.opencv.highgui.VideoCapture webcam) {
- frame.setSize(1024, 768);
- frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- frame.setVisible(true);
- frame.getContentPane().add(label);
- saveBtn.setBounds(0,0,200,100);
- saveBtn.setVisible(true);
- label.add(saveBtn);
- numberOfFingersLabel.setBounds(500, 0, 300, 100);
- numberOfFingersLabel.setFont(new Font("Courier New", Font.BOLD, 24));
- label.add(numberOfFingersLabel);
- saveSeriesBtn.setBounds(250,0,200,100);
- saveSeriesBtn.setVisible(true);
- label.add(saveSeriesBtn);
- saveBtn.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- int returnValue = fileChooser.showSaveDialog(null);
- if (returnValue == JFileChooser.APPROVE_OPTION) {
- onePictureSavePath = fileChooser.getSelectedFile().toString();
- savedOnePicture = false;
- }
- }
- });
- saveSeriesBtn.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- savedPictureSeries = true;
- }
- });
- }
- public void frameToLabel(Mat matFrame) {
- MatOfByte cc = new MatOfByte();
- Highgui.imencode(".JPG", matFrame, cc);
- byte[] bytes = cc.toArray();
- InputStream ss = new ByteArrayInputStream(bytes);
- try {
- BufferedImage aa = ImageIO.read(ss);
- label.setIcon(new ImageIcon(aa));
- if(!savedOnePicture && (onePictureSavePath != null)) {
- fetchOnePicture(onePictureSavePath, aa);
- savedOnePicture = true;
- }
- if(savedPictureSeries) {
- if(counter < 5) {
- fetchSeriesOfPictures(counter, aa);
- counter++;
- } else {
- savedPictureSeries = false;
- counter = 0;
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- public void fetchOnePicture(String path, BufferedImage aa) throws IOException {
- File outputFile = new File(path);
- ImageIO.write(aa, "jpg", outputFile);
- }
- public void fetchSeriesOfPictures(int i, BufferedImage aa) throws IOException {
- String filename = "C:\\Users\\pfilipowicz\\Desktop\\images\\image" + String.valueOf(i) + ".jpg";
- fetchOnePicture(filename, aa);
- }
- public Mat morphologicalFilter(int kd,int ke,Mat image){
- Mat modified=new Mat();
- Imgproc.erode(image, modified, Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(ke,ke)));
- Imgproc.dilate(modified, modified, Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(kd,kd)));
- return modified;
- }
- public Mat hsvColorFilter(int h,int s,int v,int h1,int s1,int v1,Mat image){
- Mat modified = new Mat();
- if(image!=null){
- Core.inRange(image, new Scalar(h,s,v), new Scalar(h1,s1,v1), modified);
- } else{
- System.out.println("Error image");
- }
- return modified;
- }
- public List<Point> inviluppodifetti(Mat image,List<MatOfPoint> contours,boolean draws,int depthThreshold){
- List<Point> defects=new LinkedList<Point>();
- for(int i=0;i<contours.size();i++){
- MatOfInt hull_=new MatOfInt();
- MatOfInt4 convexityDefects=new MatOfInt4();
- @SuppressWarnings("unused")
- List<Point> outlinePoints = new LinkedList<Point>();
- outlinePoints=contours.get(i).toList();
- Imgproc.convexHull(contours.get(i), hull_);
- if (hull_.size().height>=4){
- Imgproc.convexityDefects(contours.get(i), hull_, convexityDefects);
- List<Point> pts=new ArrayList<Point>();
- MatOfPoint2f pr=new MatOfPoint2f();
- Converters.Mat_to_vector_Point(contours.get(i), pts);
- //rectangle
- pr.create((int)(pts.size()), 1, CvType.CV_32S);
- pr.fromList(pts);
- if(pr.height()>10){
- RotatedRect r=Imgproc.minAreaRect(pr);
- Point[] rect=new Point[4];
- r.points(rect);
- Core.line(image, rect[0], rect[1],new Scalar(0,100,0),2);
- Core.line(image, rect[0], rect[3],new Scalar(0,100,0),2);
- Core.line(image, rect[1], rect[2],new Scalar(0,100,0),2);
- Core.line(image, rect[2], rect[3],new Scalar(0,100,0),2);
- Core.rectangle(image, r.boundingRect().tl(), r.boundingRect().br(), new Scalar(50,50,50));
- }
- //fine rectangle
- int[] buff = new int[4];
- int[] zx=new int[1];
- int[] zxx=new int[1];
- for(int i1=0;i1<hull_.size().height;i1++){
- if(i1<hull_.size().height-1){
- hull_.get(i1,0,zx);
- hull_.get(i1+1,0,zxx);
- }
- else {
- hull_.get(i1,0,zx);
- hull_.get(0,0,zxx);
- }
- if(draws) {
- Core.line(image, pts.get(zx[0]), pts.get(zxx[0]), new Scalar(140,140,140),2);
- }
- }
- for(int i1=0;i1<convexityDefects.size().height;i1++){
- convexityDefects.get(i1, 0,buff);
- if(buff[3]/256>depthThreshold){
- 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){
- defects.add(pts.get(buff[2]));
- Core.circle(image, pts.get(buff[2]), 6, new Scalar(0,255,0));
- if(draws) {
- Core.circle(image, pts.get(buff[2]), 6, new Scalar(0,255,0));
- }
- }
- }
- }
- if (defects.size()<3){
- int dim=pts.size();
- Core.circle(image, pts.get(0), 3, new Scalar(0,255,0),2);
- Core.circle(image, pts.get(0+dim/4), 3, new Scalar(0,255,0),2);
- defects.add(pts.get(0));
- defects.add(pts.get(0+dim/4));
- }
- }
- }
- return defects;
- }
- public List<MatOfPoint> searchOutline(Mat original, Mat image,boolean draws, boolean drawEverything, int pixelFilter){
- List<MatOfPoint> contours = new LinkedList<MatOfPoint>();
- List<MatOfPoint> contoursBig = new LinkedList<MatOfPoint>();
- Mat hierarchy= new Mat();
- Imgproc.findContours(image,contours , hierarchy ,Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_NONE,new Point(0,0));
- for(int i=0;i<contours.size();i++) {
- if(contours.get(i).size().height>pixelFilter){
- contoursBig.add(contours.get(i));
- if(draws && !drawEverything)
- Imgproc.drawContours(original, contours,i,new Scalar(0,255,0),2,8,hierarchy,0,new Point());
- }
- if(drawEverything && !draws)
- Imgproc.drawContours(original, contours,i,new Scalar(0,255,255),2,8,hierarchy,0,new Point());
- }
- return contoursBig;
- }
- public Point centerPalm(Mat image,List<Point> defects){
- MatOfPoint2f pr=new MatOfPoint2f();
- Point center=new Point();
- float[] radius=new float[1];
- pr.create((int)(defects.size()), 1, CvType.CV_32S);
- pr.fromList(defects);
- if (pr.size().height>0){
- start=true;
- Imgproc.minEnclosingCircle(pr, center, radius);
- } else {
- start=false;
- }
- return center;
- }
- public Point movingAverageFilter(List<Point> buffer, Point current){
- Point media=new Point();
- media.x=0;
- media.y=0;
- for(int i=buffer.size()-1;i>0;i--){
- buffer.set(i, buffer.get(i-1));
- media.x=media.x+buffer.get(i).x;
- media.y=media.y+buffer.get(i).y;
- }
- buffer.set(0, current);
- media.x=(media.x+buffer.get(0).x)/buffer.size();
- media.y=(media.y+buffer.get(0).y)/buffer.size();
- return media;
- }
- public List<Point> fingers(Mat image,List<Point> outlinePoints,Point center){
- List<Point> fingerPoints=new LinkedList<Point>();
- List<Point> fingers=new LinkedList<Point>();
- int interval=55;
- for(int j=0;j<outlinePoints.size();j++){
- Point prec=new Point();
- Point vertice=new Point();
- Point next=new Point();
- vertice=outlinePoints.get(j);
- if(j-interval>0){
- prec=outlinePoints.get(j-interval);
- } else {
- int a=interval-j;
- prec=outlinePoints.get(outlinePoints.size()-a-1);
- }
- if(j+interval<outlinePoints.size()){
- next=outlinePoints.get(j+interval);
- } else {
- int a=j+interval-outlinePoints.size();
- next=outlinePoints.get(a);
- }
- Point v1= new Point();
- Point v2= new Point();
- v1.x=vertice.x-next.x;
- v1.y=vertice.y-next.y;
- v2.x=vertice.x-prec.x;
- v2.y=vertice.y-prec.y;
- double dotproduct = (v1.x*v2.x) + (v1.y*v2.y);
- double length1 = Math.sqrt((v1.x*v1.x)+(v1.y*v1.y));
- double length2 = Math.sqrt((v2.x*v2.x)+(v2.y*v2.y));
- double angle = Math.acos(dotproduct/(length1*length2));
- angle=angle*180/Math.PI;
- if(angle<60) {
- double centroprec=Math.sqrt(((prec.x-center.x)*(prec.x-center.x))+((prec.y-center.y)*(prec.y-center.y)));
- double centrovert=Math.sqrt(((vertice.x-center.x)*(vertice.x-center.x))+((vertice.y-center.y)*(vertice.y-center.y)));
- double centronext=Math.sqrt(((next.x-center.x)*(next.x-center.x))+((next.y-center.y)*(next.y-center.y)));
- if(centroprec<centrovert && centronext<centrovert){
- fingerPoints.add(vertice);
- //Core.circle(image, vertice, 2, new Scalar(200,0,230));
- //Core.line(image, vertice, center, new Scalar(0,255,255));
- }
- }
- }
- Point media=new Point();
- media.x=0;
- media.y=0;
- int med=0;
- boolean t=false;
- if (fingerPoints.size()>0){
- 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)));
- if(dif<=20){
- t=true;
- }
- }
- for (int i=0;i<fingerPoints.size()-1;i++){
- 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)));
- if (d>20 || i+1==fingerPoints.size()-1){
- Point p=new Point();
- p.x=(int)(media.x/med);
- p.y=(int)(media.y/med);
- fingers.add(p);
- if(t && i+1==fingerPoints.size()-1){
- Point ult=new Point();
- if(fingers.size()>1){
- ult.x=(fingers.get(0).x+fingers.get(fingers.size()-1).x)/2;
- ult.y=(fingers.get(0).y+fingers.get(fingers.size()-1).y)/2;
- fingers.set(0, ult);
- fingers.remove(fingers.size()-1);
- }
- }
- med=0;
- media.x=0;
- media.y=0;
- } else {
- media.x=(media.x+fingerPoints.get(i).x);
- media.y=(media.y+fingerPoints.get(i).y);
- med++;
- }
- }
- return fingers;
- }
- public List<Point> outlineList(Mat image,int pixelFilter){
- List<MatOfPoint> contours = new LinkedList<MatOfPoint>();
- List<MatOfPoint> contoursBig = new LinkedList<MatOfPoint>();
- List<Point> pointsList=new LinkedList<Point>();
- Mat hierarchy= new Mat();
- Imgproc.findContours(image,contours , hierarchy ,Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_NONE,new Point(0,0));
- for(int i=0;i<contours.size();i++) {
- if(contours.get(i).size().height>pixelFilter){
- contoursBig.add(contours.get(i));
- }
- }
- if(contoursBig.size()>0){
- pointsList=contoursBig.get(0).toList();
- }
- return pointsList;
- }
- public int drawPalmsCenterFingers(Mat image,Point center,Point finger,List<Point> fingers) throws URISyntaxException {
- Core.line(image,new Point(150,50),new Point(730,50), new Scalar(255,0,0),2);
- Core.line(image,new Point(150,380),new Point(730,380), new Scalar(255,0,0),2);
- Core.line(image,new Point(150,50),new Point(150,380), new Scalar(255,0,0),2);
- Core.line(image,new Point(730,50),new Point(730,380), new Scalar(255,0,0),2);
- if (fingers.size()==1){
- Core.line(image, center, finger, new Scalar(0, 255, 255),4);
- Core.circle(image, finger, 3, new Scalar(255,0,255),3);
- }
- else {
- for (int i=0;i<fingers.size();i++){
- Core.line(image, center, fingers.get(i), new Scalar(0, 255, 255),4);
- Core.circle(image, fingers.get(i), 3, new Scalar(255,0,255),3);
- }
- numberOfFingersLabel.setText("Number of fingers: " + Integer.toString(fingers.size()));
- }
- Core.circle(image, center, 3, new Scalar(0,0,255),3);
- return fingers.size();
- }
- public static <T> T mostCommon(List<T> list) {
- Map<T, Integer> map = new HashMap<>();
- for (T t : list) {
- Integer val = map.get(t);
- map.put(t, val == null ? 1 : val + 1);
- }
- Map.Entry<T, Integer> max = null;
- for (Map.Entry<T, Integer> e : map.entrySet()) {
- if (max == null || e.getValue() > max.getValue())
- max = e;
- }
- return max.getKey();
- }
- public void frametolabel(Mat matframe){
- MatOfByte cc=new MatOfByte();
- Highgui.imencode(".JPG", matframe, cc);
- byte[] bytes= cc.toArray();
- InputStream ss=new ByteArrayInputStream(bytes);
- try {
- BufferedImage aa= ImageIO.read(ss);
- label.setIcon(new ImageIcon(aa));
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- public static void main(String[] args) throws URISyntaxException, InterruptedException {
- System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
- HandDetector handDetector = new HandDetector();
- VideoCapture webcam = new VideoCapture(0);
- webcam.set(Highgui.CV_CAP_PROP_FRAME_HEIGHT, 500);
- webcam.set(Highgui.CV_CAP_PROP_FRAME_WIDTH, 700);
- handDetector.setFrame(webcam);
- Mat mimm = new Mat();
- Mat modified;
- List<Point> buffer=new LinkedList<Point>();
- Point center=new Point();
- List<Point> fingers;
- List<Point> bufferFingers=new LinkedList<Point>();
- Point finger=new Point();
- List<Integer> listOfMeasurment = new ArrayList<>();
- while (true && !close) {
- if (!webcam.isOpened() && !close) {
- System.out.println("Camera Error");
- } else {
- List<Point> defects;
- if (!close) {
- webcam.retrieve(mimm);
- handDetector.frameToLabel(mimm);
- // H(0-180), S(0-255), V(0-255)
- // do zmiany tylko V - jasność
- // czarna rękawiczka 0-40
- modified = handDetector.morphologicalFilter(2, 7, handDetector.hsvColorFilter(0, 0, 0, 180, 255, 40, mimm));
- defects= handDetector.inviluppodifetti(mimm,handDetector.searchOutline(mimm, modified, false, false, 450), false, 5);
- if(buffer.size()<7){
- buffer.add(handDetector.centerPalm(mimm,defects));
- }
- else {
- center=handDetector.movingAverageFilter(buffer, handDetector.centerPalm(mimm,defects));
- }
- fingers=handDetector.fingers(mimm, handDetector.outlineList(modified, 200), center);
- if(fingers.size()==1 && bufferFingers.size()<5){
- bufferFingers.add(fingers.get(0));
- finger=fingers.get(0);
- }
- else {
- if(fingers.size()==1){
- finger=handDetector.movingAverageFilter(bufferFingers, fingers.get(0));
- }
- }
- int a = handDetector.drawPalmsCenterFingers(mimm, center, finger, fingers);
- listOfMeasurment.add(a);
- if (listOfMeasurment.size() == 50) {
- int ints = mostCommon(listOfMeasurment);
- switch (ints) {
- case 0:
- System.out.println("0 fingers!");
- break;
- case 1:
- ProcessBuilder pb = new ProcessBuilder("Notepad.exe", "myfile.txt");
- try {
- pb.start();
- } catch (IOException e) {
- e.printStackTrace();
- }
- break;
- case 2:
- URI uri = new URI("www.onet.pl");
- try {
- Desktop.getDesktop().browse(uri);
- } catch (IOException e) {
- e.printStackTrace();
- }
- break;
- case 3:
- try {
- Runtime.getRuntime().exec("calc");
- } catch (IOException e) {
- e.printStackTrace();
- }
- case 4:
- URI uri2 = new URI("www.pudelek.pl");
- try {
- Desktop.getDesktop().browse(uri2);
- } catch (IOException e) {
- e.printStackTrace();
- }
- break;
- case 5:
- URI uri3 = new URI("www.agh.pl");
- try {
- Desktop.getDesktop().browse(uri3);
- } catch (IOException e) {
- e.printStackTrace();
- }
- break;
- default:
- System.out.println("Amount of fingers is not defined!");
- }
- listOfMeasurment.clear();
- sleep(2000);
- }
- handDetector.frametolabel(mimm);
- }
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement