diff --git a/Libs/archive.dll b/Libs/archive.dll new file mode 100644 index 0000000..ebb9ff4 Binary files /dev/null and b/Libs/archive.dll differ diff --git a/Libs/avif.dll b/Libs/avif.dll new file mode 100644 index 0000000..a9ed759 Binary files /dev/null and b/Libs/avif.dll differ diff --git a/Libs/bz2.dll b/Libs/bz2.dll new file mode 100644 index 0000000..3abd58d Binary files /dev/null and b/Libs/bz2.dll differ diff --git a/Libs/cublas64_12.dll b/Libs/cublas64_12.dll new file mode 100644 index 0000000..81a05a6 Binary files /dev/null and b/Libs/cublas64_12.dll differ diff --git a/Libs/cublasLt64_12.dll b/Libs/cublasLt64_12.dll new file mode 100644 index 0000000..7f81535 Binary files /dev/null and b/Libs/cublasLt64_12.dll differ diff --git a/Libs/cudnn64_9.dll b/Libs/cudnn64_9.dll new file mode 100644 index 0000000..7fe172c Binary files /dev/null and b/Libs/cudnn64_9.dll differ diff --git a/Libs/cudnn_cnn64_9.dll b/Libs/cudnn_cnn64_9.dll new file mode 100644 index 0000000..d85ef17 Binary files /dev/null and b/Libs/cudnn_cnn64_9.dll differ diff --git a/Libs/cudnn_engines_precompiled64_9.dll b/Libs/cudnn_engines_precompiled64_9.dll new file mode 100644 index 0000000..9b531ee Binary files /dev/null and b/Libs/cudnn_engines_precompiled64_9.dll differ diff --git a/Libs/cudnn_engines_runtime_compiled64_9.dll b/Libs/cudnn_engines_runtime_compiled64_9.dll new file mode 100644 index 0000000..3f99f5f Binary files /dev/null and b/Libs/cudnn_engines_runtime_compiled64_9.dll differ diff --git a/Libs/cudnn_graph64_9.dll b/Libs/cudnn_graph64_9.dll new file mode 100644 index 0000000..42b0b3b Binary files /dev/null and b/Libs/cudnn_graph64_9.dll differ diff --git a/Libs/cudnn_heuristic64_9.dll b/Libs/cudnn_heuristic64_9.dll new file mode 100644 index 0000000..abbcadf Binary files /dev/null and b/Libs/cudnn_heuristic64_9.dll differ diff --git a/Libs/cudnn_ops64_9.dll b/Libs/cudnn_ops64_9.dll new file mode 100644 index 0000000..b7d7159 Binary files /dev/null and b/Libs/cudnn_ops64_9.dll differ diff --git a/Libs/ffi-7.dll b/Libs/ffi-7.dll new file mode 100644 index 0000000..3610655 Binary files /dev/null and b/Libs/ffi-7.dll differ diff --git a/Libs/gif.dll b/Libs/gif.dll new file mode 100644 index 0000000..708d968 Binary files /dev/null and b/Libs/gif.dll differ diff --git a/Libs/glib-2.0-0.dll b/Libs/glib-2.0-0.dll new file mode 100644 index 0000000..b1024f9 Binary files /dev/null and b/Libs/glib-2.0-0.dll differ diff --git a/Libs/gmodule-2.0-0.dll b/Libs/gmodule-2.0-0.dll new file mode 100644 index 0000000..6c26599 Binary files /dev/null and b/Libs/gmodule-2.0-0.dll differ diff --git a/Libs/gobject-2.0-0.dll b/Libs/gobject-2.0-0.dll new file mode 100644 index 0000000..d8f309c Binary files /dev/null and b/Libs/gobject-2.0-0.dll differ diff --git a/Libs/gstapp-1.0-0.dll b/Libs/gstapp-1.0-0.dll new file mode 100644 index 0000000..0c3b330 Binary files /dev/null and b/Libs/gstapp-1.0-0.dll differ diff --git a/Libs/gstaudio-1.0-0.dll b/Libs/gstaudio-1.0-0.dll new file mode 100644 index 0000000..f57c8d3 Binary files /dev/null and b/Libs/gstaudio-1.0-0.dll differ diff --git a/Libs/gstbase-1.0-0.dll b/Libs/gstbase-1.0-0.dll new file mode 100644 index 0000000..604cdc8 Binary files /dev/null and b/Libs/gstbase-1.0-0.dll differ diff --git a/Libs/gstpbutils-1.0-0.dll b/Libs/gstpbutils-1.0-0.dll new file mode 100644 index 0000000..bd6f540 Binary files /dev/null and b/Libs/gstpbutils-1.0-0.dll differ diff --git a/Libs/gstreamer-1.0-0.dll b/Libs/gstreamer-1.0-0.dll new file mode 100644 index 0000000..c56b99c Binary files /dev/null and b/Libs/gstreamer-1.0-0.dll differ diff --git a/Libs/gstriff-1.0-0.dll b/Libs/gstriff-1.0-0.dll new file mode 100644 index 0000000..45bacb5 Binary files /dev/null and b/Libs/gstriff-1.0-0.dll differ diff --git a/Libs/gsttag-1.0-0.dll b/Libs/gsttag-1.0-0.dll new file mode 100644 index 0000000..7bd2e67 Binary files /dev/null and b/Libs/gsttag-1.0-0.dll differ diff --git a/Libs/gstvideo-1.0-0.dll b/Libs/gstvideo-1.0-0.dll new file mode 100644 index 0000000..fafbb27 Binary files /dev/null and b/Libs/gstvideo-1.0-0.dll differ diff --git a/Libs/intl-8.dll b/Libs/intl-8.dll new file mode 100644 index 0000000..bb07349 Binary files /dev/null and b/Libs/intl-8.dll differ diff --git a/Libs/jpeg62.dll b/Libs/jpeg62.dll new file mode 100644 index 0000000..ebafecb Binary files /dev/null and b/Libs/jpeg62.dll differ diff --git a/Libs/leptonica-1.85.0.dll b/Libs/leptonica-1.85.0.dll new file mode 100644 index 0000000..73fdbf1 Binary files /dev/null and b/Libs/leptonica-1.85.0.dll differ diff --git a/Libs/libcrypto-3-x64.dll b/Libs/libcrypto-3-x64.dll new file mode 100644 index 0000000..2f783b8 Binary files /dev/null and b/Libs/libcrypto-3-x64.dll differ diff --git a/Libs/libcurl.dll b/Libs/libcurl.dll new file mode 100644 index 0000000..aec577a Binary files /dev/null and b/Libs/libcurl.dll differ diff --git a/Libs/liblzma.dll b/Libs/liblzma.dll new file mode 100644 index 0000000..51cf80a Binary files /dev/null and b/Libs/liblzma.dll differ diff --git a/Libs/libpng16.dll b/Libs/libpng16.dll new file mode 100644 index 0000000..e90f622 Binary files /dev/null and b/Libs/libpng16.dll differ diff --git a/Libs/libsharpyuv.dll b/Libs/libsharpyuv.dll new file mode 100644 index 0000000..47ec4fb Binary files /dev/null and b/Libs/libsharpyuv.dll differ diff --git a/Libs/libwebp.dll b/Libs/libwebp.dll new file mode 100644 index 0000000..20ec6c8 Binary files /dev/null and b/Libs/libwebp.dll differ diff --git a/Libs/libwebpmux.dll b/Libs/libwebpmux.dll new file mode 100644 index 0000000..c2928c7 Binary files /dev/null and b/Libs/libwebpmux.dll differ diff --git a/Libs/libyuv.dll b/Libs/libyuv.dll new file mode 100644 index 0000000..fe9cde0 Binary files /dev/null and b/Libs/libyuv.dll differ diff --git a/Libs/lz4.dll b/Libs/lz4.dll new file mode 100644 index 0000000..90d9a35 Binary files /dev/null and b/Libs/lz4.dll differ diff --git a/Libs/nppc64_12.dll b/Libs/nppc64_12.dll new file mode 100644 index 0000000..cfd3e00 Binary files /dev/null and b/Libs/nppc64_12.dll differ diff --git a/Libs/nppial64_12.dll b/Libs/nppial64_12.dll new file mode 100644 index 0000000..99bba5e Binary files /dev/null and b/Libs/nppial64_12.dll differ diff --git a/Libs/nppist64_12.dll b/Libs/nppist64_12.dll new file mode 100644 index 0000000..44615ae Binary files /dev/null and b/Libs/nppist64_12.dll differ diff --git a/Libs/openjp2.dll b/Libs/openjp2.dll new file mode 100644 index 0000000..13763dd Binary files /dev/null and b/Libs/openjp2.dll differ diff --git a/Libs/openvino.dll b/Libs/openvino.dll new file mode 100644 index 0000000..4a6b761 Binary files /dev/null and b/Libs/openvino.dll differ diff --git a/Libs/orc-0.4-0.dll b/Libs/orc-0.4-0.dll new file mode 100644 index 0000000..bcca30e Binary files /dev/null and b/Libs/orc-0.4-0.dll differ diff --git a/Libs/pcre2-8-0.dll b/Libs/pcre2-8-0.dll new file mode 100644 index 0000000..d539463 Binary files /dev/null and b/Libs/pcre2-8-0.dll differ diff --git a/Libs/tbb12.dll b/Libs/tbb12.dll new file mode 100644 index 0000000..a20a1d1 Binary files /dev/null and b/Libs/tbb12.dll differ diff --git a/Libs/tesseract55.dll b/Libs/tesseract55.dll new file mode 100644 index 0000000..ff4516a Binary files /dev/null and b/Libs/tesseract55.dll differ diff --git a/Libs/tiff.dll b/Libs/tiff.dll new file mode 100644 index 0000000..db71c35 Binary files /dev/null and b/Libs/tiff.dll differ diff --git a/Libs/z-1.dll b/Libs/z-1.dll new file mode 100644 index 0000000..7e257a1 Binary files /dev/null and b/Libs/z-1.dll differ diff --git a/Libs/zlib1.dll b/Libs/zlib1.dll new file mode 100644 index 0000000..fc2c81e Binary files /dev/null and b/Libs/zlib1.dll differ diff --git a/Libs/zstd.dll b/Libs/zstd.dll new file mode 100644 index 0000000..dc83d81 Binary files /dev/null and b/Libs/zstd.dll differ diff --git a/YOLO/coco.names b/YOLO/coco.names new file mode 100644 index 0000000..941cb4e --- /dev/null +++ b/YOLO/coco.names @@ -0,0 +1,80 @@ +person +bicycle +car +motorcycle +airplane +bus +train +truck +boat +traffic light +fire hydrant +stop sign +parking meter +bench +bird +cat +dog +horse +sheep +cow +elephant +bear +zebra +giraffe +backpack +umbrella +handbag +tie +suitcase +frisbee +skis +snowboard +sports ball +kite +baseball bat +baseball glove +skateboard +surfboard +tennis racket +bottle +wine glass +cup +fork +knife +spoon +bowl +banana +apple +sandwich +orange +broccoli +carrot +hot dog +pizza +donut +cake +chair +couch +potted plant +bed +dining table +toilet +tv +laptop +mouse +remote +keyboard +cell phone +microwave +oven +toaster +sink +refrigerator +book +clock +vase +scissors +teddy bear +hair drier +toothbrush diff --git a/YOLO/yolov8n.onnx b/YOLO/yolov8n.onnx new file mode 100644 index 0000000..9ede1eb Binary files /dev/null and b/YOLO/yolov8n.onnx differ diff --git a/YOLO/yolov8n.pt b/YOLO/yolov8n.pt new file mode 100644 index 0000000..0db4ca4 Binary files /dev/null and b/YOLO/yolov8n.pt differ diff --git a/src/main/java/id/co/gtc/cctvwithcuda/Libraries.java b/src/main/java/id/co/gtc/cctvwithcuda/Libraries.java new file mode 100644 index 0000000..1ecf5cf --- /dev/null +++ b/src/main/java/id/co/gtc/cctvwithcuda/Libraries.java @@ -0,0 +1,91 @@ +package id.co.gtc.cctvwithcuda; + +import java.io.File; +import java.io.InputStream; +import java.nio.file.Files; +import java.util.function.Consumer; + +public class Libraries { + private static final String[] opencv_libraries = { + "avif", + "cublas64_12", + "cublasLt64_12", + "cudnn64_9", + "glib-2.0-0", + "gobject-2.0-0", + "gstapp-1.0-0", + "gstaudio-1.0-0", + "gstbase-1.0-0", + "gstpbutils-1.0-0", + "gstreamer-1.0-0", + "gstriff-1.0-0", + "gstvideo-1.0-0", + "nppc64_12", + "nppial64_12", + "nppist64_12", + "openvino", + "tesseract55", + "opencv_java4100", + "opencv_videoio_ffmpeg4100_64", + "archive", + "leptonica-1.85.0", + "libcurl", + "libyuv", + "intl-8", + "gmodule-2.0-0", + "pcre2-8-0", + "ffi-7", + "gsttag-1.0-0", + "orc-0.4-0", + "zlib1", + "bz2", + "lz4", + "zstd", + "gif", + "jpeg62", + "openjp2", + "libpng16", + "libwebpmux", + "libwebp", + "liblzma", + "libcrypto-3-x64", + "tiff", + "libsharpyuv", + "z-1", + "tbb12", + "libopenblas", + "cudnn_graph64_9", + "cudnn_ops64_9", + "cudnn_cnn64_9", + "cudnn_engines_precompiled64_9", + "cudnn_heuristic64_9", + "cudnn_engines_runtime_compiled64_9" + }; + + public static void ExtractAll(String targetdir, Consumer new_extract, Consumer already_exists, Consumer failed){ + + for(String lib : opencv_libraries){ + String libraryname = System.mapLibraryName(lib); + File libfile = new File(targetdir, libraryname); + if (libfile.isFile()) { + if (already_exists!=null) already_exists.accept(libraryname); + } else { + try{ + InputStream input = Libraries.class.getResourceAsStream("/"+libraryname); + if (input!=null){ + Files.copy(input, libfile.toPath()); + System.out.println("Library "+libraryname+" extracted to "+libfile.getAbsolutePath()); + if (new_extract!=null) new_extract.accept(libraryname); + } else { + System.out.println("Library "+libraryname+" not found in jar"); + if (failed!=null) failed.accept(libraryname); + } + } catch (Exception e){ + System.out.println("Exception when extracting library "+libraryname+", message : "+e.getMessage()); + if (failed!=null) failed.accept(libraryname); + } + } + } + + } +} diff --git a/src/main/java/id/co/gtc/cctvwithcuda/MainApplication.java b/src/main/java/id/co/gtc/cctvwithcuda/MainApplication.java index 09318fd..6776034 100644 --- a/src/main/java/id/co/gtc/cctvwithcuda/MainApplication.java +++ b/src/main/java/id/co/gtc/cctvwithcuda/MainApplication.java @@ -11,7 +11,7 @@ public class MainApplication extends Application { @Override public void start(Stage stage) throws IOException { FXMLLoader fxmlLoader = new FXMLLoader(MainApplication.class.getResource("MainView.fxml")); - Scene scene = new Scene(fxmlLoader.load(), 320, 240); + Scene scene = new Scene(fxmlLoader.load(), 1024, 576); stage.setTitle("CCTV with CUDA"); stage.setScene(scene); stage.show(); diff --git a/src/main/java/id/co/gtc/cctvwithcuda/MainController.java b/src/main/java/id/co/gtc/cctvwithcuda/MainController.java index 1c181cc..9ead3a7 100644 --- a/src/main/java/id/co/gtc/cctvwithcuda/MainController.java +++ b/src/main/java/id/co/gtc/cctvwithcuda/MainController.java @@ -1,14 +1,142 @@ package id.co.gtc.cctvwithcuda; import javafx.fxml.FXML; +import javafx.scene.control.Button; import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.layout.StackPane; +import org.opencv.osgi.OpenCVNativeLoader; + +import java.time.LocalDateTime; + public class MainController { - @FXML - private Label welcomeText; + + static OpenCVNativeLoader nl; + static{ + Libraries.ExtractAll(SomeCodes.currentDirectory, null, null, null); + nl = new OpenCVNativeLoader(); + nl.init(); + } @FXML - protected void onHelloButtonClick() { - welcomeText.setText("Welcome to JavaFX Application!"); + Button startStreamButton; + @FXML + Button stopStreamButton; + @FXML + Label statusLabel; + @FXML + Label datetimeLabel; + @FXML + ImageView imageView; + @FXML + StackPane imageStackPane; + @FXML + TextField cameraUrlField; + @FXML + TextField rtspUsernameField; + @FXML + TextField rtspPasswordField; + + RtspGrabber rtspGrabber; + YoloDetector yoloDetector; + boolean isRunning = false; + + @FXML + public void initialize() { + SomeCodes.EnableDisableButton(startStreamButton,true); + SomeCodes.EnableDisableButton(stopStreamButton,false); + SomeCodes.UpdateLabel(statusLabel, "Stopped"); + + imageView.setFitWidth(640); + imageView.setFitHeight(360); + rtspGrabber = new RtspGrabber(); + + Thread thread = new Thread(()->{ + while (true) { + try { + Thread.sleep(1000); + SomeCodes.UpdateLabel(datetimeLabel, SomeCodes.GetDateTime(LocalDateTime.now())); + } catch (InterruptedException e) { + System.out.println("Thread interrupted"); + break; + } + } + }); + thread.setName("datetime-thread"); + thread.setDaemon(true); + thread.start(); + + Runtime.getRuntime().addShutdownHook(new Thread("shutdown-hook") { + @Override + public void run() { + System.out.println("Shutdown hook triggered"); + thread.interrupt(); + rtspGrabber.Stop(); + } + }); + + cameraUrlField.setText("100.64.0.2:8554/carportA"); + yoloDetector = new YoloDetector("yolov8n.onnx"); + } + + @FXML + private void startStreamButtonOnAction() { + String cameraURL = cameraUrlField.getText(); + String rtspUsername = rtspUsernameField.getText(); + String rtspPassword = rtspPasswordField.getText(); + if (cameraURL.isEmpty()) { + SomeCodes.ShowErrorAlert("Invalid Camera URL", "Camera URL cannot be empty"); + return; + } + rtspGrabber.Start(cameraURL, rtspUsername, rtspPassword, + (running)->{ + isRunning = running; + if (isRunning){ + SomeCodes.UpdateLabel(statusLabel, "Started"); + SomeCodes.EnableDisableButton(startStreamButton, false); + SomeCodes.EnableDisableButton(stopStreamButton, true); + } else { + SomeCodes.UpdateLabel(statusLabel, "Stopped"); + SomeCodes.EnableDisableButton(startStreamButton, true); + SomeCodes.EnableDisableButton(stopStreamButton, false); + } + }, + (frame) -> { + yoloDetector.Detect(frame, (detection)->{ + String dimension = "Dimension : "+detection.dims(); + String imagesize = "Image Size : "+detection.size(0); + String imagechannels = "Image Channels : "+detection.size(1); + String imageheight = "Image Height : "+detection.size(2); + String imagewidth = "Image Width : "+detection.size(3); + System.out.println("Detection : "); + System.out.println(dimension); + System.out.println(imagesize); + System.out.println(imagechannels); + System.out.println(imageheight); + System.out.println(imagewidth); + }); + Image img = SomeCodes.MatToImage(frame); + if (img!=null) { + SomeCodes.ImageViewSetImage(imageView, img); + + } + }, + (frameInfo) -> { + if (frameInfo != null && frameInfo.length == 3 && isRunning) { + int width = frameInfo[0]; + int height = frameInfo[1]; + int fps = frameInfo[2]; + SomeCodes.UpdateLabel(statusLabel, "Connected: " + width + "x" + height + ", FPS: " + fps); + } + }); + + } + + @FXML + private void stopStreamButtonOnAction() { + rtspGrabber.Stop(); } } \ No newline at end of file diff --git a/src/main/java/id/co/gtc/cctvwithcuda/RtspGrabber.java b/src/main/java/id/co/gtc/cctvwithcuda/RtspGrabber.java new file mode 100644 index 0000000..dc0aa1e --- /dev/null +++ b/src/main/java/id/co/gtc/cctvwithcuda/RtspGrabber.java @@ -0,0 +1,87 @@ +package id.co.gtc.cctvwithcuda; + +import org.opencv.core.Mat; +import org.opencv.videoio.VideoCapture; + +import java.util.function.Consumer; + +public class RtspGrabber { + private VideoCapture vcap; + private final int[] frameHeight = {0}; + private final int[] frameWidth = {0}; + private final int[] frameCount = {0}; + private final boolean[] isRunning = {false}; + public RtspGrabber(){ + + } + + public void Start(String rtspUrl, String rtspUsername, String rtspPassword, Consumer onRunning, Consumer frameConsumer, Consumer frameInfoConsumer) { + if (vcap!=null) Stop(); + + vcap = new VideoCapture(); + String rtspUrlWithAuth = "rtsp://" + rtspUsername + ":" + rtspPassword + "@" + rtspUrl; + if (!vcap.open(rtspUrlWithAuth)) { + System.out.println("Error: Unable to open RTSP stream"); + if (onRunning!=null) onRunning.accept(false); + } + + int[] fps = {0}; + + Thread thread1 = new Thread(() -> { + isRunning[0] = true; + if (onRunning!=null) onRunning.accept(true); + while (isRunning[0]) { + if (vcap.isOpened()) { + Mat frame = new Mat(); + if (vcap.read(frame)) { + if (frame.empty()) continue; + fps[0] = fps[0] + 1; + if (frameHeight[0]!=frame.height() || frameWidth[0]!=frame.width()){ + frameHeight[0] = frame.height(); + frameWidth[0] = frame.width(); + if (frameInfoConsumer!=null) frameInfoConsumer.accept(new int[]{frameWidth[0], frameHeight[0], frameCount[0]}); + } + if (frameConsumer!=null) frameConsumer.accept(frame); + } else { + System.out.println("Error: Unable to read frame from RTSP stream"); + break; + } + } else { + System.out.println("Error: RTSP stream is not opened"); + break; + } + } + if (onRunning!=null) onRunning.accept(false); + vcap.release(); + vcap = null; + }); + thread1.setName("rtsp-thread"); + thread1.setDaemon(true); + thread1.start(); + + Thread thread2 = new Thread(() -> { + while (isRunning[0]) { + try { + Thread.sleep(1000); + if (fps[0] != frameCount[0]){ + frameCount[0] = fps[0]; + if (frameInfoConsumer!=null) frameInfoConsumer.accept(new int[]{frameWidth[0], frameHeight[0], frameCount[0]}); + } + fps[0] = 0; + } catch (InterruptedException ignored) { + break; + } + } + }); + thread2.setName("fps-thread"); + thread2.setDaemon(true); + thread2.start(); + + + + } + + public void Stop() { + isRunning[0] = false; + } +} diff --git a/src/main/java/id/co/gtc/cctvwithcuda/SomeCodes.java b/src/main/java/id/co/gtc/cctvwithcuda/SomeCodes.java new file mode 100644 index 0000000..9cb0b00 --- /dev/null +++ b/src/main/java/id/co/gtc/cctvwithcuda/SomeCodes.java @@ -0,0 +1,101 @@ +package id.co.gtc.cctvwithcuda; + +import javafx.application.Platform; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import org.opencv.core.Mat; +import org.opencv.core.MatOfByte; +import org.opencv.imgcodecs.Imgcodecs; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.InputStream; +import java.nio.file.Files; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public class SomeCodes { + public final static String currentDirectory = System.getProperty("user.dir"); + private final static DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss"); + + public static String GetDateTime(LocalDateTime dateTime) { + if (dateTime != null) { + return dateTime.format(dtf); + } else { + return "null"; + } + } + + public static void UpdateLabel(Label label, String text) { + if (label != null) { + if (text!=null){ + if (Platform.isFxApplicationThread()){ + label.setText(text); + } else { + Platform.runLater(() -> label.setText(text)); + } + } + } + } + + public static void EnableDisableButton(Button button, boolean enable) { + if (button != null) { + if (Platform.isFxApplicationThread()){ + button.setDisable(!enable); + } else { + Platform.runLater(() -> button.setDisable(!enable)); + } + } + } + + public static void ShowErrorAlert(String title, String message) { + // Implement alert dialog logic here + Alert alert = new Alert(Alert.AlertType.ERROR); + alert.setTitle(title); + alert.setHeaderText(null); + alert.setContentText(message); + alert.showAndWait(); + } + + public static void ImageViewSetImage(ImageView imageView, Image image) { + if (imageView != null) { + if (Platform.isFxApplicationThread()){ + imageView.setImage(image); + } else { + Platform.runLater(() -> imageView.setImage(image)); + } + } + } + + public static Image MatToImage(Mat mat) { + if (mat != null && !mat.empty()) { + MatOfByte matOfByte = new MatOfByte(); + Imgcodecs.imencode(".bmp", mat, matOfByte); + return new Image(new ByteArrayInputStream(matOfByte.toArray())); + } + return null; + } + + public static String ExtractResource(String filename){ + try{ + File destination = new File(currentDirectory, filename); + + if (destination.exists()){ + return destination.getAbsolutePath(); + } + InputStream is = SomeCodes.class.getResourceAsStream(filename); + + if (is!=null){ + Files.copy(is, destination.toPath()); + return destination.getAbsolutePath(); + } + } catch (Exception e){ + System.out.println("Error extracting resource: "+filename+", Message : "+e.getMessage()); + } + return null; + } + +} diff --git a/src/main/java/id/co/gtc/cctvwithcuda/YoloDetector.java b/src/main/java/id/co/gtc/cctvwithcuda/YoloDetector.java new file mode 100644 index 0000000..4d600be --- /dev/null +++ b/src/main/java/id/co/gtc/cctvwithcuda/YoloDetector.java @@ -0,0 +1,62 @@ +package id.co.gtc.cctvwithcuda; + +import org.opencv.core.Mat; +import org.opencv.core.Scalar; +import org.opencv.core.Size; +import org.opencv.dnn.Dnn; +import org.opencv.dnn.Net; + +import java.util.function.Consumer; + +@SuppressWarnings("FieldCanBeLocal") +public class YoloDetector { + + + + private Net net = null; + private boolean loaded = false; + + /** + * Create a YoloDetector object + */ + public YoloDetector(String yolofile){ + if (yolofile!=null && !yolofile.isEmpty()){ + if (!yolofile.startsWith("/")) yolofile = "/" + yolofile; + String yolofilepath = SomeCodes.ExtractResource(yolofile); + if (yolofilepath!=null){ + net = org.opencv.dnn.Dnn.readNetFromONNX(yolofilepath); + loaded = !net.empty(); + if (loaded){ + net.setPreferableBackend(Dnn.DNN_BACKEND_CUDA); + net.setPreferableTarget(Dnn.DNN_TARGET_CUDA); + System.out.println("YoloDetector loaded from " + yolofilepath); + return; + } + } + } + SomeCodes.ExtractResource("/coco.names"); + System.out.println("YoloDetector failed to load from " + yolofile); + } + + private final double scale = 1/255.0; + private final boolean swapRGB = true; + private final boolean crop = false; + private final Size blobSize = new Size(640, 640); + private final Scalar blobScalar = new Scalar(0, 0, 0); + + /** + * Detect objects in the given frame + * @param frame the input frame + * @param onDetect the callback function to be called when detection is done + */ + public void Detect(Mat frame, Consumer onDetect){ + if (loaded){ + Mat blob = Dnn.blobFromImage(frame, scale, blobSize, blobScalar, swapRGB, crop); + net.setInput(blob); + Mat detections = net.forward(); + if (detections!=null && !detections.empty()){ + if (onDetect!=null) onDetect.accept(detections); + } + } + } +} diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index b3919ae..213774a 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -1,6 +1,8 @@ module id.co.gtc.cctvwithcuda { requires javafx.controls; requires javafx.fxml; + requires java.desktop; + requires opencv; opens id.co.gtc.cctvwithcuda to javafx.fxml; diff --git a/src/main/resources/id/co/gtc/cctvwithcuda/MainView.fxml b/src/main/resources/id/co/gtc/cctvwithcuda/MainView.fxml index 05f44d0..b8dcb86 100644 --- a/src/main/resources/id/co/gtc/cctvwithcuda/MainView.fxml +++ b/src/main/resources/id/co/gtc/cctvwithcuda/MainView.fxml @@ -1,16 +1,104 @@ - - - + + + + - - - - - - - + + + + + + + + + + + + +
+ + + + + + + + +
+