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 intrudersrecorder; import com.sun.deploy.net.DownloadEngine; import java.io.ByteArrayInputStream; import java.net.URL; import java.util.ArrayList; import java.util.LinkedList; import java.util.Queue; import java.util.ResourceBundle; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.geometry.Insets; import javafx.scene.control.Label; import javafx.scene.control.Slider; import javafx.scene.control.ToggleButton; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.paint.Color; import javafx.scene.text.Font; import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.core.MatOfByte; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; import org.opencv.videoio.VideoCapture; import org.opencv.videoio.Videoio; /** * * @author myotherself */ public class MainFXMLDocumentController implements Initializable { static { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); } // FXML NODES @FXML private ImageView imageView; @FXML private ToggleButton cameraSwitch; @FXML private Color x2; @FXML private Font x1; @FXML private Insets x3; @FXML private Slider resWidthSlider; @FXML private Label resHeight; @FXML private Slider resHeightSlider; @FXML private Label pixDiff; @FXML private Slider pixDiffSlider; @FXML private Label objSize; @FXML private Slider objSizeSlider; @FXML private Label borderSize; @FXML private Label resWidth; // OCV VARIABLES private VideoCapture vidCap; private Mat previousMatrix, subtractionResult, singleFrame; // MY VARIABLES private ScheduledExecutorService SES; private Image inputImage; private static boolean applicationShouldClose = false; private boolean hasPrevious = false; private static int minPixelDiff = 20; private static int minPixelsOfAnObject = 1500; private int cnt; private int wi; private int hi; private int topLeftR; private int topLeftC; private int bottomRightR; private int bottomRightC; private ArrayList<Coordinates> col; private int resolutionWidth; private int resolutionHeight; private int borderSz = 2; private int borderClr = 0; @FXML private ToggleButton toggleColor; @Override public void initialize(URL url, ResourceBundle rb) { vidCap = new VideoCapture(); previousMatrix = new Mat(); subtractionResult = new Mat(); col = new ArrayList<>(); resolutionWidth = 100; resolutionHeight = 100; sliderInit(); resSliderListener(); pixDiffSliderListener(); objSizeSliderListener(); cameraSwitch.setStyle("-fx-background-color: red"); } @FXML private void StartMenuAction(ActionEvent event) { vidCap.open(0); vidCap.set(Videoio.CV_CAP_PROP_FRAME_HEIGHT, resolutionHeight); vidCap.set(Videoio.CV_CAP_PROP_FRAME_WIDTH, resolutionWidth); SES = Executors.newSingleThreadScheduledExecutor(); SES.scheduleAtFixedRate(() -> imageView.setImage(grabFrame()), 0, 10, TimeUnit.MILLISECONDS); } @FXML private void StopMenuAction(ActionEvent event) { SES.shutdown(); if (vidCap.isOpened()) { vidCap.release(); } // imageView.setFitHeight(450.0); // imageView.setFitWidth(600.0); // Mat singleFrame = new Mat((int)imageView.getFitWidth(), (int)imageView.getFitHeight(), CvType.CV_8UC1, new Scalar(0)); // MatOfByte buff = new MatOfByte(); // Imgcodecs.imencode(".jpg", singleFrame, buff); // blackScreen = new Image(new ByteArrayInputStream(buff.toArray())); // imageView.setImage(blackScreen); } private Image grabFrame() { inputImage = null; singleFrame = new Mat(); if (vidCap.isOpened()) { try { vidCap.read(singleFrame); Imgproc.cvtColor(singleFrame, singleFrame, Imgproc.COLOR_BGR2GRAY); if (!hasPrevious) { MatOfByte buff = new MatOfByte(); Imgcodecs.imencode(".jpg", singleFrame, buff); inputImage = new Image(new ByteArrayInputStream(buff.toArray())); } } catch (Exception e) { System.out.println("problem in reading frame"); } } if (hasPrevious) { Core.absdiff(singleFrame, previousMatrix, subtractionResult); hi = singleFrame.rows(); wi = singleFrame.cols(); col.clear(); for (int r = 0; r < hi; r++) { for (int c = 0; c < wi; c++) { // double v1[] = singleFrame.get(r, c); // double v2[] = prevMat.get(r, c); // double diff = Math.abs(v1[0] - v2[0]); previousMatrix.put(r, c, singleFrame.get(r, c)[0]); if (subtractionResult.get(r, c)[0] >= minPixelDiff) { subtractionResult.put(r, c, 255); col.add(new Coordinates(r, c)); } else { subtractionResult.put(r, c, 0); } } } boolean ok = true; int sz = col.size(); for (int i = 0; i < sz; i++) { double v[] = subtractionResult.get(col.get(i).getR(), col.get(i).getC()); if (v[0] == 255) { topLeftR = 2 * hi; topLeftC = 2 * wi; bottomRightR = -1; bottomRightC = -1; cnt = 1; floodFill(col.get(i).getR(), col.get(i).getC()); if (cnt >= minPixelsOfAnObject) { // System.out.println("burglur........"+cnt); drawBorder(); } } } // using non recursive flood fill // for(int i = 0; i < sz; i++){ // topLeftR = 2 * hi; // topLeftC = 2 * wi; // bottomRightR = -1; // bottomRightC = -1; // cnt = 1; // Coordinates c = new Coordinates(col.get(i).getR(), col.get(i).getC()); // if(subsRes.get(c.getR(), c.getC())[0] == 255){ // nonRecursiveFloodfill(c); // if(cnt >= minPixelsOfAnObject){ // System.out.println("burglur........"+cnt); // //floodOne(r, c); // //drawBorder(); // //ok = false; // } // } // } // System.out.println("h: "+subsRes.rows() + " w "+subsRes.cols()); MatOfByte buff = new MatOfByte(); Imgcodecs.imencode(".jpg", singleFrame, buff); inputImage = new Image(new ByteArrayInputStream(buff.toArray())); } else { //System.out.println("first frame"); hasPrevious = true; previousMatrix = singleFrame.clone(); } return inputImage; } int dr[] = { -1, +1, +0, +0 }; int dc[] = { +0, +0, -1, +1 }; private void floodFill(int r, int c) { topLeftR = Math.min(r, topLeftR); topLeftC = Math.min(c, topLeftC); bottomRightR = Math.max(r, bottomRightR); bottomRightC = Math.max(c, bottomRightC); cnt++; subtractionResult.put(r, c, 2); for (int i = 0; i < 4; i++) { if ((r + dr[i]) >= 0 && (r + dr[i]) < hi && (c + dc[i]) >= 0 && (c + dc[i]) < wi && subtractionResult.get(r + dr[i], c + dc[i])[0] == 255) { floodFill(r + dr[i], c + dc[i]); } } } private void nonRecursiveFloodfill(Coordinates cord) { Queue<Coordinates> q = new LinkedList<>(); q.add(cord); while (!q.isEmpty()) { cnt++; cord = q.poll(); int r = cord.getR(), c = cord.getC(); subtractionResult.put(r, c, 2); for (int i = 0; i < 4; i++) { if ((r + dr[i]) >= 0 && (r + dr[i]) < hi && (c + dc[i]) >= 0 && (c + dc[i]) < wi && subtractionResult.get(r + dr[i], c + dc[i])[0] == 255) { q.add(new Coordinates(r + dr[i], c + dc[i])); } } } } private void drawBorder() { for (int r = topLeftR - borderSz; r <= bottomRightR + borderSz; r++) { for (int x = -borderSz; x < 0; x++) { if (r >= 0 && r < hi && (topLeftC + x) >= 0 && (topLeftC + x) < wi) singleFrame.put(r, topLeftC + x, borderClr); if (r >= 0 && r < hi && (topLeftC - x) >= 0 && (topLeftC - x) < wi) singleFrame.put(r, bottomRightC - x, borderClr); } } for (int c = topLeftC; c <= bottomRightC; c++) { for (int x = -borderSz; x < 0; x++) { if ((topLeftR + x) >= 0 && (topLeftR + x) < hi && c >= 0 && c < wi) singleFrame.put(topLeftR + x, c, borderClr); if ((topLeftR - x) >= 0 && (topLeftR - x) < hi && c >= 0 && c < wi) singleFrame.put(bottomRightR - x, c, borderClr); } } } @FXML private void cameraSwitchAction(ActionEvent event) { if (cameraSwitch.getText().equals("Turn On Camera")) { vidCap.open(0); vidCap.set(Videoio.CV_CAP_PROP_FRAME_HEIGHT, resolutionHeight); vidCap.set(Videoio.CV_CAP_PROP_FRAME_WIDTH, resolutionWidth); SES = Executors.newSingleThreadScheduledExecutor(); SES.scheduleAtFixedRate(() -> imageView.setImage(grabFrame()), 0, 10, TimeUnit.MILLISECONDS); cameraSwitch.setText("Turn Off Camera"); cameraSwitch.setStyle("-fx-background-color:green"); } else { SES.shutdown(); if (vidCap.isOpened()) { vidCap.release(); } cameraSwitch.setStyle("-fx-background-color:red"); cameraSwitch.setText("Turn On Camera"); hasPrevious = false; } } private void resSliderListener() { resWidthSlider.valueProperty().addListener(new ChangeListener<Number>() { @Override public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { resolutionWidth = (int) newValue.doubleValue(); resWidth.setText(String.valueOf(resolutionWidth)); } }); resHeightSlider.valueProperty().addListener(new ChangeListener<Number>() { @Override public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { //System.out.println("old="+oldValue.doubleValue()+" new="+newValue.doubleValue()); resolutionHeight = (int) newValue.doubleValue(); resHeight.setText(String.valueOf(resolutionHeight)); } }); } private void pixDiffSliderListener() { pixDiffSlider.valueProperty().addListener(new ChangeListener<Number>() { @Override public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { //System.out.println("old="+oldValue.doubleValue()+" new="+newValue.doubleValue()); minPixelDiff = (int) newValue.doubleValue(); pixDiff.setText(String.valueOf(minPixelDiff)); } }); } private void objSizeSliderListener() { objSizeSlider.valueProperty().addListener(new ChangeListener<Number>() { @Override public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { //System.out.println("old="+oldValue.doubleValue()+" new="+newValue.doubleValue()); minPixelsOfAnObject = (int) newValue.doubleValue(); objSize.setText(String.valueOf(minPixelsOfAnObject)); } }); } private void sliderInit() { resWidth.setText(String.valueOf(resolutionWidth)); resWidthSlider.setMin(50); resWidthSlider.setMax(1024); resWidthSlider.setValue(resolutionWidth); resWidthSlider.setMajorTickUnit(100); resWidthSlider.setMinorTickCount(50); resHeight.setText(String.valueOf(resolutionHeight)); resHeightSlider.setMin(50); resHeightSlider.setMax(786); resHeightSlider.setValue(resolutionHeight); resHeightSlider.setMajorTickUnit(100); resHeightSlider.setMinorTickCount(50); pixDiff.setText(String.valueOf(minPixelDiff)); pixDiffSlider.setMin(1); pixDiffSlider.setMax(255); pixDiffSlider.setValue(minPixelDiff); pixDiffSlider.setMajorTickUnit(10); pixDiffSlider.setMinorTickCount(5); objSize.setText(String.valueOf(minPixelsOfAnObject)); objSizeSlider.setMin(1); objSizeSlider.setMax(100000); objSizeSlider.setValue(minPixelsOfAnObject); objSizeSlider.setMajorTickUnit(10000); objSizeSlider.setMinorTickCount(1000); borderSize.setText(String.valueOf(borderSz)); toggleColor.setStyle("-fx-border-color:black black black black"); //toggleColor.setStyle("-fx-background-color:black"); //toggleColor.setStyle("-fx-text-fill:white"); } @FXML private void reduceBorderSize(ActionEvent event) { if (borderSz - 1 > 0) { borderSz--; borderSize.setText(String.valueOf(borderSz)); } } @FXML private void increaseBorderSize(ActionEvent event) { if ((borderSz + 1) <= (resolutionHeight + resolutionWidth) / 4) { borderSz++; borderSize.setText(String.valueOf(borderSz)); } } @FXML private void changeBorderColor(ActionEvent event) { if (toggleColor.getText().equals("Set White")) { borderClr = 255; toggleColor.setText("Set Black"); toggleColor.setStyle("-fx-border-color:white white white white"); } else { borderClr = 0; toggleColor.setText("Set White"); toggleColor.setStyle("-fx-border-color:black black black black"); } } }