Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package udp.server; import java.awt.AWTException; import java.awt.Graphics; //import java.awt.Panel; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Semaphore; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JFrame; import javax.swing.JPanel; import org.opencv.core.Core; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.core.MatOfPoint; import org.opencv.core.Point; import org.opencv.core.Scalar; import org.opencv.core.Size; import org.opencv.highgui.VideoCapture; import org.opencv.imgproc.Imgproc; import org.opencv.imgproc.Moments; /** * * @author mgrib */ public class ObjectTracker implements Runnable { private DataHandler dh; private Semaphore semaphore; private CameraCapture camCap; private VideoCapture capture; private Mat webcam_image; private Mat hsv_image; private Mat thresholded; private Mat thresholded2; private double[] data; private Mat circles; private double[] hsv_values; private Scalar hsv_min; private Scalar hsv_max; private List<Mat> lhsv; private Mat array255; private Mat distance; //Blball //Flaske private int hueMin = 29;//104; //40;//35; private int hueMax = 38;//115; //68;//74; private int satMin = 66;//185;//51;//93; private int satMax = 195;//255;//255;//223; private int valMin = 71;//36;//38;//74; private int valMax = 255;//100;//167;//14335; // Flaske Hue[40 68] Sat[51 255] Val[38 167] // Blball Hue[104 115] Sat[185 255] Val[36 100] Fungerer ikke // Tennisball Hue[29 38] Sat[66 195] Val[71 255] private double brightness; private double contrast; private float angleErrorX; private float angleErrorY; List<MatOfPoint> contours; public ObjectTracker(DataHandler dh, Semaphore semaphore, CameraCapture camCap) { this.dh = dh; this.semaphore = semaphore; this.camCap = camCap; //System.loadLibrary(Core.NATIVE_LIBRARY_NAME); try { createMat(); createFrames(); setColorTrackingValues(); //trackColors(); } catch (AWTException e) { e.printStackTrace(); } } @Override public void run() { this.trackColors(); } private void createFrames() throws AWTException { //capture = new VideoCapture(1); //capture.set(3, 1280); //capture.set(3, 1366); // 500 //capture.set(4, 720); //capture.set(4, 768); // 400 //capture.set(15, -3); //capture.read(webcam_image); webcam_image = this.camCap.getFrame(); array255 = new Mat(480, 640, CvType.CV_8UC1); //array255 = new Mat(webcam_image.height(),webcam_image.width(),CvType.CV_8UC1); array255.setTo(new Scalar(255)); distance = new Mat(480, 640, CvType.CV_8UC1); //distance=new Mat(webcam_image.height(),webcam_image.width(),CvType.CV_8UC1); lhsv = new ArrayList<>(3); circles = new Mat(); } private void trackColors() { while (true) { //capture.read(webcam_image); //System.out.println(this.camCap.getFrame().size()); webcam_image = this.camCap.getFrame().clone(); if (!webcam_image.empty()) { //Adjusting brightness and contrast webcam_image.convertTo(webcam_image, -1, brightness, contrast); //Adding blur to remove noise Imgproc.blur(webcam_image, webcam_image, new Size(7, 7)); // converting to HSV image Imgproc.cvtColor(webcam_image, hsv_image, Imgproc.COLOR_BGR2HSV); //Checking if the hsv image is in range. Core.inRange(hsv_image, hsv_min, hsv_max, thresholded); Imgproc.erode(thresholded, thresholded, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(8, 8))); Imgproc.dilate(thresholded, thresholded, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(8, 8))); Core.split(hsv_image, lhsv); // We get 3 2D one channel Mats Mat S = lhsv.get(1); Mat V = lhsv.get(2); Core.subtract(array255, S, S); Core.subtract(array255, V, V); S.convertTo(S, CvType.CV_32F); V.convertTo(V, CvType.CV_32F); Core.magnitude(S, V, distance); Core.inRange(distance, new Scalar(0.0), new Scalar(200.0), thresholded2); Imgproc.GaussianBlur(thresholded, thresholded, new Size(9, 9), 0, 0); Imgproc.HoughCircles(thresholded, circles, Imgproc.CV_HOUGH_GRADIENT, 2, thresholded.height() / 8, 200, 100, 0, 0); Imgproc.findContours(thresholded, contours, thresholded2, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE); //------Imgproc.drawContours(webcam_image, contours, -1, new Scalar(255, 0, 0), 2); //------Core.circle(webcam_image, new Point(210,210), 10, new Scalar(100,10,10),3); data = webcam_image.get(210, 210); //------Core.putText(webcam_image,String.format("("+String.valueOf(data[0])+","+String.valueOf(data[1])+","+String.valueOf(data[2])+")"),new Point(30, 30) , 3 //FONT_HERSHEY_SCRIPT_SIMPLEX //------ ,1.0,new Scalar(100,10,10,255),3); //ArrayList<Float> errorAngles = new ArrayList<>(); ArrayList<Float> errorAngles = getTargetError(); if (errorAngles != null) { try { semaphore.acquire(); } catch (InterruptedException ex) { Logger.getLogger(ObjectTracker.class.getName()).log(Level.SEVERE, null, ex); } float eXa = (errorAngles.get(0)); float eYa = (errorAngles.get(1)); this.dh.setPixyXvalue(eXa); this.dh.setPixyYvalue(eYa); //System.out.print("AngleErrorX: "+errorAngles.get(0)); //System.out.println(" AngleErrorY: "+ errorAngles.get(1)); semaphore.release(); } } /*else { System.out.println(" --(!) No captured frame -- Break!"); } */ } } private void createMat() { webcam_image = new Mat(); hsv_image = new Mat(); thresholded = new Mat(); thresholded2 = new Mat(); data = new double[3]; circles = new Mat(); lhsv = new ArrayList<>(3); // new ArrayList<Mat>(3); array255 = new Mat(webcam_image.height(), webcam_image.width(), CvType.CV_8UC1); array255.setTo(new Scalar(255)); distance = new Mat(webcam_image.height(), webcam_image.width(), CvType.CV_8UC1); hsv_min = new Scalar(1, 1, 1); hsv_max = new Scalar(1, 1, 1); contours = new ArrayList<>(); // new ArrayList<MatOfPoint>(); } private ArrayList<Float> getTargetError() { ArrayList<Float> angles = null; int x = getX(contours); int y = getY(contours); contours.clear(); angles = new ArrayList<>(); if (x > 0) { Core.circle(webcam_image, new Point(x, y), 4, new Scalar(50, 49, 0, 255), 4); float centerX = webcam_image.width() / 2; float centerY = webcam_image.height() / 2; // CenterCirle Core.circle(webcam_image, new Point(centerX, centerY), 4, new Scalar(50, 49, 0, 255), 4); // Setup camera angles (from producer) float cameraAngleX = 60.0f; //70.42f; float cameraAngleY = 43.30f; // Calculate difference from x and y to center float pixErrorX = x - centerX; float pixErrorY = -y + centerY; // Calculate angle error in x and y direction angleErrorX = (pixErrorX / centerX) * cameraAngleX; angleErrorY = (pixErrorY / centerY) * cameraAngleY; Core.line(webcam_image, new Point(x, y), new Point(centerX, centerY), new Scalar(150, 150, 100)/*CV_BGR(100,10,10)*/, 3); //angles = new float[]{angleErrorX, angleErrorY}; //angles.add(angleErrorX); //angles.add(angleErrorY); } else { if (angleErrorX > 0) { angleErrorX = 255; angleErrorY = 255; } else { angleErrorX = -255; angleErrorY = -255; } } angles.add(angleErrorX); angles.add(angleErrorY); return angles; } private void setColorTrackingValues() { double[] HsvMin = new double[] { this.hueMin, this.satMin, this.valMin }; //{35, 93, 74}; hsv_min.set(HsvMin); double[] HsvMax = new double[] { this.hueMax, this.satMax, this.valMax }; //{74,223,14335}; hsv_max.set(HsvMax); brightness = 1.0; contrast = 1.0; } public int getX(List<MatOfPoint> contours) { List<Moments> mu = new ArrayList<>(contours.size()); int x = 0; for (int i = 0; i < contours.size(); i++) { mu.add(i, Imgproc.moments(contours.get(i), false)); Moments p = mu.get(i); x = (int) (p.get_m10() / p.get_m00()); } return x; } public int getY(List<MatOfPoint> contours) { List<Moments> mu = new ArrayList<>(contours.size()); int y = 0; for (int i = 0; i < contours.size(); i++) { mu.add(i, Imgproc.moments(contours.get(i), false)); Moments p = mu.get(i); y = (int) (p.get_m01() / p.get_m00()); } return y; } }