diff --git a/out/artifacts/ErhaCam_jar/ErhaCam.jar b/out/artifacts/ErhaCam_jar/ErhaCam.jar index c58d4c9..3b0e2bf 100644 Binary files a/out/artifacts/ErhaCam_jar/ErhaCam.jar and b/out/artifacts/ErhaCam_jar/ErhaCam.jar differ diff --git a/src/main/java/Config/ConfigFile.java b/src/main/java/Config/ConfigFile.java index 3b41d61..8e16088 100644 --- a/src/main/java/Config/ConfigFile.java +++ b/src/main/java/Config/ConfigFile.java @@ -1,6 +1,6 @@ package Config; -import id.co.gtc.erhacam.Detectors; +import id.co.gtc.erhacam.MainApplication; import lombok.Getter; import org.tinylog.Logger; @@ -856,9 +856,20 @@ public class ConfigFile { cascadeMinSize = toInt(prop.getProperty("cascadeMinSize")); cascadeMaxSize = toInt(prop.getProperty("cascadeMaxSize")); - Detectors.setFaceMaxSize(cascadeMaxSize); - Detectors.setFaceMinSize(cascadeMinSize); - Detectors.setScaleFactor(cascadeScaleFactor); + if (MainApplication.detectorsList!=null){ + MainApplication.detectorsList.forEach((i, d) -> { + if (d != null) { + d.setFaceMaxSize(cascadeMaxSize); + d.setFaceMinSize(cascadeMinSize); + d.setScaleFactor(cascadeScaleFactor); + } + }); + } + + +// Detectors.setFaceMaxSize(cascadeMaxSize); +// Detectors.setFaceMinSize(cascadeMinSize); +// Detectors.setScaleFactor(cascadeScaleFactor); MirrorCamera = toBoolean(prop.getProperty("MirrorCamera")); FlipCamera = toBoolean(prop.getProperty("FlipCamera")); @@ -944,9 +955,16 @@ public class ConfigFile { cascadeMinNeighbors = 3; cascadeMinSize = 250; cascadeMaxSize = 360; - Detectors.setFaceMaxSize(cascadeMaxSize); - Detectors.setFaceMinSize(cascadeMinSize); - Detectors.setScaleFactor(cascadeScaleFactor); + if (MainApplication.detectorsList!= null) MainApplication.detectorsList.forEach((i, d) -> { + if (d != null) { + d.setFaceMaxSize(cascadeMaxSize); + d.setFaceMinSize(cascadeMinSize); + d.setScaleFactor(cascadeScaleFactor); + } + }); +// Detectors.setFaceMaxSize(cascadeMaxSize); +// Detectors.setFaceMinSize(cascadeMinSize); +// Detectors.setScaleFactor(cascadeScaleFactor); MirrorCamera = false; FlipCamera = false; SharpnessThreshold = 300.0; diff --git a/src/main/java/ErhaAPI/BarcodeHttpResult.java b/src/main/java/ErhaAPI/BarcodeHttpResult.java new file mode 100644 index 0000000..b696c08 --- /dev/null +++ b/src/main/java/ErhaAPI/BarcodeHttpResult.java @@ -0,0 +1,10 @@ +package ErhaAPI; + +import lombok.Data; + +@Data +public class BarcodeHttpResult { + private int statusCode; + private String body; + private BarcodeResult result; +} diff --git a/src/main/java/ErhaAPI/BarcodeResullt.java b/src/main/java/ErhaAPI/BarcodeResult.java similarity index 96% rename from src/main/java/ErhaAPI/BarcodeResullt.java rename to src/main/java/ErhaAPI/BarcodeResult.java index 6380e2a..5476f71 100644 --- a/src/main/java/ErhaAPI/BarcodeResullt.java +++ b/src/main/java/ErhaAPI/BarcodeResult.java @@ -1,7 +1,7 @@ package ErhaAPI; -public class BarcodeResullt { +public class BarcodeResult { public int currentPage; public int limit; public int totalPages; diff --git a/src/main/java/ErhaAPI/ErhaAPI.java b/src/main/java/ErhaAPI/ErhaAPI.java index fd87927..fbcaa2c 100644 --- a/src/main/java/ErhaAPI/ErhaAPI.java +++ b/src/main/java/ErhaAPI/ErhaAPI.java @@ -3,6 +3,7 @@ package ErhaAPI; import Config.SomeCodes; import com.google.gson.Gson; import lombok.Getter; +import lombok.NonNull; import org.tinylog.Logger; @@ -68,12 +69,14 @@ public class ErhaAPI { } } + /** * Validate Barcode data * @param Barcode Barcode to verify - * @return BarcodeResullt object if success, or null if failed + * @return BarcodeHttpResult object */ - public BarcodeResullt Validate_Barcode(String Barcode, boolean printdebug){ + public @NonNull BarcodeHttpResult Validate_Barcode(String Barcode, boolean printdebug){ + BarcodeHttpResult bhr = new BarcodeHttpResult(); if (ValidBarCode(Barcode)){ try (HttpClient client = HttpClient.newHttpClient()) { @@ -84,6 +87,11 @@ public class ErhaAPI { .GET() .build(); HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + + + bhr.setStatusCode(response.statusCode()); + bhr.setBody(response.body()); + if (response.statusCode()==200){ String body = response.body(); if (printdebug){ @@ -91,7 +99,8 @@ public class ErhaAPI { System.out.println("Validate_Barcode HTTP body : "); System.out.println(body); } - return gson.fromJson(body, BarcodeResullt.class); + BarcodeResult brr = gson.fromJson(body, BarcodeResult.class); + bhr.setResult(brr); } else { Logger.error("Validate_Barcode failed, status code : " , response.statusCode()); } @@ -103,7 +112,7 @@ public class ErhaAPI { } } - return null; + return bhr; } @@ -113,9 +122,10 @@ public class ErhaAPI { * Upload File * @param patientID Patient ID * @param filename File to upload - * @return null if failed, or response body if success + * @return UploadHttpResult object */ - public UploadResult Upload_File(String patientID, String filename, boolean printdebug) { + public @NonNull UploadHttpResult Upload_File(String patientID, String filename, boolean printdebug) { + UploadHttpResult uhr = new UploadHttpResult(); if (ValidMedicalRecordId(patientID)){ int medical_record_detail_id = toInt(patientID); if (ValidFile(filename)){ @@ -159,6 +169,8 @@ public class ErhaAPI { // Send request HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + uhr.setStatusCode(response.statusCode()); + uhr.setBody(response.body()); if (printdebug){ System.out.println("Upload_File status code : " + response.statusCode()); System.out.println("Upload_File HTTP body : "); @@ -167,7 +179,8 @@ public class ErhaAPI { if (response.statusCode()==200){ - return gson.fromJson(response.body(), UploadResult.class); + UploadResult ur = gson.fromJson(response.body(), UploadResult.class); + uhr.setResult(ur); } else { Logger.error("Upload_File file ",filename," failed, status code : " , response.statusCode()); @@ -179,7 +192,7 @@ public class ErhaAPI { } } } - return null; + return uhr; } diff --git a/src/main/java/ErhaAPI/UploadHttpResult.java b/src/main/java/ErhaAPI/UploadHttpResult.java new file mode 100644 index 0000000..8274c8b --- /dev/null +++ b/src/main/java/ErhaAPI/UploadHttpResult.java @@ -0,0 +1,10 @@ +package ErhaAPI; + +import lombok.Data; + +@Data +public class UploadHttpResult { + int statusCode; + String body; + UploadResult result; +} diff --git a/src/main/java/id/co/gtc/erhacam/Cameradetail.java b/src/main/java/id/co/gtc/erhacam/Cameradetail.java index e7feca5..67d6145 100644 --- a/src/main/java/id/co/gtc/erhacam/Cameradetail.java +++ b/src/main/java/id/co/gtc/erhacam/Cameradetail.java @@ -44,7 +44,6 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import static Config.SomeCodes.*; -import static id.co.gtc.erhacam.Detectors.*; import static org.bytedeco.opencv.global.opencv_imgproc.*; @SuppressWarnings({"unused"}) @@ -157,6 +156,8 @@ public class Cameradetail { private boolean use_qr = false; private boolean use_face = false; + private @Getter Detectors detector; + private void setSliderValue(Slider sld, CameraProperty prop, double value){ if (sld!=null){ @@ -239,6 +240,8 @@ public class Cameradetail { raise_log("Exposure for "+getCameraTitle()+" changed to "+newVal); }); + detector = new Detectors(); + } @FXML @@ -903,7 +906,7 @@ public class Cameradetail { int _face_width = 0; int _face_height = 0; - List frontalfaces = HaveFrontalFace(GrayMat.clone()); + List frontalfaces = detector.HaveFrontalFace(GrayMat.clone()); if (!frontalfaces.isEmpty()){ for(DetectorResult rect : frontalfaces){ if (rect.haveFace() ){ @@ -921,7 +924,7 @@ public class Cameradetail { } else { // gak punya frontal face // coba cek punya profile left face 45 gak - List Left45Faces = HaveLeft45Face(GrayMat.clone()); + List Left45Faces = detector.HaveLeft45Face(GrayMat.clone()); if (!Left45Faces.isEmpty()){ for(DetectorResult rect : Left45Faces){ if (rect.haveFace()){ diff --git a/src/main/java/id/co/gtc/erhacam/CaptureView.java b/src/main/java/id/co/gtc/erhacam/CaptureView.java index b4bf73f..63bfbe4 100644 --- a/src/main/java/id/co/gtc/erhacam/CaptureView.java +++ b/src/main/java/id/co/gtc/erhacam/CaptureView.java @@ -7,10 +7,10 @@ import Config.CameraConfigEnum; import Database.PhotoReviewClass; import Database.Sqlite; import ErhaAPI.ErhaAPI; -import ErhaAPI.BarcodeResullt; +import ErhaAPI.BarcodeHttpResult; +import ErhaAPI.UploadHttpResult; import ErhaAPI.PhotoResult; import ErhaAPI.PatientRecord; -import ErhaAPI.UploadResult; import javafx.animation.KeyFrame; import javafx.animation.Timeline; @@ -520,14 +520,11 @@ public class CaptureView { int totalfiles = files.length; int counter = 0; for (String ff : files) { - UploadResult ur = erhaAPI.Upload_File(prefix, ff,true); - if (ur != null) { - if (ur.message.startsWith("Record has been created")) { - counter++; - updateMessage("Upload success for " + ff); - } else updateMessage("Upload failed for " + ff+", Message : "+ur.message); - } else updateMessage("Upload failed for " + ff+" because UploadResult is null"); - + UploadHttpResult ur = erhaAPI.Upload_File(prefix, ff,true); + if (ur.getResult().message.startsWith("Record has been created")) { + counter++; + updateMessage("Upload success for " + ff); + } else updateMessage("Upload failed for " + ff+", Message : "+ur.getResult().message); } if (counter == totalfiles) { super.succeeded(); @@ -931,11 +928,11 @@ public class CaptureView { Task checkpatientID = new Task<>() { @Override protected PatientRecord call() throws Exception { - BarcodeResullt br = erhaAPI.Validate_Barcode(finalbarCode,true); - if (br!=null){ - if (br.message.startsWith("Records found")){ - if (br.data!=null && br.data.length>0){ - PatientRecord pr = br.data[0]; + BarcodeHttpResult br = erhaAPI.Validate_Barcode(finalbarCode,true); + if (br.getStatusCode()==200){ + if (br.getResult().message.startsWith("Records found")){ + if (br.getResult().data!=null && br.getResult().data.length>0){ + PatientRecord pr = br.getResult().data[0]; if (!pr.medical_record_detail_id.isBlank()){ if (!pr.name.isBlank()){ super.succeeded(); @@ -957,10 +954,12 @@ public class CaptureView { throw new Exception("Data dengan barcode "+finalbarCode+" tidak ditemukan di server"); } } else { - Logger.error("BarcodeResullt with barcode ",finalbarCode," is null"); - throw new Exception("BarcodeResult dengan barcode "+finalbarCode+" menghasilkan null"); + Logger.error("HTTP code ", br.getStatusCode(), " for barcode ", finalbarCode); + throw new Exception("HTTP code "+br.getStatusCode()+" untuk barcode "+finalbarCode); + } } + }; checkpatientID.setOnSucceeded(event -> { @@ -1102,7 +1101,8 @@ public class CaptureView { }; image.setCameraStatus("Camera Starting"); if (image.StartLiveView(lce, title, use_qr_detector, use_face_detector)){ - //Runtime.getRuntime().addShutdownHook(new Thread(image::Release)); + MainApplication.detectorsList.put(devicenumber, image.getDetector()); + Logger.info("Camera "+cameraname+" started with device number "+devicenumber); } else image.setCameraStatus("Unable to Set Grabber"); } else image.setCameraStatus("Camera not found, please check setting"); } diff --git a/src/main/java/id/co/gtc/erhacam/Detectors.java b/src/main/java/id/co/gtc/erhacam/Detectors.java index bb4666b..446a194 100644 --- a/src/main/java/id/co/gtc/erhacam/Detectors.java +++ b/src/main/java/id/co/gtc/erhacam/Detectors.java @@ -20,16 +20,23 @@ public class Detectors { private static Size FaceminSize; private static Size FacemaxSize; - public static void LoadAllDetectors(){ - + public Detectors(){ LoadFrontalFaceDetector(); LoadEyeDetector(); LoadProfileFaceDetector(); - } - private static void LoadFrontalFaceDetector(){ +// public static void LoadAllDetectors(){ +// +// LoadFrontalFaceDetector(); +// LoadEyeDetector(); +// +// LoadProfileFaceDetector(); +// +// } + + private void LoadFrontalFaceDetector(){ // revisi 09/05/2025, dari filename = SomeCodes.ExtractResource("/haarcascade_frontalface_default.xml"); String filename = SomeCodes.ExtractResource("/haarcascade_frontalface_alt.xml"); if (filename!=null) { @@ -46,7 +53,7 @@ public class Detectors { } else Logger.error("Unable to extract face detector file"); } - private static void LoadProfileFaceDetector(){ + private void LoadProfileFaceDetector(){ String filename = SomeCodes.ExtractResource("/haarcascade_profileface.xml"); if (filename!=null) { Logger.info("Profile Face Detector file : " + filename); @@ -62,7 +69,7 @@ public class Detectors { } else Logger.error("Unable to extract profile face detector file"); } - private static void LoadEyeDetector(){ + private void LoadEyeDetector(){ String filename = SomeCodes.ExtractResource("/haarcascade_eye.xml"); if (filename!=null) { Logger.info("Eye Detector file : " + filename); @@ -84,7 +91,7 @@ public class Detectors { * @param graymat Mat in Gray Scale * @return List of Rect if face detected, otherwise empty list */ - public static @NonNull List HaveFrontalFace(Mat graymat){ + public @NonNull List HaveFrontalFace(Mat graymat){ List result = new ArrayList<>(); RectVector faces = DetectFrontalFace(graymat); if (faces!=null && faces.size()>0){ @@ -106,7 +113,7 @@ public class Detectors { return result; } - public static @NonNull List HaveLeft45Face(Mat graymat){ + public @NonNull List HaveLeft45Face(Mat graymat){ List result = new ArrayList<>(); RectVector faces = DetectProfileFace(graymat); if (faces!=null && faces.size()>0){ @@ -129,11 +136,11 @@ public class Detectors { - public static void setScaleFactor(double value){ + public void setScaleFactor(double value){ if (scaleFactor!=value) scaleFactor = value; } - public static void setFaceMinSize(int value){ + public void setFaceMinSize(int value){ if (FaceminSize!=null){ if (FaceminSize.width()!=value || FaceminSize.height()!=value) { FaceminSize = new Size(value, value); @@ -146,7 +153,7 @@ public class Detectors { } - public static void setFaceMaxSize(int value){ + public void setFaceMaxSize(int value){ if (FacemaxSize!=null){ if (FacemaxSize.width()!=value || FacemaxSize.height()!=value) { FacemaxSize = new Size(value, value); @@ -160,7 +167,7 @@ public class Detectors { } - public static RectVector DetectProfileFace(Mat graymat){ + public RectVector DetectProfileFace(Mat graymat){ return Detect(graymat, profilefaceDetector, scaleFactor, minNeighbors, flags, FaceminSize, FacemaxSize); } @@ -169,7 +176,7 @@ public class Detectors { * @param graymat Mat in Gray Scale * @return RectVector if face detected, otherwise null */ - public static RectVector DetectFrontalFace(Mat graymat){ + public RectVector DetectFrontalFace(Mat graymat){ return Detect(graymat, frontalfaceDetector, scaleFactor, minNeighbors, flags, FaceminSize, FacemaxSize); } @@ -179,7 +186,7 @@ public class Detectors { * @param graymat Mat in Gray Scale * @return RectVector if eye detected, otherwise null */ - public static RectVector DetectEye(Mat graymat, int facewidth){ + public RectVector DetectEye(Mat graymat, int facewidth){ //return Detect(graymat, eyeDetector); int minwidth = (int)(facewidth*0.2); int maxwidth = (int)(facewidth*0.4); @@ -189,7 +196,7 @@ public class Detectors { } @SuppressWarnings("SameParameterValue") - private static RectVector Detect(Mat graymat, CascadeClassifier detector, double scaleFactor, int minNeighbors, int flags, Size minSize, Size maxSize){ + private RectVector Detect(Mat graymat, CascadeClassifier detector, double scaleFactor, int minNeighbors, int flags, Size minSize, Size maxSize){ if (detector!=null && !detector.empty()){ if (graymat!=null && graymat.channels()==1 && !graymat.empty()){ if (minSize!=null && maxSize!=null){ diff --git a/src/main/java/id/co/gtc/erhacam/MainApplication.java b/src/main/java/id/co/gtc/erhacam/MainApplication.java index 885e119..77ea03e 100644 --- a/src/main/java/id/co/gtc/erhacam/MainApplication.java +++ b/src/main/java/id/co/gtc/erhacam/MainApplication.java @@ -15,6 +15,8 @@ import javafx.stage.Stage; import org.tinylog.Logger; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; import static Config.SomeCodes.ShowAlert; import static Config.SomeCodes.config; @@ -22,8 +24,10 @@ import static Config.SomeCodes.config; public class MainApplication extends Application { - final String version = "01072025-PRODUCTION-1.0.1"; + final String version = "10072025-PRODUCTION-1.0.2"; PhotoCleaner photoCleaner; + public static Map detectorsList = new HashMap<>(); + @Override public void start(Stage stage) throws IOException { @@ -62,7 +66,8 @@ public class MainApplication extends Application { Logger.info("Application closed"); }); SomeCodes.LoadQRReader(); - Detectors.LoadAllDetectors(); + // buang, pindah ke Cameradetail + //Detectors.LoadAllDetectors(); stage.show(); diff --git a/src/main/java/id/co/gtc/erhacam/SettingView.java b/src/main/java/id/co/gtc/erhacam/SettingView.java index b9a651b..a440400 100644 --- a/src/main/java/id/co/gtc/erhacam/SettingView.java +++ b/src/main/java/id/co/gtc/erhacam/SettingView.java @@ -239,9 +239,20 @@ public class SettingView { config.setCascadeScaleFactor(scale); config.Save(); - Detectors.setFaceMaxSize(max); - Detectors.setFaceMinSize(min); - Detectors.setScaleFactor(scale); + if (MainApplication.detectorsList!=null){ + MainApplication.detectorsList.forEach((i,d)-> { + d.setFaceMaxSize(max); + d.setFaceMinSize(min); + d.setScaleFactor(scale); + }); + + } else { + Logger.error("MainApplication.detectorsList is null, unable to set cascade settings"); + } + +// Detectors.setFaceMaxSize(max); +// Detectors.setFaceMinSize(min); +// Detectors.setScaleFactor(scale); 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");