first commit

This commit is contained in:
rdkartono
2025-05-09 16:12:50 +07:00
parent f9e832e20c
commit 5567ca16ba
61 changed files with 657 additions and 18 deletions

BIN
Libs/archive.dll Normal file

Binary file not shown.

BIN
Libs/avif.dll Normal file

Binary file not shown.

BIN
Libs/bz2.dll Normal file

Binary file not shown.

BIN
Libs/cublas64_12.dll Normal file

Binary file not shown.

BIN
Libs/cublasLt64_12.dll Normal file

Binary file not shown.

BIN
Libs/cudnn64_9.dll Normal file

Binary file not shown.

BIN
Libs/cudnn_cnn64_9.dll Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Libs/cudnn_graph64_9.dll Normal file

Binary file not shown.

Binary file not shown.

BIN
Libs/cudnn_ops64_9.dll Normal file

Binary file not shown.

BIN
Libs/ffi-7.dll Normal file

Binary file not shown.

BIN
Libs/gif.dll Normal file

Binary file not shown.

BIN
Libs/glib-2.0-0.dll Normal file

Binary file not shown.

BIN
Libs/gmodule-2.0-0.dll Normal file

Binary file not shown.

BIN
Libs/gobject-2.0-0.dll Normal file

Binary file not shown.

BIN
Libs/gstapp-1.0-0.dll Normal file

Binary file not shown.

BIN
Libs/gstaudio-1.0-0.dll Normal file

Binary file not shown.

BIN
Libs/gstbase-1.0-0.dll Normal file

Binary file not shown.

BIN
Libs/gstpbutils-1.0-0.dll Normal file

Binary file not shown.

BIN
Libs/gstreamer-1.0-0.dll Normal file

Binary file not shown.

BIN
Libs/gstriff-1.0-0.dll Normal file

Binary file not shown.

BIN
Libs/gsttag-1.0-0.dll Normal file

Binary file not shown.

BIN
Libs/gstvideo-1.0-0.dll Normal file

Binary file not shown.

BIN
Libs/intl-8.dll Normal file

Binary file not shown.

BIN
Libs/jpeg62.dll Normal file

Binary file not shown.

BIN
Libs/leptonica-1.85.0.dll Normal file

Binary file not shown.

BIN
Libs/libcrypto-3-x64.dll Normal file

Binary file not shown.

BIN
Libs/libcurl.dll Normal file

Binary file not shown.

BIN
Libs/liblzma.dll Normal file

Binary file not shown.

BIN
Libs/libpng16.dll Normal file

Binary file not shown.

BIN
Libs/libsharpyuv.dll Normal file

Binary file not shown.

BIN
Libs/libwebp.dll Normal file

Binary file not shown.

BIN
Libs/libwebpmux.dll Normal file

Binary file not shown.

BIN
Libs/libyuv.dll Normal file

Binary file not shown.

BIN
Libs/lz4.dll Normal file

Binary file not shown.

BIN
Libs/nppc64_12.dll Normal file

Binary file not shown.

BIN
Libs/nppial64_12.dll Normal file

Binary file not shown.

BIN
Libs/nppist64_12.dll Normal file

Binary file not shown.

BIN
Libs/openjp2.dll Normal file

Binary file not shown.

BIN
Libs/openvino.dll Normal file

Binary file not shown.

BIN
Libs/orc-0.4-0.dll Normal file

Binary file not shown.

BIN
Libs/pcre2-8-0.dll Normal file

Binary file not shown.

BIN
Libs/tbb12.dll Normal file

Binary file not shown.

BIN
Libs/tesseract55.dll Normal file

Binary file not shown.

BIN
Libs/tiff.dll Normal file

Binary file not shown.

BIN
Libs/z-1.dll Normal file

Binary file not shown.

BIN
Libs/zlib1.dll Normal file

Binary file not shown.

BIN
Libs/zstd.dll Normal file

Binary file not shown.

80
YOLO/coco.names Normal file
View File

@@ -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

BIN
YOLO/yolov8n.onnx Normal file

Binary file not shown.

BIN
YOLO/yolov8n.pt Normal file

Binary file not shown.

View File

@@ -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<String> new_extract, Consumer<String> already_exists, Consumer<String> 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);
}
}
}
}
}

View File

@@ -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();

View File

@@ -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();
}
}

View File

@@ -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<Boolean> onRunning, Consumer<Mat> frameConsumer, Consumer<int[]> 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;
}
}

View File

@@ -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;
}
}

View File

@@ -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<Mat> 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);
}
}
}
}

View File

@@ -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;

View File

@@ -1,16 +1,104 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.control.Button?>
<VBox alignment="CENTER" spacing="20.0" xmlns:fx="http://javafx.com/fxml"
fx:controller="id.co.gtc.cctvwithcuda.MainController">
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="576.0" prefWidth="1024.0" xmlns="http://javafx.com/javafx/17.0.12" xmlns:fx="http://javafx.com/fxml/1" fx:controller="id.co.gtc.cctvwithcuda.MainController">
<top>
<VBox BorderPane.alignment="CENTER">
<BorderPane.margin>
<Insets bottom="5.0" top="5.0" />
</BorderPane.margin>
<children>
<HBox prefHeight="40.0">
<children>
<Label maxHeight="1.7976931348623157E308" text="Camera URL">
<HBox.margin>
<Insets left="5.0" right="5.0" />
</HBox.margin>
</Label>
<TextField fx:id="cameraUrlField" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" promptText="enter camera RTSP URL" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="5.0" right="5.0" />
</HBox.margin>
</TextField>
<Button fx:id="startStreamButton" maxHeight="1.7976931348623157E308" mnemonicParsing="false" onAction="#startStreamButtonOnAction" prefWidth="120.0" text="Start Streaming">
<HBox.margin>
<Insets left="5.0" right="5.0" />
</HBox.margin>
</Button>
<Button fx:id="stopStreamButton" maxHeight="1.7976931348623157E308" mnemonicParsing="false" onAction="#stopStreamButtonOnAction" prefWidth="120.0" text="Stop Streaming">
<HBox.margin>
<Insets left="5.0" right="5.0" />
</HBox.margin>
</Button>
</children>
</HBox>
<HBox prefHeight="40.0">
<children>
<Label maxHeight="1.7976931348623157E308" text="Username">
<HBox.margin>
<Insets left="5.0" right="5.0" />
</HBox.margin>
</Label>
<TextField fx:id="rtspUsernameField" maxHeight="1.7976931348623157E308" promptText="enter username" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="5.0" right="5.0" />
</HBox.margin>
</TextField>
<Label maxHeight="1.7976931348623157E308" text="Password">
<HBox.margin>
<Insets left="5.0" right="5.0" />
</HBox.margin>
</Label>
<PasswordField fx:id="rtspPasswordField" maxHeight="1.7976931348623157E308" promptText="enter password" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="5.0" right="5.0" />
</HBox.margin>
</PasswordField>
</children>
<VBox.margin>
<Insets bottom="5.0" top="5.0" />
</VBox.margin>
</HBox>
</children>
</VBox>
</top>
<bottom>
<HBox prefHeight="40.0" BorderPane.alignment="CENTER">
<BorderPane.margin>
<Insets bottom="5.0" top="5.0" />
</BorderPane.margin>
<children>
<Label fx:id="statusLabel" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-border-color: black;" text="Streaming Status" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets left="5.0" />
</HBox.margin>
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0"/>
<Insets left="5.0" right="5.0" />
</padding>
<Label fx:id="welcomeText"/>
<Button text="Hello!" onAction="#onHelloButtonClick"/>
</VBox>
</Label>
<Label fx:id="datetimeLabel" maxHeight="1.7976931348623157E308" style="-fx-border-color: black;" text="Date and TIme">
<HBox.margin>
<Insets right="5.0" />
</HBox.margin>
<padding>
<Insets left="5.0" right="5.0" />
</padding>
</Label>
</children>
</HBox>
</bottom>
<center>
<StackPane fx:id="imageStackPane" prefHeight="150.0" prefWidth="200.0" style="-fx-border-color: black;" BorderPane.alignment="CENTER">
<BorderPane.margin>
<Insets left="5.0" right="5.0" />
</BorderPane.margin>
<children>
<ImageView fx:id="imageView" fitHeight="150.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" />
</children>
</StackPane>
</center>
</BorderPane>