Commit 21032025

This commit is contained in:
2025-03-21 14:24:05 +07:00
parent b248c59e32
commit 80d468a79a
37 changed files with 858 additions and 964 deletions

View File

@@ -0,0 +1,99 @@
package id.co.gtc.erhacam;
import javafx.animation.PauseTransition;
import javafx.application.Platform;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.util.Duration;
import java.util.Optional;
public class AutoCloseAlert {
private static Stage currentAlertStage;
public static String shownTitle = "";
public static String shownContent = "";
public static String shownHeader = "";
private static void clear(){
shownTitle = "";
shownContent = "";
shownHeader = "";
}
/**
* Close the current alert if it is shown
*/
public static void close(){
Optional.ofNullable(currentAlertStage).ifPresent(Stage::close);
currentAlertStage = null;
clear();
}
/**
* Show an alert with a title, header, content, and automatically close after a few seconds
* If called several times, the previous alert will be closed before showing a new one
* @param title the title of the alert
* @param header the header of the alert
* @param content the content of the alert
* @param seconds the number of seconds before the alert is closed, or put 0 to keep it open
*/
public static void show(String title, String header, String content, int seconds) {
Platform.runLater(()->{
// close previous alert before showing a new one
Optional.ofNullable(currentAlertStage).ifPresent(Stage::close);
Stage alertStage = new Stage();
alertStage.initModality(Modality.APPLICATION_MODAL);
alertStage.initStyle(StageStyle.UTILITY);
alertStage.setAlwaysOnTop(true);
alertStage.setResizable(false);
double screenwidth = Screen.getPrimary().getVisualBounds().getWidth();
double width = screenwidth/4;
double height = width * 9 / 16;
Label headerLabel = new Label(header);
headerLabel.setStyle("-fx-font-weight: bold; -fx-font-size: 16px;");
headerLabel.setMinHeight(height*0.25);
Label contentLabel = new Label(content);
contentLabel.setStyle("-fx-font-size: 12px;");
contentLabel.setMinHeight(height*0.75);
VBox root = new VBox(10, headerLabel, contentLabel);
root.setPrefSize(width, height);
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root);
alertStage.setScene(scene);
alertStage.setTitle(title);
currentAlertStage = alertStage;
alertStage.show();
shownHeader = header;
shownContent = content;
shownTitle = title;
if (seconds>0){
PauseTransition delay = new PauseTransition(Duration.seconds(seconds));
delay.setOnFinished(e -> {
alertStage.close();
if (currentAlertStage == alertStage) {
currentAlertStage = null;
}
clear();
} );
delay.play();
}
});
}
}

View File

@@ -31,6 +31,7 @@ import org.bytedeco.opencv.global.opencv_imgcodecs;
import org.bytedeco.opencv.global.opencv_imgproc;
import org.bytedeco.opencv.opencv_core.*;
import org.opencv.videoio.Videoio;
import org.tinylog.Logger;
import java.awt.image.BufferedImage;
@@ -48,7 +49,6 @@ import static Config.SomeCodes.*;
import static id.co.gtc.erhacam.Detectors.*;
import static org.bytedeco.opencv.global.opencv_core.CV_8UC3;
import static org.bytedeco.opencv.global.opencv_core.mean;
import static org.bytedeco.opencv.global.opencv_imgcodecs.imwrite;
import static org.bytedeco.opencv.global.opencv_imgproc.*;
@SuppressWarnings({"unused"})
@@ -58,6 +58,7 @@ public class Cameradetail {
isCudaAvailable = opencv_core.getCudaEnabledDeviceCount()>0;
if (isCudaAvailable){
System.out.println("CUDA is available");
opencv_core.printCudaDeviceInfo(0);
} else {
System.out.println("CUDA is not available");
}
@@ -608,23 +609,27 @@ public class Cameradetail {
}
public String GetFullQualityPhotoPath(String directory, String prefix){
if (!ValidDirectory(directory)) directory = currentDirectory;
return Path.of(directory, "FullQuality", makeFileName(prefix,".png")).toString();
//if (!ValidDirectory(directory)) directory = currentDirectory;
//return Path.of(directory, "FullQuality", makeFileName(prefix,".png")).toString();
return Path.of(config.getFullQualityDirectory(), makeFileName(prefix,".png")).toString();
}
public String GetReducedPhotoPath(String directory, String prefix){
if (!ValidDirectory(directory)) directory = currentDirectory;
return Path.of(directory, "Compressed", makeReducedFileName(prefix,".jpg")).toString();
//if (!ValidDirectory(directory)) directory = currentDirectory;
//return Path.of(directory, "Compressed", makeReducedFileName(prefix,".jpg")).toString();
return Path.of(config.getCompressedDirectory(), makeFileName(prefix,".jpg")).toString();
}
public String GetFullQualityCropPhotoPath(String directory, String prefix){
if (!ValidDirectory(directory)) directory = currentDirectory;
return Path.of(directory, "FullQualityCrop", makeFileName(prefix,".png")).toString();
//if (!ValidDirectory(directory)) directory = currentDirectory;
//return Path.of(directory, "FullQualityCrop", makeFileName(prefix,".png")).toString();
return Path.of(config.getFullQualityCropDirectory(), makeFileName(prefix,".png")).toString();
}
public String GetReducedCropPhotoPath(String directory, String prefix){
if (!ValidDirectory(directory)) directory = currentDirectory;
return Path.of(directory, "CompressedCrop", makeReducedFileName(prefix,".jpg")).toString();
//if (!ValidDirectory(directory)) directory = currentDirectory;
//return Path.of(directory, "CompressedCrop", makeReducedFileName(prefix,".jpg")).toString();
return Path.of(config.getCompressedCropDirectory(), makeFileName(prefix,".jpg")).toString();
}
/**
@@ -643,18 +648,10 @@ public class Cameradetail {
}
TakingPhoto.set(true);
if (!BestMat.empty()){
Size sz = BestMat.size();
raise_log("TakePhoto got frame with width: " + sz.width() + " and height: " + sz.height());
// String timestamp = prefix+" "+SomeCodes.GetDateTimeString();
// Scalar color = new Scalar(255, 255, 255, 0); // white
// PutText(BestMat, timestamp, 4.0, color, 2);
// save BestMat at quality 9 PNG
String filename = GetFullQualityCropPhotoPath(directory, prefix);
//String filename = Path.of(directory, "FullQuality", makeFileName(prefix,".png")).toString();
String filename = GetFullQualityPhotoPath(directory, prefix);
if (opencv_imgcodecs.imwrite(filename, BestMat, parampng)){
result.setFullres(filename);
} else System.out.println("TakePhoto failed, Unable to Save FullQUality Photo for camera "+cameratitle.getText());
@@ -664,22 +661,9 @@ public class Cameradetail {
result.setFullcrop(xx);
result.setBestROI(new Rect(BestMatROI.x(), BestMatROI.y(), BestMatROI.width(), BestMatROI.height()));
}
// if (BestMatROI!=null){
// UMat FullCrop = CropUMat(BestMat, BestMatROI);
// if (FullCrop!=null){
// //String roifilename = Path.of(directory, "FullQualityCrop", makeFileName(prefix,".png")).toString();
// String roifilename = GetFullQualityCropPhotoPath(directory, prefix);
// if (!opencv_imgcodecs.imwrite(roifilename, FullCrop, parampng)){
// System.out.println("TakePhoto failed, Unable to Save FullQUalityCrop for camera "+cameratitle.getText());
// } else {
// result.setFullcrop(roifilename);
// result.setBestROI(new Rect(BestMatROI.x(), BestMatROI.y(), BestMatROI.width(), BestMatROI.height()));
// }
// }
// }
// save ReducedMat at 100% JPEG
//String reducedfilename = Path.of(directory, "Compressed", makeReducedFileName(prefix,".jpg")).toString();
String reducedfilename = GetReducedPhotoPath(directory, prefix);
opencv_imgproc.resize(BestMat, ReducedMat, ReducedSize);
if (!opencv_imgcodecs.imwrite(reducedfilename, ReducedMat, paramjpeg)){
@@ -691,19 +675,6 @@ public class Cameradetail {
result.setCompressedcrop(xy);
result.setReducedROI(new Rect(ReducedMatROI.x(), ReducedMatROI.y(), ReducedMatROI.width(), ReducedMatROI.height()));
}
// if (ReducedMatROI!=null){
// UMat ReducedCrop = CropUMat(ReducedMat, ReducedMatROI);
// if (ReducedCrop!=null){
// //String roifilename = Path.of(directory, "CompressedCrop", makeReducedFileName(prefix,".jpg")).toString();
// String roifilename = GetReducedCropPhotoPath(directory, prefix);
// if (!opencv_imgcodecs.imwrite(roifilename, ReducedCrop, paramjpeg)){
// System.out.println("TakePhoto failed, Unable to Save CompressedCrop for camera "+cameratitle.getText());
// } else {
// result.setCompressedcrop(roifilename);
// result.setReducedROI(new Rect(ReducedMatROI.x(), ReducedMatROI.y(), ReducedMatROI.width(), ReducedMatROI.height()));
// }
// }
// }
} else raise_log("TakePhoto failed, Live View is Empty");
} else raise_log("TakePhoto failed, Grabber is null");
@@ -711,22 +682,25 @@ public class Cameradetail {
return result;
}
public String CropBestMat(String directory, String prefix, Rect ROI){
if (!BestMat.empty()) {
UMat cloned = new UMat();
BestMat.copyTo(cloned);
if (!cloned.empty()) {
if (ValidROI(ROI)){
if (ROIInsideUMat(ROI, BestMat)){
UMat cropped = CropUMat(BestMat, ROI);
if (ROIInsideUMat(ROI, cloned)){
UMat cropped = CropUMat(cloned, ROI);
if (cropped != null) {
String filename = GetFullQualityCropPhotoPath(directory, prefix);
if (opencv_imgcodecs.imwrite(filename, cropped, parampng)) {
System.out.println("CropBestMat success, saved as " + filename);
Wait(500);
Logger.info("CropBestMat success, saved as " + filename);
return filename;
} //else System.out.println("CropBestMat failed, Unable to Save BestMat");
} //else System.out.println("CropBestMat failed, Unable to Crop BestMat");
} //else System.out.println("CropBestMat failed, ROI is outside BestMat");
} //else System.out.println("CropBestMat failed, ROI is invalid");
} //else System.out.println("CropBestMat failed, BestMat is empty");
} else Logger.error("CropBestMat failed, Unable to Save BestMat as ",filename);
} else Logger.error("CropBestMat failed, Unable to Crop BestMat");
} else Logger.error("CropBestMat failed, ROI is outside BestMat");
} else Logger.error("CropBestMat failed, ROI is invalid");
} else Logger.error("CropBestMat failed, BestMat is empty");
return null;
}
@@ -738,14 +712,13 @@ public class Cameradetail {
if (cropped!=null){
String filename = GetReducedCropPhotoPath(directory, prefix);
if (opencv_imgcodecs.imwrite(filename, cropped, paramjpeg)){
System.out.println("CropReducedMat success, saved as "+filename);
Wait(100);
Logger.info("CropReducedMat success, saved as ",filename);
return filename;
} //else System.out.println("CropReducedMat failed, Unable to Save ReducedMat");
} //else System.out.println("CropReducedMat failed, Unable to Crop ReducedMat");
} //else System.out.println("CropReducedMat failed, ROI is outside ReducedMat");
} //else System.out.println("CropReducedMat failed, ROI is invalid");
} //else System.out.println("CropReducedMat failed, ReducedMat is empty");
} else Logger.error("CropReducedMat failed, Unable to Save ReducedMat as ",filename);
} else Logger.error("CropReducedMat failed, Unable to Crop ReducedMat");
} else Logger.error("CropReducedMat failed, ROI is outside ReducedMat");
} else Logger.error("CropReducedMat failed, ROI is invalid");
} else Logger.error("CropReducedMat failed, ReducedMat is empty");
return null;
}
@@ -770,7 +743,8 @@ public class Cameradetail {
Capturing.set(false);
if (mGrabber!=null){
try{
mGrabber.stop();
mGrabber.close();
System.out.println("Camera "+cameratitle.getText()+" stopped");
Platform.runLater(()->setCameraStatus("Camera Stopped"));
} catch (Exception e){
raise_log("StopLiveView failed, Unable to Stop Camera, Error: " + e.getMessage());
@@ -827,6 +801,8 @@ public class Cameradetail {
LiveFPS = 0;
mGrabber.start();
mGrabber.flush();
System.out.println("Camera "+cameratitle+" started");
Capturing.set(true);
// just information
@@ -870,6 +846,8 @@ public class Cameradetail {
boolean have_fist = false;
int no_face_counter = 0;
int face_counter = 0;
int open_eye_counter = 0;
int close_eye_counter = 0;
while (Capturing.get()) {
try {
@@ -880,11 +858,26 @@ public class Cameradetail {
if (!Capturing.get()) return null;
IsGrabbingLiveView.set(true);
Frame frame=null;
Frame frame;
try{
frame = mGrabber.grab(); // grab frame
} catch (Exception e){
System.out.println("Exception on grab frame from camera "+cameratitle+", Message : "+e.getMessage());
frame = null;
if (e.getMessage()!=null && e.getMessage().length()>0){
String msg = e.getMessage();
if (msg.contains("start() been called")){
if (Capturing.get()){
System.out.println("Camera "+cameratitle+" has been stopped, restarting");
mGrabber.close();
Wait(100);
mGrabber.start();
mGrabber.flush();
} else {
System.out.println("Camera "+cameratitle+" has been stopped, not restarting");
}
} else System.out.println("Exception on grab frame from camera "+cameratitle+", Message : "+e.getMessage());
}
}
if (frame==null) continue;
Mat mat = matconverter.convert(frame); // convert to Mat
@@ -892,7 +885,10 @@ public class Cameradetail {
UMat originalmat = new UMat();
mat.copyTo(originalmat); // copy to BestMat for using OpenCL
opencv_core.rotate(originalmat, BestMat, opencv_core.ROTATE_90_COUNTERCLOCKWISE);
// revisi 18/03/2025
UMat flippedmat = new UMat();
opencv_core.flip(originalmat, flippedmat, 1); // flip horizontal
opencv_core.rotate(flippedmat, BestMat, opencv_core.ROTATE_90_COUNTERCLOCKWISE);
IsGrabbingLiveView.set(false);
if (!BestMat.empty()) {
@@ -962,21 +958,29 @@ public class Cameradetail {
if (theface.haveEyes()){
// ada mata (buka mata)
close_eye_counter=0;
if (open_eye_counter<1){
open_eye_counter++;
continue;
}
System.out.println("Valid Open Eyes");
if (eye_state==0){
// transisi dari tutup mata ke buka mata
//System.out.println("Eye Open Detected from camera "+cameratitle);
System.out.println("Transition from close to open eyes");
long now = System.currentTimeMillis();
if (waiting_for_second_blink){
long diff = now - last_blink;
// kalau beda waktu antara blink 1 dan blink 2 kurang dari 10 detik
if (diff<=10000){
waiting_for_second_blink = false;
//System.out.println("Double Blink Detected from camera "+cameratitle);
System.out.println("Double Blink Detected from camera "+cameratitle);
if (event!=null) event.onBlink((int)diff);
}
} else {
waiting_for_second_blink = true;
//System.out.println("First Blink Detected from camera "+cameratitle);
System.out.println("First Blink Detected from camera "+cameratitle);
}
last_blink = now;
}
@@ -984,28 +988,36 @@ public class Cameradetail {
} else {
// ada muka, tidak ada mata
// transisi dari buka mata ke tutup mata
open_eye_counter=0;
if (close_eye_counter<1){
close_eye_counter++;
continue;
}
System.out.println("Valid Closed Eyes");
if (eye_state!=0){
//System.out.println("Eye Closed Detected from camera "+cameratitle);
System.out.println("Transition from open to close eyes");
}
eye_state = 0;
}
} else if (have_left_45_face ){
no_face_counter = 0;
if (event!=null) event.onProfileFaceDetector(true, _face_width, _face_height);
} else {
// no face detected, but let's not cancel the previous state immediately
if (no_face_counter>60){
if (no_face_counter>30){
// kalau tidak ada face selama 30 frame, reset state
// 60 frame approximately 2 second
// 30 frame approximately 2 second
eye_state = -1;
last_blink = 0;
waiting_for_second_blink = false;
face_counter = 0;
if (close_eye_counter!=0 || open_eye_counter!=0){
close_eye_counter=0;
open_eye_counter=0;
System.out.println("Reset Open and Close Eyes");
}
if (event!=null) {
event.onFrontalFaceDetector(false, _face_width, _face_height);
event.onProfileFaceDetector(false, _face_width, _face_height);
@@ -1040,7 +1052,9 @@ public class Cameradetail {
updateValue(matToWritableImage(imgmat, imgmat.cols(), imgmat.rows()));
}
} catch (Exception e) {
raise_log("Unable to Grab Frame, Error: " + e.getMessage());
if (ValidString(e.getMessage())){
raise_log("Unable to Grab Frame, Error: " + e.getMessage());
}
//if (!Capturing.get()) Platform.runLater(this::StopLiveView);
}
}
@@ -1067,17 +1081,19 @@ public class Cameradetail {
return false;
}
/**
* Remap LiveMatROI to BestMatROI and ReducedMatROI Resolution
* @param scaleX scale factor for width
* @param scaleY scale factor for height
*/
public void RemapROI(double scaleX, double scaleY){
public void RemapROI(double scaleX, double scaleY, boolean printdebug){
BestMatROI = null;
ReducedMatROI = null;
if (ValidROI(LiveMatROI)){
if (ROIInsideUMat(LiveMatROI, LiveMat)){
System.out.println("LiveMatROI camera "+cameratitle.getText()+" = "+RectToString(LiveMatROI));
if (printdebug) System.out.println("LiveMatROI camera "+cameratitle.getText()+" = "+RectToString(LiveMatROI));
double scaleXBest = 1.0*BestSize.width()/LiveSize.width();
double scaleYBest = 1.0*BestSize.height()/LiveSize.height();
@@ -1096,8 +1112,11 @@ public class Cameradetail {
HBest = HBest + deltaHBest;
if (HBest>BestSize.height()) HBest = BestSize.height();
BestMatROI = new Rect(XBest, YBest, WBest, HBest);
System.out.println("scaleXBest = "+scaleXBest+" scaleYBest = "+scaleYBest);
System.out.println("BestMatROI camera "+cameratitle.getText()+" = "+RectToString(BestMatROI));
if (printdebug){
System.out.println("scaleXBest = "+scaleXBest+" scaleYBest = "+scaleYBest);
System.out.println("BestMatROI camera "+cameratitle.getText()+" = "+RectToString(BestMatROI));
}
double scaleXReduced = 1.0*ReducedSize.width()/LiveSize.width();
double scaleYReduced = 1.0*ReducedSize.height()/LiveSize.height();
@@ -1116,8 +1135,11 @@ public class Cameradetail {
HReduced = HReduced + deltaHReduced;
if (HReduced>ReducedSize.height()) HReduced = ReducedSize.height();
ReducedMatROI = new Rect(XReduced, YReduced, WReduced, HReduced);
System.out.println("scaleXReduced = "+scaleXReduced+" scaleYReduced = "+scaleYReduced);
System.out.println("ReducedMatROI camera "+cameratitle.getText()+" = "+RectToString(ReducedMatROI));
if (printdebug){
System.out.println("scaleXReduced = "+scaleXReduced+" scaleYReduced = "+scaleYReduced);
System.out.println("ReducedMatROI camera "+cameratitle.getText()+" = "+RectToString(ReducedMatROI));
}
} //else System.out.println("LiveMatROI is Outside LiveMat for camera "+cameratitle.getText());
} //else System.out.println("LiveMatROI is invalid for camera "+cameratitle.getText());

View File

@@ -12,17 +12,14 @@ import ErhaAPI.BarcodeResullt;
import ErhaAPI.PhotoResult;
import ErhaAPI.PatientRecord;
import ErhaAPI.UploadResult;
import FTP.FTPUpload;
import FTP.FTPUploadEvent;
import FTP.FtpMonitorData;
import javafx.application.Platform;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.concurrent.Task;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.layout.AnchorPane;
import javafx.stage.DirectoryChooser;
@@ -64,9 +61,6 @@ public class CaptureView {
private Cameradetail image1, image2, image3, image4, image5;
@FXML
private TextArea directorypath;
@FXML
private TextArea barcodeData;
@FXML
@@ -74,15 +68,6 @@ public class CaptureView {
@FXML
private TextArea PatientName;
@FXML
private Button btnTakePhoto;
@FXML
private Button btnAutoFocus;
@FXML
private AnchorPane progressanchor;
private AudioPlayer audioPlayer;
private String audio_posisikan_muka = "posisikan_wajah.wav";
private String audio_scan_barcode = "scan_barcode.wav";
@@ -91,6 +76,7 @@ public class CaptureView {
private String audio_upload_berhasil = "upload_berhasil.wav";
private String audio_upload_gagal = "upload_gagal.wav";
private String audio_countdown = "countdown321.wav";
private String audio_tahan_posisi = "tahan_posisi.wav";
private List<String> cams;
@@ -105,6 +91,7 @@ public class CaptureView {
private final ErhaAPI erhaAPI = new ErhaAPI(false);
private final double sharpness_threshold = 150;
@FXML
private void ChangeDirectory(){
DirectoryChooser dc = new DirectoryChooser();
@@ -113,7 +100,6 @@ public class CaptureView {
config.SetPhotoDirectory(path);
config.Save();
directorypath.setText(path);
}
private void trigger_autofocus(Cameradetail image) throws InterruptedException {
@@ -139,29 +125,34 @@ public class CaptureView {
}
@SuppressWarnings("resource")
@FXML
private void TakePhotos(){
boolean has_face = Arrays.stream(have_face).anyMatch(AtomicBoolean::get);
if (has_face){
AutoCloseAlert.show("Pengambilan Foto", "Tahan Posisi Anda", "Proses ini kurang lebih 3 detik", 5);
if (audioPlayer!=null && audioPlayer.isInited()){
if (!audioPlayer.getCurrentFile().equals(audio_countdown)) {
audioPlayer.StopCurrentPlayback();
Wait(200);
}
audioPlayer.PlayFile(audio_countdown, ps);
audioPlayer.PlayFile(audio_tahan_posisi, ps);
} else System.out.println("audioPlayer already playing countdown");
}
try{
AutoFocus();
Thread.sleep(2000);
} catch (InterruptedException e){
Logger.error("Error AutoFocus: "+e.getMessage());
}
// try{
// AutoFocus();
// Thread.sleep(1000);
// } catch (InterruptedException e){
// Logger.error("Error AutoFocus: "+e.getMessage());
// }
Size thumbsize = new Size(160,120);
String directory = directorypath.getText();
String directory = config.getPhotoDirectory();
String prefix = RemoveSpaces(medicalRecordID.getText()) ;
if (ValidDirectory(directory)){
if (ValidMedicalRecordId(prefix)){
@@ -175,12 +166,17 @@ public class CaptureView {
Callable<PhotoResult> task1 = ()->{
if (image1!=null) {
image1.RemapROI(0.1,0.3);
image1.RemapROI(0.1,0.3, false);
double sharpness = CalculateSharpness(image1.getBestMat());
if (sharpness<sharpness_threshold){
AutoCloseAlert.show("Take Photos Failed", "Blurred Image Detected", "Blurred Image Detected at Camera 1 with sharpness score "+sharpness, 5);
return null;
}
PhotoResult p1 = image1.TakePhoto(directory,prefix);
//System.out.println("PhotoResult P1 :");
//System.out.println(p1);
if (ValidFile(p1.getFullres())){
if (ValidFile(p1.getCompressedfile())){
p1.setSharpscore(sharpness);
return p1;
}
}
@@ -189,12 +185,16 @@ public class CaptureView {
};
Callable<PhotoResult> task2 = ()->{
if (image2!=null) {
image2.RemapROI(0.1,0.3);
image2.RemapROI(0.1,0.3, false);
double sharpness = CalculateSharpness(image2.getBestMat());
if (sharpness<sharpness_threshold){
AutoCloseAlert.show("Take Photos Failed", "Blurred Image Detected", "Blurred Image Detected at Camera 2 with sharpness score "+sharpness, 5);
return null;
}
PhotoResult p2 = image2.TakePhoto(directory,prefix);
//System.out.println("PhotoResult P2 :");
//System.out.println(p2);
if (ValidFile(p2.getFullres())){
if (ValidFile(p2.getCompressedfile())){
p2.setSharpscore(sharpness);
return p2;
}
}
@@ -204,12 +204,17 @@ public class CaptureView {
Callable<PhotoResult> task3 = ()->{
if (image3!=null) {
image3.RemapROI(0.1,0.3);
image3.RemapROI(0.1,0.3, false);
double sharpness = CalculateSharpness(image3.getBestMat());
if (sharpness<sharpness_threshold){
AutoCloseAlert.show("Take Photos Failed", "Blurred Image Detected", "Blurred Image Detected at Camera 3 with sharpness score "+sharpness, 5);
return null;
}
PhotoResult p3 = image3.TakePhoto(directory,prefix);
//System.out.println("PhotoResult P3 :");
//System.out.println(p3);
if (ValidFile(p3.getFullres())){
if (ValidFile(p3.getCompressedfile())){
p3.setSharpscore(sharpness);
return p3;
}
}
@@ -220,12 +225,17 @@ public class CaptureView {
Callable<PhotoResult> task4 = ()->{
if (image4!=null) {
image4.RemapROI(0.1,0.3);
image4.RemapROI(0.1,0.3, false);
double sharpness = CalculateSharpness(image4.getBestMat());
if (sharpness<sharpness_threshold){
AutoCloseAlert.show("Take Photos Failed", "Blurred Image Detected", "Blurred Image Detected at Camera 4 with sharpness score "+sharpness, 5);
return null;
}
PhotoResult p4 = image4.TakePhoto(directory,prefix);
//System.out.println("PhotoResult P4 :");
//System.out.println(p4);
if (ValidFile(p4.getFullres())){
if (ValidFile(p4.getCompressedfile())){
p4.setSharpscore(sharpness);
return p4;
}
}
@@ -236,12 +246,17 @@ public class CaptureView {
Callable<PhotoResult> task5 = ()->{
if (image5!=null) {
image5.RemapROI(0.1,0.3);
image5.RemapROI(0.1,0.3, false);
double sharpness = CalculateSharpness(image5.getBestMat());
if (sharpness<sharpness_threshold){
AutoCloseAlert.show("Take Photos Failed", "Blurred Image Detected", "Blurred Image Detected at Camera 5 with sharpness score "+sharpness, 5);
return null;
}
PhotoResult p5 = image5.TakePhoto(directory,prefix);
//System.out.println("PhotoResult P5 :");
//System.out.println(p5);
if (ValidFile(p5.getFullres())){
if (ValidFile(p5.getCompressedfile())){
p5.setSharpscore(sharpness);
return p5;
}
}
@@ -279,6 +294,37 @@ public class CaptureView {
String timestamp = SomeCodes.GetDateTimeString();
System.out.println("Creating timestamp: "+timestamp);
// check for blurred image
double score1=0, score2=0, score3=0, score4=0, score5=0;
if (p1!=null){
score1 = p1.getSharpscore();
}
if (p2!=null){
score2 = p2.getSharpscore();
}
if (p3!=null){
score3 = p3.getSharpscore();
}
if (p4!=null){
score4 = p4.getSharpscore();
}
if (p5!=null){
score5 = p5.getSharpscore();
}
System.out.println("Sharpness score: "+score1+", "+score2+", "+score3+", "+score4+", "+score5);
double lowest = FindLowestValue(score1,score2,score3,score4,score5);
if (lowest<sharpness_threshold){
String culprit = "";
if (lowest==score1) culprit = "camera 1";
else if (lowest==score2) culprit = "camera 2";
else if (lowest==score3) culprit = "camera 3";
else if (lowest==score4) culprit = "camera 4";
else if (lowest==score5) culprit = "camera 5";
AutoCloseAlert.show("Take Photos Failed", "Blurred Image Detected", "Blurred Image Detected at "+culprit+" with sharpness score "+lowest, 5);
return;
}
Rect bestroi = null;
Rect reducedroi = null;
if (p1!=null && p1.getBestROI()!=null){
@@ -327,120 +373,118 @@ public class CaptureView {
reducedroi = p5.getReducedROI();
}
prc.setFileLeft90(p1.getFullres());
prc.setFileLeft45(p2.getFullres());
prc.setFileCenter(p3.getFullres());
prc.setFileRight45(p4.getFullres());
prc.setFileRight90(p5.getFullres());
prc.setCompressedLeft90(p1.getCompressedfile());
prc.setCompressedLeft45(p2.getCompressedfile());
prc.setCompressedCenter(p3.getCompressedfile());
prc.setCompressedRight45(p4.getCompressedfile());
prc.setCompressedRight90(p5.getCompressedfile());
if (ValidFile(p1.getFullcrop())){
// ada crop
prc.setCroppedLeft90(p1.getFullcrop());
} else {
String xx = image1.CropBestMat(directory,prefix, bestroi);
if (ValidFile(xx)) prc.setCroppedLeft90(xx);
}
if (ValidFile(p2.getFullcrop())){
// ada crop
prc.setCroppedLeft45(p2.getFullcrop());
} else {
String xx = image2.CropBestMat(directory,prefix, bestroi);
if (ValidFile(xx)) prc.setCroppedLeft45(xx);
}
if (ValidFile(p3.getFullcrop())){
// ada crop
prc.setCroppedCenter(p3.getFullcrop());
} else {
String xx = image3.CropBestMat(directory,prefix, bestroi);
if (ValidFile(xx)) prc.setCroppedCenter(xx);
}
if (ValidFile(p4.getFullcrop())){
// ada crop
prc.setCroppedRight45(p4.getFullcrop());
} else {
String xx = image4.CropBestMat(directory,prefix, bestroi);
if (ValidFile(xx)) prc.setCroppedRight45(xx);
}
if (ValidFile(p5.getFullcrop())){
// ada crop
prc.setCroppedRight90(p5.getFullcrop());
} else {
String xx = image5.CropBestMat(directory,prefix, bestroi);
if (ValidFile(xx)) prc.setCroppedRight90(xx);
}
if (ValidFile(p1.getCompressedcrop())){
prc.setCompressedCropLeft90(p1.getCompressedcrop());
} else {
String xx =image1.CropReducedMat(directory,prefix, reducedroi);
if (ValidFile(xx)) prc.setCompressedCropLeft90(xx);
}
if (ValidFile(p2.getCompressedcrop())){
prc.setCompressedCropLeft45(p2.getCompressedcrop());
} else {
String xx = image2.CropReducedMat(directory,prefix, reducedroi);
if (ValidFile(xx)) prc.setCompressedCropLeft45(xx);
}
if (ValidFile(p3.getCompressedcrop())){
prc.setCompressedCropCenter(p3.getCompressedcrop());
} else {
String xx = image3.CropReducedMat(directory,prefix, reducedroi);
if (ValidFile(xx)) prc.setCompressedCropCenter(xx);
}
if (ValidFile(p4.getCompressedcrop())){
prc.setCompressedCropRight45(p4.getCompressedcrop());
} else {
String xx = image4.CropReducedMat(directory,prefix, reducedroi);
if (ValidFile(xx)) prc.setCompressedCropRight45(xx);
}
if (ValidFile(p5.getCompressedcrop())){
prc.setCompressedCropRight90(p5.getCompressedcrop());
} else {
String xx= image5.CropReducedMat(directory,prefix, reducedroi);
if (ValidFile(xx)) prc.setCompressedCropRight90(xx);
}
if (p1!=null){
prc.setFileLeft90(ValidFile(p1.getFullres()) ? p1.getFullres() : "");
prc.setCompressedLeft90(ValidFile(p1.getCompressedfile()) ? p1.getCompressedfile() : "");
if (ValidFile(p1.getFullcrop())){
// ada crop
prc.setCroppedLeft90(p1.getFullcrop());
} else {
String xx = image1.CropBestMat(directory,prefix, bestroi);
if (ValidFile(xx)) prc.setCroppedLeft90(xx);
}
if (ValidFile(p1.getCompressedcrop())){
prc.setCompressedCropLeft90(p1.getCompressedcrop());
} else {
String xx =image1.CropReducedMat(directory,prefix, reducedroi);
if (ValidFile(xx)) prc.setCompressedCropLeft90(xx);
}
String thumb1 = MakeThumbfile(p1.getFullres(), thumbsize);
if (ValidFile(thumb1)) prc.setThumbLeft90(thumb1);
}
if (p2!=null){
prc.setFileLeft45(ValidFile(p2.getFullres()) ? p2.getFullres() : "");
prc.setCompressedLeft45(ValidFile(p2.getCompressedfile()) ? p2.getCompressedfile() : "");
if (ValidFile(p2.getFullcrop())){
// ada crop
prc.setCroppedLeft45(p2.getFullcrop());
} else {
String xx = image2.CropBestMat(directory,prefix, bestroi);
if (ValidFile(xx)) prc.setCroppedLeft45(xx);
}
if (ValidFile(p2.getCompressedcrop())){
prc.setCompressedCropLeft45(p2.getCompressedcrop());
} else {
String xx = image2.CropReducedMat(directory,prefix, reducedroi);
if (ValidFile(xx)) prc.setCompressedCropLeft45(xx);
}
String thumb2 = MakeThumbfile(p2.getFullres(), thumbsize);
if (ValidFile(thumb2)) prc.setThumbLeft45(thumb2);
}
if (p3!=null){
prc.setFileCenter(ValidFile(p3.getFullres()) ? p3.getFullres() : "");
prc.setCompressedCenter(ValidFile(p3.getCompressedfile()) ? p3.getCompressedfile() : "");
if (ValidFile(p3.getFullcrop())){
// ada crop
prc.setCroppedCenter(p3.getFullcrop());
} else {
String xx = image3.CropBestMat(directory,prefix, bestroi);
if (ValidFile(xx)) prc.setCroppedCenter(xx);
}
if (ValidFile(p3.getCompressedcrop())){
prc.setCompressedCropCenter(p3.getCompressedcrop());
} else {
String xx = image3.CropReducedMat(directory,prefix, reducedroi);
if (ValidFile(xx)) prc.setCompressedCropCenter(xx);
}
String thumb3 = MakeThumbfile(p3.getFullres(), thumbsize);
if (ValidFile(thumb3)) prc.setThumbCenter(thumb3);
}
if (p4!=null){
prc.setFileRight45(ValidFile(p4.getFullres()) ? p4.getFullres() : "");
prc.setCompressedRight45(ValidFile(p4.getCompressedfile()) ? p4.getCompressedfile() : "");
if (ValidFile(p4.getFullcrop())){
// ada crop
prc.setCroppedRight45(p4.getFullcrop());
} else {
String xx = image4.CropBestMat(directory,prefix, bestroi);
if (ValidFile(xx)) prc.setCroppedRight45(xx);
}
if (ValidFile(p4.getCompressedcrop())){
prc.setCompressedCropRight45(p4.getCompressedcrop());
} else {
String xx = image4.CropReducedMat(directory,prefix, reducedroi);
if (ValidFile(xx)) prc.setCompressedCropRight45(xx);
}
String thumb4 = MakeThumbfile(p4.getFullres(), thumbsize);
if (ValidFile(thumb4)) prc.setThumbRight45(thumb4);
}
if (p5!=null){
prc.setFileRight90(ValidFile(p5.getFullres()) ? p5.getFullres() : "");
prc.setCompressedRight90(ValidFile(p5.getCompressedfile()) ? p5.getCompressedfile() : "");
if (ValidFile(p5.getFullcrop())){
// ada crop
prc.setCroppedRight90(p5.getFullcrop());
} else {
String xx = image5.CropBestMat(directory,prefix, bestroi);
if (ValidFile(xx)) prc.setCroppedRight90(xx);
}
if (ValidFile(p5.getCompressedcrop())){
prc.setCompressedCropRight90(p5.getCompressedcrop());
} else {
String xx= image5.CropReducedMat(directory,prefix, reducedroi);
if (ValidFile(xx)) prc.setCompressedCropRight90(xx);
}
String thumb5 = MakeThumbfile(p5.getFullres(), thumbsize);
if (ValidFile(thumb5)) prc.setThumbRight90(thumb5);
}
long duration = (System.nanoTime() - nanostart) / 1000000; // in milliseconds
System.out.println("TakePhotos duration: "+duration+" ms");
Platform.runLater(()->{
progressanchor.getChildren().clear();
barcodeData.setText("");
medicalRecordID.setText("");
PatientName.setText("");
isTakingPhoto.set(false);
});
AutoCloseAlert.show("Photos Taken", "Photos Taken", "Photos Taken", 5);
if (audioPlayer!=null && audioPlayer.isInited()){
if (!audioPlayer.getCurrentFile().equals(audio_pengambilan_berhasil)) {
audioPlayer.StopCurrentPlayback();
Wait(200);
}
audioPlayer.PlayFile(audio_pengambilan_berhasil, ps);
audioPlayer.PlayFile(audio_pengambilan_berhasil, ps);
} else System.out.println("audioPlayer already playing pengambilan berhasil");
}
// file untuk di upload
String[] files = prc.compressed();
if (files.length>0){
InsertSQL(prc);
@@ -450,7 +494,7 @@ public class CaptureView {
int totalfiles = files.length;
int counter = 0;
for (String ff : files) {
UploadResult ur = erhaAPI.Upload_File(prefix, ff);
UploadResult ur = erhaAPI.Upload_File(prefix, ff,true);
if (ur != null) {
if (ur.message.startsWith("Record has been created")) {
counter++;
@@ -475,90 +519,57 @@ public class CaptureView {
uploadtask.setOnSucceeded(e-> {
System.out.println("UploadTask succeeded");
if (audioPlayer!=null && audioPlayer.isInited()){
if (!audioPlayer.getCurrentFile().equals(audio_upload_berhasil)) {
audioPlayer.StopCurrentPlayback();
Wait(200);
}
audioPlayer.PlayFile(audio_upload_berhasil, ps);
audioPlayer.WaitUntilFinished();
audioPlayer.PlayFile(audio_upload_berhasil, ps);
} else System.out.println("audioPlayer already playing upload berhasil");
}
AutoCloseAlert.show("Upload Success", "Upload Success", "Upload Success", 5);
Platform.runLater(()->{
barcodeData.setText("");
medicalRecordID.setText("");
PatientName.setText("");
isTakingPhoto.set(false);
});
});
uploadtask.setOnFailed(e-> {
System.out.println("UploadTask failed");
if (audioPlayer!=null && audioPlayer.isInited()){
if (!audioPlayer.getCurrentFile().equals(audio_upload_gagal)) {
audioPlayer.StopCurrentPlayback();
Wait(200);
}
audioPlayer.PlayFile(audio_upload_gagal, ps);
audioPlayer.WaitUntilFinished();
audioPlayer.PlayFile(audio_upload_gagal, ps);
} else System.out.println("audioPlayer already playing upload gagal");
}
AutoCloseAlert.show("Upload Failed", "Upload Failed", "Upload Failed", 5);
Platform.runLater(()->{
barcodeData.setText("");
medicalRecordID.setText("");
PatientName.setText("");
isTakingPhoto.set(false);
});
});
new Thread(uploadtask).start();
} else ShowAlert(AlertType.ERROR, "Error", "No Photos Taken", "No Photos Taken, please check camera");
} else ShowAlert(AlertType.ERROR, "Error", "Invalid Prefix", "Please input valid prefix or scan QR Code");
} else ShowAlert(AlertType.ERROR,"Error","Invalid Directory","Please select valid directory");
// new Thread(()-> {
// try{
// InetAddress target = InetAddress.getByName(config.getFTPHost());
// int port = toInt(config.getFTPPort());
// if (target.isReachable(2000)){
// Socket socket = new Socket();
// InetSocketAddress isa = new InetSocketAddress(target, port);
// socket.connect(isa,2000);
// socket.close();
// // sampai sini berarti FTP Host reachable
// UploadToFTP(files);
// } else throw new Exception("FTP Host not reachable");
// } catch (Exception e){
// Logger.error("Error UploadToFTP: "+e.getMessage());
// Platform.runLater(()->{
// Alert alert = new Alert(AlertType.ERROR);
// alert.setTitle("Error");
// alert.setHeaderText("Upload to FTP Failed");
// alert.setContentText("Error: "+e.getMessage());
// alert.showAndWait();
// });
//
// }
// }).start();
} else {
Alert Alert = new Alert(AlertType.ERROR);
Alert.setTitle("Error");
Alert.setHeaderText("No Photos Taken");
Alert.setContentText("No Photos Taken, please check camera");
Alert.showAndWait();
}
} else {
Alert Alert = new Alert(AlertType.ERROR);
Alert.setTitle("Error");
Alert.setHeaderText("Invalid Prefix");
Alert.setContentText("Please input valid prefix or scan QR Code");
Alert.showAndWait();
}
} else {
Alert Alert = new Alert(AlertType.ERROR);
Alert.setTitle("Error");
Alert.setHeaderText("Invalid Directory");
Alert.setContentText("Please select valid directory");
Alert.showAndWait();
}
} else {
AutoCloseAlert.show("Error", "No Face Detected", "No Face Detected", 5);
if (audioPlayer!=null && audioPlayer.isInited()){
if (!audioPlayer.getCurrentFile().equals(audio_posisikan_muka)) {
audioPlayer.StopCurrentPlayback();
Wait(200);
}
audioPlayer.PlayFile(audio_posisikan_muka, ps);
audioPlayer.PlayFile(audio_posisikan_muka, ps);
} else System.out.println("audioPlayer already playing posisikan muka");
}
}
@@ -566,11 +577,6 @@ public class CaptureView {
}
private void UpdateBtnTakePhoto(){
boolean valid = ValidDirectory(directorypath.getText()) && ValidString(barcodeData.getText()) && ValidString(medicalRecordID.getText()) && ValidString(PatientName.getText());
btnTakePhoto.setDisable(!valid);
}
@FXML
public void initialize(){
audio_posisikan_muka = ExtractResource("/posisikan_wajah.wav");
@@ -580,16 +586,29 @@ public class CaptureView {
audio_upload_berhasil = ExtractResource("/upload_berhasil.wav");
audio_upload_gagal = ExtractResource("/upload_gagal.wav");
audio_countdown = ExtractResource("/countdown321.wav");
audio_tahan_posisi = ExtractResource("/tahan_posisi.wav");
//tambahan 19/03/2025
barcodeData.textProperty().addListener(new InvalidationListener() {
@Override
public void invalidated(Observable observable) {
String barcode = barcodeData.getText();
System.out.println("barcodeData invalidated, value: "+barcode);
if (ValidBarCode(barcode)){
if (AutoCloseAlert.shownTitle.equals("Scan Barcode")){
AutoCloseAlert.close();
}
} else {
AutoCloseAlert.show("Scan Barcode", "Silahkan Scan Barcode Anda", "Arahkan kertas barcode ke kamera", 0);
}
}
});
barcodeData.setText("");
audioPlayer = new AudioPlayer(1,48000);
Logger.info("Audio Player : "+(audioPlayer.isInited()? "Inited" : "Not Inited"));
btnTakePhoto.setDisable(true);
directorypath.textProperty().addListener((obs, oldval, newval)-> UpdateBtnTakePhoto());
barcodeData.textProperty().addListener((obs, oldval, newval)-> UpdateBtnTakePhoto());
medicalRecordID.textProperty().addListener((obs, oldval, newval)-> UpdateBtnTakePhoto());
PatientName.textProperty().addListener((obs, oldval, newval)-> UpdateBtnTakePhoto());
cams = null;
try{
String[] xxx = VideoInputFrameGrabber.getDeviceDescriptions();
@@ -678,10 +697,9 @@ public class CaptureView {
}
}
directorypath.setText(config.getPhotoDirectory());
progressanchor.prefWidthProperty().bind(controlpane.widthProperty());
});
}
public void Unload(){
@@ -879,7 +897,7 @@ public class CaptureView {
Task<PatientRecord> checkpatientID = new Task<>() {
@Override
protected PatientRecord call() {
BarcodeResullt br = erhaAPI.Validate_Barcode(finalbarCode);
BarcodeResullt br = erhaAPI.Validate_Barcode(finalbarCode,true);
if (br!=null){
if (br.message.startsWith("Records found")){
if (br.data!=null && br.data.length>0){
@@ -911,8 +929,8 @@ public class CaptureView {
if (!audioPlayer.getCurrentFile().equals(audio_posisikan_muka)) {
audioPlayer.StopCurrentPlayback();
Wait(200);
}
audioPlayer.PlayFile(audio_posisikan_muka, ps);
audioPlayer.PlayFile(audio_posisikan_muka, ps);
} else System.out.println("audioPlayer already playing posisikan muka");
}
}
@@ -927,6 +945,7 @@ public class CaptureView {
});
System.out.println("checkpatientID failed");
AutoCloseAlert.show("Error","checkpatientID failed","checkpatientID failed",5);
});
new Thread(checkpatientID).start();
@@ -1001,15 +1020,18 @@ public class CaptureView {
String prefix = medicalRecordID.getText();
if (!prefix.isEmpty()){
System.out.println("Prefix valid, taking photo");
btnTakePhoto.fire();
TakePhotos();
} else {
System.out.println("Prefix invalid, not taking photo");
isTakingPhoto.set(false);
AutoCloseAlert.show("QR Code Not Available", "", "Please scan QR before continue", 5);
if (audioPlayer!=null && audioPlayer.isInited()){
if (!audioPlayer.getCurrentFile().equals(audio_scan_barcode)) {
audioPlayer.StopCurrentPlayback();
Wait(200);
}
audioPlayer.PlayFile(audio_scan_barcode, ps);
audioPlayer.PlayFile(audio_scan_barcode, ps);
} else System.out.println("audioPlayer already playing scan barcode");
}
}
@@ -1117,157 +1139,6 @@ public class CaptureView {
}
}
@Deprecated
private void UploadToFTP(String[] files){
final double uploadprogressheight = 50;
Map<String, UploadProgress> progressmap = new HashMap<>();
// Load uploadprogress.fxml for each file
for (String filetoupload : files){
Task<AnchorPane> loadtask = new Task<>() {
@Override
protected AnchorPane call() throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("uploadprogress.fxml"));
AnchorPane pane = loader.load();
pane.prefWidthProperty().bind(progressanchor.widthProperty());
pane.setPrefHeight(uploadprogressheight);
UploadProgress up = loader.getController();
up.SetFile(filetoupload);
up.SetStatus("Initialized");
up.SetProgress(0,0);
int ii = progressmap.size();
AnchorPane.setTopAnchor(pane, (ii*uploadprogressheight)+10);
progressmap.put(GetFileName(filetoupload), up);
return pane;
}
};
// kalau berhasil, add ke progressanchor
loadtask.setOnSucceeded(e-> progressanchor.getChildren().add(loadtask.getValue()));
// kalau gagal, log error
loadtask.setOnFailed(e-> Logger.error("Error LoadTask: {}",e.getSource().getMessage()));
new Thread(loadtask).start();
}
InvalidationListener progressanchorlistener = observable -> {
// kalau sudah selesai load semua, mulai upload
Logger.info("Progress Anchor Children Size: {}", progressanchor.getChildren().size());
if (progressanchor.getChildren().size()==files.length){
Task<FtpMonitorData> monitorFTP = new Task<>() {
@Override
protected FtpMonitorData call() throws Exception {
FTPUpload ftp = new FTPUpload(config.getFTPHost(), toInt(config.getFTPPort()), config.getFTPUser(), config.getFTPPass(), config.getFTPPath());
ftp.UploadFile(new FTPUploadEvent() {
@Override
public void onUploadSuccess(String file) {
Logger.info("Upload Success: {}" ,file);
String filename = GetFileName(file);
UploadProgress up = progressmap.get(filename);
if (up!=null){
updateValue(new FtpMonitorData("Success", filename, up, 1, 1));
// Platform.runLater(()->{
// up.SetStatus("Success");
// up.SetProgress(1,1);
// });
}
}
@Override
public void onUploadFailed(String file) {
Logger.info("Upload Failed: {}",file);
String filename = GetFileName(file);
UploadProgress up = progressmap.get(filename);
if (up!=null){
updateValue(new FtpMonitorData("Failed", filename, up, 1, 0));
// Platform.runLater(()->{
// up.SetStatus("Failed");
// up.SetProgress(0,1);
// });
}
}
@Override
public void onUploadProgress(String file, long bytes, long total) {
String filename = GetFileName(file);
UploadProgress up = progressmap.get(filename);
if (up!=null){
updateValue(new FtpMonitorData("Uploading", filename, up, total, bytes));
// Platform.runLater(()->up.SetProgress(bytes, total));
}
}
@Override
public void onUploadStarted(String file) {
Logger.info("Upload Started: {}",file);
String filename = GetFileName(file);
UploadProgress up = progressmap.get(filename);
if (up!=null){
updateValue(new FtpMonitorData("Started", filename, up, 0, 0));
// Platform.runLater(()->{
// up.SetStatus("Started");
// up.SetProgress(0,0);
// });
}
}
@Override
public void uploadLog(String msg) {
Logger.info("Upload Log: {}",msg);
}
@Override
public void onUploadFinished(int total, int success, int failed, String[] files) {
Logger.info("Upload Finished, Total: {}, Success: {}, Failed: {}", total, success, failed);
Platform.runLater(()->{
if (!audioPlayer.getCurrentFile().equals(audio_upload_berhasil)) {
audioPlayer.StopCurrentPlayback();
Wait(200);
}
audioPlayer.PlayFile(audio_upload_berhasil, ps);
Alert Alert = new Alert(AlertType.INFORMATION);
Alert.setTitle("Upload Finished");
Alert.setHeaderText("Upload Finished");
Alert.setContentText("Total: "+total+"\nSuccess: "+success+"\nFailed: "+failed);
Alert.showAndWait();
});
}
}, files);
// Task selesai, return null
return null;
}
};
monitorFTP.valueProperty().addListener(
(observable1, oldValue, newValue) -> {
if (newValue!=null){
if (newValue.progress!=null){
newValue.progress.SetStatus(newValue.information);
newValue.progress.SetProgress(newValue.current, newValue.total);
}
}
}
);
new Thread(monitorFTP).start();
}
};
progressanchor.getChildren().addListener(progressanchorlistener);
}
private void InsertSQL(PhotoReviewClass prc){
Sqlite sql = new Sqlite();
sql.Insert(prc);

View File

@@ -14,10 +14,9 @@ import static Config.SomeCodes.IsInsideRect;
public class Detectors {
public static CascadeClassifier frontalfaceDetector;
private static CascadeClassifier eyeDetector;
private static CascadeClassifier profilefaceDetector;
private static CascadeClassifier palmDetector;
private static CascadeClassifier fistDetector;
//private static CascadeClassifier palmDetector;
//private static CascadeClassifier fistDetector;
private static double scaleFactor = 1.1;
private final static int minNeighbors = 3;
@@ -37,43 +36,43 @@ public class Detectors {
LoadProfileFaceDetector();
LoadFistDetector();
LoadRightPalmDetector();
//LoadFistDetector();
//LoadRightPalmDetector();
}
private static void LoadFistDetector(){
String filename = SomeCodes.ExtractResource("/fist.xml");
if (filename!=null) {
Logger.info("Fist Detector file : " + filename);
if (fistDetector ==null) {
try{
// private static void LoadFistDetector(){
// String filename = SomeCodes.ExtractResource("/fist.xml");
// if (filename!=null) {
// Logger.info("Fist Detector file : " + filename);
// if (fistDetector ==null) {
// try{
//
// fistDetector = new CascadeClassifier(filename);
// Logger.info("FistDetector loaded");
// } catch (Exception e){
// Logger.error("Exception on loading FistDetector : " + e.getMessage());
// }
//
// } else Logger.info("FistDetector already loaded");
// } else Logger.error("Unable to extract fist detector file");
// }
fistDetector = new CascadeClassifier(filename);
Logger.info("FistDetector loaded");
} catch (Exception e){
Logger.error("Exception on loading FistDetector : " + e.getMessage());
}
} else Logger.info("FistDetector already loaded");
} else Logger.error("Unable to extract fist detector file");
}
private static void LoadRightPalmDetector(){
String filename = SomeCodes.ExtractResource("/rpalm.xml");
if (filename!=null) {
Logger.info("Right Palm Detector file : " + filename);
if (palmDetector ==null) {
try{
palmDetector = new CascadeClassifier(filename);
Logger.info("RightPalmDetector loaded");
} catch (Exception e){
Logger.error("Exception on loading RightPalmDetector : " + e.getMessage());
}
} else Logger.info("RightPalmDetector already loaded");
} else Logger.error("Unable to extract right palm detector file");
}
// private static void LoadRightPalmDetector(){
// String filename = SomeCodes.ExtractResource("/rpalm.xml");
// if (filename!=null) {
// Logger.info("Right Palm Detector file : " + filename);
// if (palmDetector ==null) {
// try{
//
// palmDetector = new CascadeClassifier(filename);
// Logger.info("RightPalmDetector loaded");
// } catch (Exception e){
// Logger.error("Exception on loading RightPalmDetector : " + e.getMessage());
// }
//
// } else Logger.info("RightPalmDetector already loaded");
// } else Logger.error("Unable to extract right palm detector file");
// }
private static void LoadFrontalFaceDetector(){
String filename = SomeCodes.ExtractResource("/haarcascade_frontalface_alt.xml");
@@ -129,15 +128,15 @@ public class Detectors {
public static boolean HavePalm(UMat graymat){
RectVector palms = Detect(graymat, palmDetector);
return palms!=null && palms.size()>0;
}
public static boolean HaveFist(UMat graymat){
RectVector fists = Detect(graymat, fistDetector);
return fists!=null && fists.size()>0;
}
// public static boolean HavePalm(UMat graymat){
// RectVector palms = Detect(graymat, palmDetector);
// return palms!=null && palms.size()>0;
// }
//
// public static boolean HaveFist(UMat graymat){
// RectVector fists = Detect(graymat, fistDetector);
// return fists!=null && fists.size()>0;
// }
/**

View File

@@ -30,12 +30,11 @@ public class MainApplication extends Application {
if (UserID.equals("14022025")){
Logger.info("Secure Dongle UserID valid");
FXMLLoader fxmlLoader = new FXMLLoader(MainApplication.class.getResource("main-view.fxml"));
Screen screen = Screen.getPrimary();
Rectangle2D screenbound = screen.getVisualBounds();
Scene scene = new Scene(fxmlLoader.load(), screenbound.getWidth(), screenbound.getHeight());
stage.setTitle("MultiCam Capture App for ERHA 18022025-032");
stage.setTitle("MultiCam Capture App for ERHA 11032025-006");
stage.setScene(scene);
stage.setResizable(true);
stage.setMaximized(true);

View File

@@ -15,6 +15,7 @@ import org.tinylog.Logger;
import java.io.File;
import java.nio.file.Path;
import static Config.SomeCodes.ShowAlert;
import static Config.SomeCodes.config;
public class PhotoRow {
@@ -47,18 +48,22 @@ public class PhotoRow {
imgview.setStyle(borderstyle);
imgview.setOnMouseClicked(e->{
if (e.getClickCount()>=2){
//System.out.println("Photo path: "+photopath);
File ff = new File(photopath);
String hires = Path.of(config.getPhotoDirectory(), ff.getName()).toString();
// System.out.println("Config exists : "+(config!=null));
// System.out.println("Photo directory: "+config.getPhotoDirectory());
// System.out.println("Full quality directory: "+config.getFullQualityDirectory());
// System.out.println("Full Quality Crop directory: "+config.getFullQualityCropDirectory());
// System.out.println("Reduced quality directory: "+config.getCompressedDirectory());
// System.out.println("Reduced quality crop directory: "+config.getCompressedCropDirectory());
//String hires = Path.of(config.getPhotoDirectory(), ff.getName()).toString();
String hires = Path.of(config.getFullQualityDirectory(), ff.getName()).toString();
//System.out.println("Hires: "+hires);
File hiresfile = new File(hires);
if (hiresfile.isFile()){
System.out.println("Opening file: "+hires);
SomeCodes.OpenPictureInDefaultViewer(hires);
} else {
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Error");
alert.setHeaderText("File not found");
alert.setContentText("File not found: "+hires);
alert.showAndWait();
}
} else ShowAlert(Alert.AlertType.ERROR, "Error", "File not found", "File not found: "+hires);
e.consume();
}
});

View File

@@ -6,6 +6,7 @@ import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextField;
import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser;
import lombok.val;
import org.bytedeco.javacv.VideoInputFrameGrabber;
@@ -13,21 +14,9 @@ import org.tinylog.Logger;
import java.io.File;
import static Config.SomeCodes.ValidString;
import static Config.SomeCodes.config;
import static Config.SomeCodes.*;
public class SettingView {
@FXML
private TextField AudioPhase1;
@FXML
private TextField AudioPhase2;
@FXML
private TextField AudioPhase3;
@FXML
private TextField AudioPhase4;
@FXML
private TextField AudioPhase5;
@FXML
private ComboBox<String> CameraLeft90;
@FXML
@@ -50,6 +39,11 @@ public class SettingView {
@FXML
private TextField FTPPath;
@FXML
private TextField PhotoDirectoryPath;
final FileChooser jfc = new FileChooser();
String[] cameranames = null;
@@ -63,6 +57,17 @@ public class SettingView {
@FXML
private TextField cascadeMaxSize;
@FXML
private void ChangePhotoDirectoryPath(){
DirectoryChooser dc = new DirectoryChooser();
dc.setTitle("Select Directory");
String path = dc.showDialog(null).getAbsolutePath();
config.SetPhotoDirectory(path);
config.Save();
PhotoDirectoryPath.setText(path);
}
@FXML
private void CascadeSettingApply(){
String minsize = cascadeMinSize.getText();
@@ -87,11 +92,8 @@ public class SettingView {
Detectors.setFaceMaxSize(max);
Detectors.setFaceMinSize(min);
Detectors.setScaleFactor(scale);
val alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("Cascade Setting");
alert.setHeaderText("Cascade Setting Saved");
alert.setContentText("Cascade Setting Saved Successfully");
alert.showAndWait();
ShowAlert(Alert.AlertType.INFORMATION, "Cascade Setting", "Cascade Setting Saved", "Cascade Setting Saved Successfully");
} else show_cascade_alert("Max Size must be greater than Min Size");
} else show_cascade_alert("Min Size must be greater than 0");
} else show_cascade_alert("Scale Factor must be greater than 1.0");
@@ -105,11 +107,7 @@ public class SettingView {
}
private void show_cascade_alert(String content){
val alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Cascade Setting Error");
alert.setHeaderText("Cascade Setting Error");
alert.setContentText(content);
alert.showAndWait();
ShowAlert(Alert.AlertType.ERROR, "Cascade Setting Error", "Cascade Setting Error", content);
}
@FXML
@@ -129,11 +127,6 @@ public class SettingView {
Platform.runLater(()->{
AudioPhase1.setText(config.getAudioPhase1());
AudioPhase2.setText(config.getAudioPhase2());
AudioPhase3.setText(config.getAudioPhase3());
AudioPhase4.setText(config.getAudioPhase4());
AudioPhase5.setText(config.getAudioPhase5());
CameraLeft90.getItems().clear();
CameraLeft45.getItems().clear();
@@ -168,6 +161,8 @@ public class SettingView {
FTPPass.setText(config.getFTPPass());
FTPPath.setText(config.getFTPPath());
PhotoDirectoryPath.setText(config.getPhotoDirectory());
cascadeScaleFactor.setText(String.valueOf(config.getCascadeScaleFactor()));
cascadeMinSize.setText(String.valueOf(config.getCascadeMinSize()));
cascadeMaxSize.setText(String.valueOf(config.getCascadeMaxSize()));
@@ -178,52 +173,6 @@ public class SettingView {
config.Save();
}
@FXML
private void BrowseAudioPhase1(){
File file = jfc.showOpenDialog(null);
if (file!=null){
config.SetAudioPhase1(file.getAbsolutePath());
AudioPhase1.setText(config.getAudioPhase1());
}
}
@FXML
private void BrowseAudioPhase2(){
File file = jfc.showOpenDialog(null);
if (file!=null){
config.SetAudioPhase2(file.getAbsolutePath());
AudioPhase2.setText(config.getAudioPhase2());
}
}
@FXML
private void BrowseAudioPhase3(){
File file = jfc.showOpenDialog(null);
if (file!=null){
config.SetAudioPhase3(file.getAbsolutePath());
AudioPhase3.setText(config.getAudioPhase3());
}
}
@FXML
private void BrowseAudioPhase4(){
File file = jfc.showOpenDialog(null);
if (file!=null){
config.SetAudioPhase4(file.getAbsolutePath());
AudioPhase4.setText(config.getAudioPhase4());
}
}
@FXML
private void BrowseAudioPhase5(){
File file = jfc.showOpenDialog(null);
if (file!=null){
config.SetAudioPhase5(file.getAbsolutePath());
AudioPhase5.setText(config.getAudioPhase5());
}
}
@FXML
private void ApplyCameraLeft90(){
config.SetCameraLeft90(CameraLeft90.getValue());
@@ -261,18 +210,8 @@ public class SettingView {
config.SetFTPPass(FTPPass.getText());
config.SetFTPPath(FTPPath.getText());
val alert = new Alert(Alert.AlertType.INFORMATION);
alert.setTitle("FTP Configuration");
alert.setHeaderText("FTP Configuration Saved");
alert.setContentText("FTP Configuration Saved Successfully");
alert.showAndWait();
} else {
val alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("FTP Error");
alert.setHeaderText("FTP Configuration Error");
alert.setContentText("FTP Configuration is incorrect, please check your FTP Configuration");
alert.showAndWait();
}
ShowAlert(Alert.AlertType.INFORMATION, "FTP Configuration", "FTP Configuration Saved", "FTP Configuration Saved Successfully");
} else ShowAlert(Alert.AlertType.ERROR, "FTP Error", "FTP Configuration Error", "FTP Configuration is incorrect, please check your FTP Configuration");
}
}