commit 18/08/2025

This commit is contained in:
2025-08-18 16:27:27 +07:00
parent d566e4bc4f
commit f7c74304f5
14 changed files with 195 additions and 113 deletions

View File

@@ -5,16 +5,14 @@ import javafx.animation.PauseTransition;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.*;
@@ -289,26 +287,37 @@ public class AutoCloseAlert {
double screenwidth = Screen.getPrimary().getBounds().getWidth();
double screenheight = Screen.getPrimary().getBounds().getHeight();
double height = screenheight/4;
double width = height * 21/9;
double height = screenheight/4.0;
double width = height * 21.0/9.0;
VBox root = new VBox(10);
root.setPadding(new Insets(12));
root.setPrefSize(width, height);
root.setAlignment(Pos.CENTER);
List<Node> children = new ArrayList<>();
if (ValidString(header)){
Label headerLabel = new Label(header);
headerLabel.setStyle("-fx-font-weight: bold; -fx-font-size: 28px;");
headerLabel.setWrapText(true);
headerLabel.setMinHeight(height*0.25);
children.add(headerLabel);
headerLabel.setMaxWidth(Double.MAX_VALUE);
headerLabel.prefWidthProperty().bind(root.widthProperty());
root.getChildren().add(headerLabel);
}
if (ValidString(content)){
Label contentLabel = new Label(content);
contentLabel.setWrapText(true);
contentLabel.setStyle("-fx-font-size: 24px;");
contentLabel.setMinHeight(height*0.75);
children.add(contentLabel);
contentLabel.setMaxWidth(Double.MAX_VALUE);
contentLabel.prefWidthProperty().bind(root.widthProperty());
VBox.setVgrow(contentLabel, Priority.ALWAYS);
contentLabel.setAlignment(Pos.TOP_CENTER);
root.getChildren().add(contentLabel);
}
VBox root = new VBox(10, children.toArray(new Node[0]));
root.setPrefSize(width, height);
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root);
alertStage.setScene(scene);

View File

@@ -905,8 +905,8 @@ public class Cameradetail {
boolean have_left_45_face = false;
int _face_width = 0;
int _face_height = 0;
List<DetectorResult> frontalfaces = detector.HaveFrontalFace(GrayMat.clone());
//System.out.println("camera "+title+ (frontalfaces.isEmpty() ? " no frontal face detected" : " found "+frontalfaces.size()+" frontal faces"));
if (!frontalfaces.isEmpty()){
for(DetectorResult rect : frontalfaces){
if (rect.haveFace() ){
@@ -925,6 +925,7 @@ public class Cameradetail {
// gak punya frontal face
// coba cek punya profile left face 45 gak
List<DetectorResult> Left45Faces = detector.HaveLeft45Face(GrayMat.clone());
//System.out.println("camera "+title+ (Left45Faces.isEmpty() ? " no left 45 face detected" : " found "+Left45Faces.size()+" left 45 faces"));
if (!Left45Faces.isEmpty()){
for(DetectorResult rect : Left45Faces){
if (rect.haveFace()){

View File

@@ -90,7 +90,7 @@ public class CaptureView {
private final AtomicBoolean isTakingPhoto = new AtomicBoolean(false);
private final ErhaAPI erhaAPI = new ErhaAPI(true);
private final ErhaAPI erhaAPI = new ErhaAPI(config.isProduction());
// for timeout 180 detik
private final int timeout = 180;
@@ -513,13 +513,14 @@ public class CaptureView {
String[] files = prc.compressedcrop();
if (files.length>0){
InsertSQL(prc);
erhaAPI.setProduction(config.isProduction());
Task<Void> uploadtask = new Task<>() {
@Override
protected Void call() {
int totalfiles = files.length;
int counter = 0;
for (String ff : files) {
UploadHttpResult ur = erhaAPI.Upload_File(prefix, ff,true);
if (ur.getResult().message.startsWith("Record has been created")) {
counter++;
@@ -928,6 +929,7 @@ public class CaptureView {
Task<PatientRecord> checkpatientID = new Task<>() {
@Override
protected PatientRecord call() throws Exception {
erhaAPI.setProduction(config.isProduction());
BarcodeHttpResult br = erhaAPI.Validate_Barcode(finalbarCode,true);
if (br.getStatusCode()==200){
if (br.getResult().message.startsWith("Records found")){
@@ -955,7 +957,7 @@ public class CaptureView {
}
} else {
Logger.error("HTTP code ", br.getStatusCode(), " for barcode ", finalbarCode);
throw new Exception("HTTP code "+br.getStatusCode()+" untuk barcode "+finalbarCode);
throw new Exception("Barcode "+finalbarCode+" failed, code= "+br.getStatusCode()+", message: "+br.getBody());
}
}
@@ -1101,6 +1103,9 @@ public class CaptureView {
};
image.setCameraStatus("Camera Starting");
if (image.StartLiveView(lce, title, use_qr_detector, use_face_detector)){
image.getDetector().setFaceMaxSize(config.getCascadeMaxSize());
image.getDetector().setFaceMinSize(config.getCascadeMinSize());
image.getDetector().setScaleFactor(config.getCascadeScaleFactor());
MainApplication.detectorsList.put(devicenumber, image.getDetector());
Logger.info("Camera "+cameraname+" started with device number "+devicenumber);
} else image.setCameraStatus("Unable to Set Grabber");

View File

@@ -10,15 +10,15 @@ import java.util.ArrayList;
import java.util.List;
public class Detectors {
public static CascadeClassifier frontalfaceDetector;
private static CascadeClassifier eyeDetector;
private static CascadeClassifier profilefaceDetector;
public CascadeClassifier frontalfaceDetector;
private CascadeClassifier eyeDetector;
private CascadeClassifier profilefaceDetector;
private static double scaleFactor = 1.2; // revisi 09/05/2025, dari nilai 1.05
private final static int minNeighbors = 5; // revisi 09/05/2025, dari nilai 3
private final static int flags = 0;
private static Size FaceminSize;
private static Size FacemaxSize;
private double scaleFactor = 1.05; // revisi 09/05/2025, dari nilai 1.05
private final int minNeighbors = 3; // revisi 09/05/2025, dari nilai 3
private final int flags = 0;
private Size FaceminSize;
private Size FacemaxSize;
public Detectors(){
LoadFrontalFaceDetector();
@@ -27,62 +27,38 @@ public class Detectors {
LoadProfileFaceDetector();
}
// 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) {
Logger.info("Face Detector file : " + filename);
if (frontalfaceDetector==null) {
try{
frontalfaceDetector = new CascadeClassifier(filename);
Logger.info("FaceDetector loaded");
} catch (Exception e){
Logger.error("Exception on loading FaceDetector : " + e.getMessage());
}
} else Logger.info("FaceDetector already loaded");
try{
frontalfaceDetector = new CascadeClassifier(filename);
} catch (Exception e){
Logger.error("Exception on loading FaceDetector : " + e.getMessage());
}
} else Logger.error("Unable to extract face detector file");
}
private void LoadProfileFaceDetector(){
String filename = SomeCodes.ExtractResource("/haarcascade_profileface.xml");
if (filename!=null) {
Logger.info("Profile Face Detector file : " + filename);
if (profilefaceDetector==null) {
try{
profilefaceDetector = new CascadeClassifier(filename);
Logger.info("ProfileFaceDetector loaded");
} catch (Exception e){
Logger.error("Exception on loading ProfileFaceDetector : " + e.getMessage());
}
} else Logger.info("ProfileFaceDetector already loaded");
try{
profilefaceDetector = new CascadeClassifier(filename);
} catch (Exception e){
Logger.error("Exception on loading ProfileFaceDetector : " + e.getMessage());
}
} else Logger.error("Unable to extract profile face detector file");
}
private void LoadEyeDetector(){
String filename = SomeCodes.ExtractResource("/haarcascade_eye.xml");
if (filename!=null) {
Logger.info("Eye Detector file : " + filename);
if (eyeDetector==null) {
try{
try{
eyeDetector = new CascadeClassifier(filename);
Logger.info("EyeDetector loaded");
} catch (Exception e){
Logger.error("Exception on loading EyeDetector : " + e.getMessage());
}
} else Logger.info("EyeDetector already loaded");
eyeDetector = new CascadeClassifier(filename);
} catch (Exception e){
Logger.error("Exception on loading EyeDetector : " + e.getMessage());
}
} else Logger.error("Unable to extract eye detector file");
}
@@ -93,14 +69,16 @@ public class Detectors {
*/
public @NonNull List<DetectorResult> HaveFrontalFace(Mat graymat){
List<DetectorResult> result = new ArrayList<>();
//System.out.println("Detecting frontal from "+ graymat.size().width() + "x" + graymat.size().height());
RectVector faces = DetectFrontalFace(graymat);
if (faces!=null && faces.size()>0){
//System.out.println("faces size = " + faces.size());
for(Rect face : faces.get()){
RectVector eyes = DetectEye(graymat, face.width());
DetectorResult dr = new DetectorResult();
dr.setFace(face);
if (eyes!=null && eyes.size()>=2){
//System.out.println("eyes size = " + eyes.size());
if (eyes.size()>=2){
for(Rect eye : eyes.get()){
if (SomeCodes.IsInsideRect(eye, face)) {
dr.AddEye(eye);
@@ -109,7 +87,7 @@ public class Detectors {
}
result.add(dr);
}
}
} //else System.out.println("faces size = 0");
return result;
}
@@ -122,7 +100,7 @@ public class Detectors {
RectVector eyes = DetectEye(graymat, face.width());
DetectorResult dr = new DetectorResult();
dr.setFace(face);
if (eyes!=null && eyes.size()>0){
if (eyes.size()>0){
for(Rect eye : eyes.get()){
if (SomeCodes.IsInsideRect(eye, face)) dr.AddEye(eye);
}
@@ -144,11 +122,11 @@ public class Detectors {
if (FaceminSize!=null){
if (FaceminSize.width()!=value || FaceminSize.height()!=value) {
FaceminSize = new Size(value, value);
//Logger.info("FaceMinSize changed to : " + FaceminSize.width());
Logger.info("FaceMinSize changed to : " + FaceminSize.width());
}
} else {
FaceminSize = new Size(value, value);
//Logger.info("FaceMinSize created with value : " + FaceminSize.width());
Logger.info("FaceMinSize created with value : " + FaceminSize.width());
}
}
@@ -157,11 +135,11 @@ public class Detectors {
if (FacemaxSize!=null){
if (FacemaxSize.width()!=value || FacemaxSize.height()!=value) {
FacemaxSize = new Size(value, value);
//Logger.info("FaceMaxSize changed to : " + FacemaxSize.width());
Logger.info("FaceMaxSize changed to : " + FacemaxSize.width());
}
} else {
FacemaxSize = new Size(value, value);
//Logger.info("FaceMaxSize created with value : " + FacemaxSize.width());
Logger.info("FaceMaxSize created with value : " + FacemaxSize.width());
}
}
@@ -192,6 +170,7 @@ public class Detectors {
int maxwidth = (int)(facewidth*0.4);
Size minsize = new Size(minwidth, minwidth);
Size maxsize = new Size(maxwidth, maxwidth);
//System.out.println("Detecting Eye with minsize = " + minsize.width() + "x" + minsize.height() + ", maxsize = " + maxsize.width() + "x" + maxsize.height());
return Detect(graymat, eyeDetector, scaleFactor, minNeighbors, flags, minsize, maxsize);
}
@@ -211,13 +190,13 @@ public class Detectors {
} catch (Exception e) {
System.out.println("Detectors Detect Error, Message : " + e.getMessage());
}
}
} else System.out.println("graymat is smaller than minSize");
}
}
}
} else System.out.println("minSize is larger than maxSize");
} else System.out.println("minSize or maxSize is null");
} else System.out.println("graymat is null, not 1 channel, or empty");
}
} else System.out.println("detector empty");
return null;
}

View File

@@ -24,7 +24,7 @@ import static Config.SomeCodes.config;
public class MainApplication extends Application {
final String version = "10072025-PRODUCTION-1.0.3";
final String version = "18082025-PRODUCTION-1.0.6";
PhotoCleaner photoCleaner;
public static Map<Integer, Detectors> detectorsList = new HashMap<>();
@@ -75,6 +75,7 @@ public class MainApplication extends Application {
Logger.info("Application started");
System.out.println("Application version : " + version+" started");
System.out.println("Using "+(config.isProduction()?"Production":"Staging")+" API URL ");
sd.setEvent(new SecureDongleEvent() {
@Override
public void onDongleMissing() {

View File

@@ -3,10 +3,7 @@ package id.co.gtc.erhacam;
import FTP.FTPCheck;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextField;
import javafx.scene.control.*;
import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser;
import org.bytedeco.javacv.VideoInputFrameGrabber;
@@ -94,6 +91,27 @@ public class SettingView {
@FXML
private TextField Cam5RightCrop;
@FXML
private RadioButton apiStaging;
@FXML
private RadioButton apiProduction;
@FXML
public void changeAPIClick(){
if (apiStaging.isSelected()){
config.setAPI(false);
config.Save();
ShowAlert(Alert.AlertType.INFORMATION, "API Change", "API Change", "API Staging is selected, API will use Staging URL");
} else if (apiProduction.isSelected()){
config.setAPI(true);
config.Save();
ShowAlert(Alert.AlertType.INFORMATION, "API Change", "API Change", "API Production is selected, API will use Production URL");
} else {
ShowAlert(Alert.AlertType.ERROR, "API Change Error", "API Change Error", "Please select API Staging or API Production");
}
}
@FXML
private void ApplyCropClick(){
// Apply crop settings for each camera
@@ -340,6 +358,8 @@ public class SettingView {
MirrorCamera.setSelected(config.isMirrorCamera());
FlipCamera.setSelected(config.isFlipCamera());
apiStaging.setSelected(!config.isProduction());
apiProduction.setSelected(config.isProduction());
TextFieldSetText(Sharpness,String.valueOf(config.getSharpnessThreshold()));
TextFieldSetText(Cam1TopCrop,String.valueOf(config.getCam1TopCrop()));