commit 10/04/2025
This commit is contained in:
@@ -3,6 +3,8 @@ package BASS;
|
||||
import lombok.Getter;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import static Config.SomeCodes.Wait;
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class AudioPlayer {
|
||||
@@ -13,10 +15,7 @@ public class AudioPlayer {
|
||||
|
||||
public void WaitUntilFinished(){
|
||||
while(currentFileHandle!=0){
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
Wait(10);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +108,7 @@ public class AudioPlayer {
|
||||
if (bass.BASS_ChannelStart(filehandle)){
|
||||
currentFile = filename;
|
||||
currentFileHandle = filehandle;
|
||||
new Thread(()->{
|
||||
Thread pl = new Thread(() -> {
|
||||
if (playbackstatus!=null) playbackstatus.onPlaybackStarted(filename);
|
||||
boolean iscontinue = true;
|
||||
while(iscontinue){
|
||||
@@ -122,18 +121,17 @@ public class AudioPlayer {
|
||||
iscontinue = false;
|
||||
break;
|
||||
default : {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
iscontinue = false;
|
||||
}
|
||||
Wait(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (playbackstatus!=null) playbackstatus.onPlaybackFinished(filename);
|
||||
currentFile = "";
|
||||
currentFileHandle = 0;
|
||||
}).start();
|
||||
});
|
||||
pl.setDaemon(true);
|
||||
pl.start();
|
||||
|
||||
} else {
|
||||
Logger.error("AudioPlayer PlayFile failed, BASS_ChannelStart failed, error code: "+bass.BASS_ErrorGetCode());
|
||||
if (playbackstatus!=null) playbackstatus.onPlaybackFailure(filename);
|
||||
|
||||
@@ -7,6 +7,8 @@ import javafx.application.Platform;
|
||||
import javafx.embed.swing.SwingFXUtils;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.image.Image;
|
||||
import org.bytedeco.javacv.Java2DFrameConverter;
|
||||
import org.bytedeco.javacv.OpenCVFrameConverter;
|
||||
@@ -19,7 +21,6 @@ import org.bytedeco.opencv.opencv_core.Size;
|
||||
import org.bytedeco.opencv.opencv_core.UMat;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
@@ -512,9 +513,7 @@ public class SomeCodes {
|
||||
if (ROI.x()>=0){
|
||||
if (ROI.y()>=0){
|
||||
if (ROI.width()>0){
|
||||
if (ROI.height()>0){
|
||||
return true;
|
||||
}
|
||||
return ROI.height() > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -523,7 +522,7 @@ public class SomeCodes {
|
||||
}
|
||||
|
||||
public static void Print(String... x){
|
||||
if (x!=null && x.length>0){
|
||||
if (x != null){
|
||||
for(String xx : x){
|
||||
System.out.println(xx);
|
||||
}
|
||||
@@ -604,53 +603,72 @@ public class SomeCodes {
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetText(Object obj, String text){
|
||||
if (obj!=null && ValidString(text)){
|
||||
if (Platform.isFxApplicationThread()){
|
||||
if (obj instanceof Label lbl){
|
||||
if (text.equals(lbl.getText())) return;
|
||||
public static void LabelSetText(Label lbl, String text, String style){
|
||||
if (lbl!=null){
|
||||
if (text!=null){
|
||||
if (text.equals(lbl.getText())) return;
|
||||
if (Platform.isFxApplicationThread()){
|
||||
lbl.setText(text);
|
||||
} else if (obj instanceof TextArea ta){
|
||||
if (text.equals(ta.getText())) return;
|
||||
ta.setText(text);
|
||||
} else if (obj instanceof TextField tf){
|
||||
if (text.equals(tf.getText())) return;
|
||||
tf.setText(text);
|
||||
}
|
||||
} else{
|
||||
Platform.runLater(()->{
|
||||
if (obj instanceof Label lbl){
|
||||
if (text.equals(lbl.getText())) return;
|
||||
lbl.setText(text);
|
||||
} else if (obj instanceof TextArea ta){
|
||||
if (text.equals(ta.getText())) return;
|
||||
ta.setText(text);
|
||||
} else if (obj instanceof TextField tf){
|
||||
if (text.equals(tf.getText())) return;
|
||||
tf.setText(text);
|
||||
if (style!=null && !style.isBlank()){
|
||||
lbl.setStyle(style);
|
||||
}
|
||||
});
|
||||
} else{
|
||||
Platform.runLater(()-> {
|
||||
lbl.setText(text);
|
||||
if (style!=null && !style.isBlank()){
|
||||
lbl.setStyle(style);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void TextAreaSetText(TextArea ta, String text){
|
||||
if (ta!=null){
|
||||
if (text!=null){
|
||||
if (text.equals(ta.getText())) return;
|
||||
if (Platform.isFxApplicationThread()){
|
||||
ta.setText(text);
|
||||
} else{
|
||||
Platform.runLater(()-> ta.setText(text));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void TextFieldSetText(TextField tf, String text){
|
||||
if (tf!=null){
|
||||
if (text!=null){
|
||||
if (text.equals(tf.getText())) return;
|
||||
if (Platform.isFxApplicationThread()){
|
||||
tf.setText(text);
|
||||
} else{
|
||||
Platform.runLater(()-> tf.setText(text));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static void LabelVisible(Label label, boolean visible){
|
||||
if (label!=null){
|
||||
if (visible){
|
||||
if (Platform.isFxApplicationThread()){
|
||||
label.setVisible(true);
|
||||
} else{
|
||||
Platform.runLater(()->{
|
||||
label.setVisible(true);
|
||||
});
|
||||
Platform.runLater(()-> label.setVisible(true));
|
||||
}
|
||||
} else {
|
||||
if (Platform.isFxApplicationThread()){
|
||||
label.setVisible(false);
|
||||
} else{
|
||||
Platform.runLater(()->{
|
||||
label.setVisible(false);
|
||||
});
|
||||
Platform.runLater(()-> label.setVisible(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,8 @@ package SecureDongle;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static Config.SomeCodes.ToShort;
|
||||
import static Config.SomeCodes.Wait;
|
||||
|
||||
public class SecureDongle {
|
||||
|
||||
@@ -108,6 +106,7 @@ public class SecureDongle {
|
||||
* Close SecureDongle
|
||||
* @return true if success
|
||||
*/
|
||||
@SuppressWarnings("UnusedReturnValue")
|
||||
public boolean Close(){
|
||||
handle[0] = Handle;
|
||||
short result = SD.SecureDongle(LibSecureDongle.SD_CLOSE, handle, lp1, lp2, p1, p2, p3, p4, buffer);
|
||||
@@ -118,12 +117,40 @@ public class SecureDongle {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write to User Data Zone (UDZ)
|
||||
* @param StartAddress start address of UDZ, zero based
|
||||
* @param length length of data to write, max 1000 bytes
|
||||
* @param data data to write
|
||||
* @return true if success
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public boolean Write(short StartAddress, short length, byte[] data){
|
||||
if (Opened){
|
||||
handle[0] = Handle;
|
||||
p1[0] = StartAddress>=0 ? StartAddress : 0;
|
||||
if (length<1) length=1;
|
||||
if (length>1000) length=1000;
|
||||
p2[0] = length;
|
||||
System.arraycopy(data, 0, buffer, 0, length);
|
||||
short result = SD.SecureDongle(LibSecureDongle.SD_WRITE, handle, lp1, lp2, p1, p2, p3, p4, buffer);
|
||||
if (result== LibSecureDongle.ERR_SUCCESS){
|
||||
//System.out.println("SecureDongle HardwareID="+HardwareID+" write success ");
|
||||
return true;
|
||||
} else if (event!=null) event.onDongleError("Write", result);
|
||||
} //else System.out.println("SecureDongle not opened");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read from User Data Zone (UDZ)
|
||||
* @param StartAddress Start Address, zero based
|
||||
* @param Length Length of data to read, max 1000 bytes
|
||||
* @return byte array of data, length=0 if failed
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public byte[] Read(short StartAddress, short Length){
|
||||
if (Opened){
|
||||
handle[0] = Handle;
|
||||
@@ -143,35 +170,11 @@ public class SecureDongle {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Write to User Data Zone (UDZ)
|
||||
* @param StartAddress start address of UDZ, zero based
|
||||
* @param length length of data to write, max 1000 bytes
|
||||
* @param data data to write
|
||||
* @return true if success
|
||||
*/
|
||||
public boolean Write(short StartAddress, short length, byte[] data){
|
||||
if (Opened){
|
||||
handle[0] = Handle;
|
||||
p1[0] = StartAddress>=0 ? StartAddress : 0;
|
||||
if (length<1) length=1;
|
||||
if (length>1000) length=1000;
|
||||
p2[0] = length;
|
||||
System.arraycopy(data, 0, buffer, 0, length);
|
||||
short result = SD.SecureDongle(LibSecureDongle.SD_WRITE, handle, lp1, lp2, p1, p2, p3, p4, buffer);
|
||||
if (result== LibSecureDongle.ERR_SUCCESS){
|
||||
//System.out.println("SecureDongle HardwareID="+HardwareID+" write success ");
|
||||
return true;
|
||||
} else if (event!=null) event.onDongleError("Write", result);
|
||||
} //else System.out.println("SecureDongle not opened");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate Random Number
|
||||
* @return short array of random number
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public short[] GenerateRandomNumber(){
|
||||
short[] random = new short[4];
|
||||
if (Opened){
|
||||
@@ -195,6 +198,7 @@ public class SecureDongle {
|
||||
* @param UserID UserID to write
|
||||
* @return true if success
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public boolean WriteUserID(int UserID){
|
||||
if (Opened){
|
||||
handle[0] = Handle;
|
||||
@@ -242,7 +246,7 @@ public class SecureDongle {
|
||||
* if dongle missing, will raise event onDongleMissing
|
||||
*/
|
||||
public void StartMonitor(){
|
||||
new Thread(()->{
|
||||
Thread tx = new Thread(()->{
|
||||
if (HardwareID==0) Find();
|
||||
Open();
|
||||
int firstUserID = ReadUserID();
|
||||
@@ -251,11 +255,7 @@ public class SecureDongle {
|
||||
ismonitoring = true;
|
||||
Logger.info("Start Monitoring UserID="+Integer.toHexString(firstUserID));
|
||||
while (ismonitoring){
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Wait(5000);
|
||||
Open();
|
||||
int newUserID = ReadUserID();
|
||||
Close();
|
||||
@@ -267,7 +267,9 @@ public class SecureDongle {
|
||||
System.out.println("Stop Monitoring");
|
||||
} else System.out.println("Canceled Monitoring, UserID not found");
|
||||
|
||||
}).start();
|
||||
});
|
||||
tx.setDaemon(true);
|
||||
tx.start();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
package id.co.gtc.erhacam;
|
||||
|
||||
import javafx.animation.KeyFrame;
|
||||
import javafx.animation.PauseTransition;
|
||||
import javafx.animation.Timeline;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.InvalidationListener;
|
||||
import javafx.beans.Observable;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.Scene;
|
||||
@@ -14,10 +21,7 @@ import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.shape.Circle;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Screen;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.StageStyle;
|
||||
import javafx.stage.*;
|
||||
import javafx.util.Duration;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
@@ -87,27 +91,8 @@ public class AutoCloseAlert {
|
||||
clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show an alert with a title, content, and automatically close after a few seconds
|
||||
* @param title the title 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
|
||||
* @param onClose What to do after auto close
|
||||
*/
|
||||
public static void show(String title, String content, int seconds, Consumer<String> onClose){
|
||||
if (Platform.isFxApplicationThread()){
|
||||
Stage alertStage = _showtext(title, "", content);
|
||||
closeAlertStage(seconds, onClose, alertStage);
|
||||
} else {
|
||||
Platform.runLater(()->{
|
||||
Stage alertStage = _showtext(title, "", content);
|
||||
closeAlertStage(seconds, onClose, alertStage);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@@ -150,6 +135,87 @@ public class AutoCloseAlert {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void showpictures(String[] pictures, int seconds, Consumer<String> onClose){
|
||||
List<Image> images = new ArrayList<>();
|
||||
|
||||
if (pictures != null){
|
||||
for(String pp : pictures){
|
||||
Image ii = LoadImage(pp);
|
||||
if (ii!=null) images.add(ii);
|
||||
}
|
||||
}
|
||||
|
||||
if (!images.isEmpty()){
|
||||
Image[] source = images.toArray(new Image[0]);
|
||||
if (Platform.isFxApplicationThread()){
|
||||
_showpictures(source, seconds, onClose);
|
||||
} else {
|
||||
Platform.runLater(()-> _showpictures(source,seconds, onClose));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static void _showpictures(Image[] pictures, int seconds, Consumer<String> onClose){
|
||||
close();
|
||||
|
||||
Stage alertStage = new Stage();
|
||||
alertStage.initModality(Modality.APPLICATION_MODAL);
|
||||
alertStage.initStyle(StageStyle.UTILITY);
|
||||
alertStage.setAlwaysOnTop(true);
|
||||
alertStage.setResizable(false);
|
||||
int width = (int) Screen.getPrimary().getBounds().getWidth();
|
||||
int height = (int) Screen.getPrimary().getBounds().getHeight();
|
||||
|
||||
ImageView imageView = new ImageView();
|
||||
imageView.setPreserveRatio(true);
|
||||
imageView.setFitWidth(width);
|
||||
imageView.setFitHeight(height);
|
||||
|
||||
BorderPane borderPane = new BorderPane();
|
||||
borderPane.setCenter(imageView);
|
||||
|
||||
alertStage.setScene(new Scene(borderPane, width, height));
|
||||
alertStage.centerOnScreen();
|
||||
|
||||
Timeline timeline = new Timeline();
|
||||
timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(0), event -> {
|
||||
System.out.println("First timeline, showing the alertstage");
|
||||
alertStage.show();
|
||||
}));
|
||||
|
||||
for(int xx = 0; xx < pictures.length; xx++){
|
||||
final int index = xx;
|
||||
timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(seconds*(index+1)), event -> {
|
||||
System.out.println("showpicture timeline keyframe "+index);
|
||||
imageView.setImage(pictures[index]);
|
||||
}));
|
||||
}
|
||||
timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(seconds* (pictures.length+1)), event -> {
|
||||
System.out.println("showpicture timeline finished");
|
||||
alertStage.close();
|
||||
if (currentAlertStage == alertStage) {
|
||||
currentAlertStage = null;
|
||||
}
|
||||
if (onClose!=null) onClose.accept(shownTitle);
|
||||
clear();
|
||||
}));
|
||||
timeline.play();
|
||||
System.out.println("showpicture timeline play");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
currentAlertStage = alertStage;
|
||||
shownTitle = "";
|
||||
shownContent = "";
|
||||
shownHeader = "";
|
||||
|
||||
}
|
||||
|
||||
private static Stage _showbanner(Image image){
|
||||
close();
|
||||
|
||||
|
||||
@@ -242,33 +242,15 @@ public class Cameradetail {
|
||||
public void setCameraTitle(String title){
|
||||
|
||||
if (ValidString(title)){
|
||||
if (cameratitle!=null){
|
||||
cameratitle.setText(title);
|
||||
}
|
||||
LabelSetText(cameratitle, title,null);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSharpness_indicator(double value){
|
||||
if (value >= config.getSharpnessThreshold()){
|
||||
if (Platform.isFxApplicationThread()){
|
||||
sharpness_indicator.setText("OK");
|
||||
sharpness_indicator.setStyle("-fx-text-fill: green; -fx-border-color: black");
|
||||
} else {
|
||||
Platform.runLater(()->{
|
||||
sharpness_indicator.setText("OK");
|
||||
sharpness_indicator.setStyle("-fx-text-fill: green; -fx-border-color: black");
|
||||
});
|
||||
}
|
||||
LabelSetText(sharpness_indicator, "OK","-fx-text-fill: green; -fx-border-color: black");
|
||||
} else {
|
||||
if (Platform.isFxApplicationThread()) {
|
||||
sharpness_indicator.setText("BAD");
|
||||
sharpness_indicator.setStyle("-fx-text-fill: red; -fx-border-color: black");
|
||||
} else {
|
||||
Platform.runLater(()->{
|
||||
sharpness_indicator.setText("BAD");
|
||||
sharpness_indicator.setStyle("-fx-text-fill: red; -fx-border-color: black");
|
||||
});
|
||||
}
|
||||
LabelSetText(sharpness_indicator,"BAD","-fx-text-fill: red; -fx-border-color: black");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,11 +309,7 @@ public class Cameradetail {
|
||||
* @param status Status of the Camera
|
||||
*/
|
||||
public void setCameraStatus(String status){
|
||||
if (ValidString(status)){
|
||||
if (camerastatus!=null){
|
||||
camerastatus.setText(status);
|
||||
}
|
||||
}
|
||||
LabelSetText(camerastatus, status,null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -352,7 +330,11 @@ public class Cameradetail {
|
||||
public void setCameraStream(Image image){
|
||||
if (image!=null){
|
||||
if (camerastream!=null){
|
||||
camerastream.setImage(image);
|
||||
if (Platform.isFxApplicationThread()){
|
||||
camerastream.setImage(image);
|
||||
} else {
|
||||
Platform.runLater(()->camerastream.setImage(image));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -677,13 +659,13 @@ public class Cameradetail {
|
||||
* @param prefix filename prefix
|
||||
* @return filename path of the saved photo, or null if failed
|
||||
*/
|
||||
public PhotoResult TakePhoto(String directory, String prefix) throws InterruptedException {
|
||||
public PhotoResult TakePhoto(String directory, String prefix) {
|
||||
PhotoResult result = new PhotoResult(cameratitle.getText());
|
||||
if (!ValidDirectory(directory)) directory = currentDirectory;
|
||||
|
||||
if (mGrabber!=null){
|
||||
while(IsGrabbingLiveView.get()){
|
||||
Thread.sleep(10);
|
||||
Wait(10);
|
||||
}
|
||||
TakingPhoto.set(true);
|
||||
if (!BestMat.empty()){
|
||||
@@ -819,15 +801,18 @@ public class Cameradetail {
|
||||
if (event!=null) event.onStartCapturing();
|
||||
|
||||
Task<Image> task = new Task<>() {
|
||||
@SuppressWarnings("BusyWait")
|
||||
@Override
|
||||
protected Image call() {
|
||||
// repeat until capturing is false
|
||||
AtomicInteger fps = new AtomicInteger(0);
|
||||
// eye state = -1 means unknown, 0 means closed, 1 means open
|
||||
int eye_state = -1;
|
||||
boolean waiting_for_second_blink = false;
|
||||
long last_blink = 0;
|
||||
final int[] eye_state = {-1};
|
||||
final boolean[] waiting_for_second_blink = {false};
|
||||
final long[] last_blink = {0};
|
||||
final int[] no_face_counter = {0};
|
||||
final int[] face_counter = {0};
|
||||
final int[] blink_counter = {0};
|
||||
|
||||
|
||||
TimerTask fpsTask = new TimerTask() {
|
||||
@Override
|
||||
@@ -857,23 +842,15 @@ public class Cameradetail {
|
||||
timer.scheduleAtFixedRate(fpsTask, 1000, 1000);
|
||||
|
||||
|
||||
boolean have_frontal_face;
|
||||
boolean have_left_45_face;
|
||||
int _face_width;
|
||||
int _face_height;
|
||||
boolean have_palm = false;
|
||||
boolean have_fist = false;
|
||||
int no_face_counter = 0;
|
||||
int face_counter = 0;
|
||||
int blink_counter = 0;
|
||||
int have_eye_counter = 0;
|
||||
int no_eye_counter = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
while (Capturing.get()) {
|
||||
try {
|
||||
// selama proses pengambilan foto, jangan ambil frame
|
||||
while(TakingPhoto.get() && Capturing.get()){
|
||||
Thread.sleep(10);
|
||||
Wait(10);
|
||||
}
|
||||
|
||||
if (!Capturing.get()) return null;
|
||||
@@ -910,19 +887,19 @@ public class Cameradetail {
|
||||
UMat flippedmat = new UMat();
|
||||
opencv_core.flip(originalmat, flippedmat, 0); // flip vertical
|
||||
flippedmat.copyTo(originalmat);
|
||||
flippedmat.close();
|
||||
}
|
||||
if (config.isFlipCamera()){
|
||||
// revisi 18/03/2025
|
||||
UMat flippedmat = new UMat();
|
||||
opencv_core.flip(originalmat, flippedmat, 1); // flip horizontal
|
||||
flippedmat.copyTo(originalmat);
|
||||
flippedmat.close();
|
||||
}
|
||||
|
||||
// rotate 90 degree counter clockwise karena kamera potrait
|
||||
opencv_core.rotate(originalmat, BestMat, opencv_core.ROTATE_90_COUNTERCLOCKWISE);
|
||||
|
||||
|
||||
|
||||
IsGrabbingLiveView.set(false);
|
||||
|
||||
if (!BestMat.empty()) {
|
||||
@@ -937,23 +914,25 @@ public class Cameradetail {
|
||||
}
|
||||
}
|
||||
if (use_face){
|
||||
|
||||
DetectorResult theface = null;
|
||||
have_frontal_face = false;
|
||||
have_left_45_face = false;
|
||||
_face_width = 0;
|
||||
_face_height = 0;
|
||||
boolean have_frontal_face = false;
|
||||
boolean have_left_45_face = false;
|
||||
int _face_width = 0;
|
||||
int _face_height = 0;
|
||||
|
||||
List<DetectorResult> frontalfaces = HaveFrontalFace(GrayMat);
|
||||
if (!frontalfaces.isEmpty()){
|
||||
|
||||
for(DetectorResult rect : frontalfaces){
|
||||
if (rect.haveFace() ){
|
||||
rect.FaceRectangle(LiveMat);
|
||||
rect.EyesRectangle(LiveMat);
|
||||
if (rect.getFaceWidth()>_face_width) _face_width = rect.getFaceWidth();
|
||||
if (rect.getFaceHeight()>_face_height) _face_height = rect.getFaceHeight();
|
||||
theface = rect;
|
||||
have_frontal_face = true;
|
||||
if (rect.haveEyes()){
|
||||
rect.EyesRectangle(LiveMat);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -963,12 +942,13 @@ public class Cameradetail {
|
||||
if (!Left45Faces.isEmpty()){
|
||||
for(DetectorResult rect : Left45Faces){
|
||||
if (rect.haveFace()){
|
||||
rect.FaceRectangle(LiveMat);
|
||||
rect.EyesRectangle(LiveMat);
|
||||
if (rect.getFaceWidth()>_face_width) _face_width = rect.getFaceWidth();
|
||||
if (rect.getFaceHeight()>_face_height) _face_height = rect.getFaceHeight();
|
||||
have_left_45_face = true;
|
||||
|
||||
if (rect.haveEyes()){
|
||||
rect.FaceRectangle(LiveMat);
|
||||
rect.EyesRectangle(LiveMat);
|
||||
if (rect.getFaceWidth()>_face_width) _face_width = rect.getFaceWidth();
|
||||
if (rect.getFaceHeight()>_face_height) _face_height = rect.getFaceHeight();
|
||||
have_left_45_face = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -976,115 +956,116 @@ public class Cameradetail {
|
||||
|
||||
if (have_frontal_face){
|
||||
|
||||
if (face_counter<5){
|
||||
face_counter++;
|
||||
if (face_counter[0]<5){
|
||||
face_counter[0]++;
|
||||
//System.out.println("Frontal Face Counter = "+face_counter+ " from camera "+cameratitle+" eye count = "+theface.getEyesCount());
|
||||
continue;
|
||||
}
|
||||
|
||||
no_face_counter = 0;
|
||||
if (event!=null) event.onFrontalFaceDetector(true, _face_width, _face_height);
|
||||
LabelVisible(face_indicator,true);
|
||||
|
||||
if (theface.getFace()!=null){
|
||||
LiveMatROI = new Rect(theface.getFace().x(), theface.getFace().y(), theface.getFace().width(), theface.getFace().height());
|
||||
//System.out.println("Frontal Face Detected from camera "+cameratitle+" "+RectToString(LiveMatROI));
|
||||
}
|
||||
|
||||
if (theface.haveEyes()){
|
||||
// ada mata (buka mata)
|
||||
// if (have_eye_counter<1){
|
||||
// have_eye_counter++;
|
||||
// continue;
|
||||
// }
|
||||
// no_eye_counter = 0;
|
||||
//System.out.println("Valid Eye Detected from camera "+cameratitle);
|
||||
if (event!=null) event.onEyeDetector(true);
|
||||
LabelVisible(eye_indicator,true);
|
||||
// Valid eye condition
|
||||
|
||||
if (eye_state!=1){
|
||||
// transisi dari tutup mata ke buka mata
|
||||
if (eye_state==-1) {
|
||||
System.out.println("First Eye Detected from camera "+cameratitle);
|
||||
eye_state=1;
|
||||
continue;
|
||||
}
|
||||
System.out.println("Transition from close to open eyes");
|
||||
eye_state = 1;
|
||||
|
||||
blink_counter++;
|
||||
if (event!=null) event.onBlink(blink_counter);
|
||||
SetText(BlinkCounterLabel, String.valueOf(blink_counter));
|
||||
|
||||
|
||||
|
||||
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 3 detik
|
||||
if (diff<=3000){
|
||||
System.out.println("Double Blink Detected from camera "+cameratitle);
|
||||
if (event!=null) event.onDoubleBlink((int)diff);
|
||||
}
|
||||
waiting_for_second_blink = false;
|
||||
} else {
|
||||
waiting_for_second_blink = true;
|
||||
System.out.println("First Blink Detected from camera "+cameratitle);
|
||||
}
|
||||
last_blink = now;
|
||||
}
|
||||
//continue;
|
||||
} else {
|
||||
// ada muka, tidak ada mata
|
||||
// transisi dari buka mata ke tutup mata
|
||||
// if (no_eye_counter<1){
|
||||
// no_eye_counter++;
|
||||
// continue;
|
||||
// }
|
||||
// have_eye_counter = 0;
|
||||
//System.out.println("Valid No Eye Detected from camera "+cameratitle);
|
||||
if (event!=null) event.onEyeDetector(false);
|
||||
LabelVisible(eye_indicator,false);
|
||||
// Valid no eye condition
|
||||
no_face_counter[0] = 0;
|
||||
if (event!=null) event.onFrontalFaceDetector(true, _face_width, _face_height);
|
||||
//LabelVisible(face_indicator,true);
|
||||
Platform.runLater(()-> face_indicator.setVisible(true));
|
||||
|
||||
if (eye_state!=0){
|
||||
System.out.println("Transition from open to close eyes");
|
||||
eye_state = 0;
|
||||
if (theface.getFace()!=null){
|
||||
LiveMatROI = new Rect(theface.getFace().x(), theface.getFace().y(), theface.getFace().width(), theface.getFace().height());
|
||||
//System.out.println("Frontal Face Detected from camera "+cameratitle+" "+RectToString(LiveMatROI));
|
||||
}
|
||||
|
||||
if (theface.haveEyes()){
|
||||
// ada mata (buka mata)
|
||||
|
||||
if (event!=null) event.onEyeDetector(true);
|
||||
//LabelVisible(eye_indicator,true);
|
||||
Platform.runLater(()-> eye_indicator.setVisible(true));
|
||||
|
||||
//System.out.println("Valid Eye Detected from camera "+cameratitle);
|
||||
// Valid eye condition
|
||||
|
||||
if (eye_state[0]!=1){
|
||||
// transisi dari tutup mata ke buka mata
|
||||
if (eye_state[0]==-1) {
|
||||
System.out.println("First Eye Detected from camera "+cameratitle);
|
||||
eye_state[0]=1;
|
||||
continue;
|
||||
} else {
|
||||
System.out.println("Transition from close to open eyes");
|
||||
eye_state[0] = 1;
|
||||
|
||||
blink_counter[0]++;
|
||||
if (event!=null) event.onBlink(blink_counter[0]);
|
||||
Platform.runLater(()-> BlinkCounterLabel.setText(blink_counter[0]+""));
|
||||
//LabelSetText(BlinkCounterLabel, String.valueOf(blink_counter[0]),null);
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
if (waiting_for_second_blink[0]){
|
||||
long diff = now - last_blink[0];
|
||||
// kalau beda waktu antara blink 1 dan blink 2 kurang dari 3 detik
|
||||
if (diff<=3000){
|
||||
System.out.println("Double Blink Detected from camera "+cameratitle);
|
||||
if (event!=null) event.onDoubleBlink((int)diff);
|
||||
}
|
||||
waiting_for_second_blink[0] = false;
|
||||
} else {
|
||||
waiting_for_second_blink[0] = true;
|
||||
System.out.println("First Blink Detected from camera "+cameratitle);
|
||||
}
|
||||
last_blink[0] = now;
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
// ada muka, tidak ada mata
|
||||
// transisi dari buka mata ke tutup mata
|
||||
|
||||
if (event!=null) event.onEyeDetector(false);
|
||||
//LabelVisible(eye_indicator,false);
|
||||
Platform.runLater(()-> eye_indicator.setVisible(false));
|
||||
// Valid no eye condition
|
||||
|
||||
|
||||
if (eye_state[0]!=0){
|
||||
System.out.println("Transition from open to close eyes");
|
||||
eye_state[0] = 0;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else if (have_left_45_face ){
|
||||
no_face_counter = 0;
|
||||
if (event!=null) event.onProfileFaceDetector(true, _face_width, _face_height);
|
||||
LabelVisible(face_indicator,true);
|
||||
//LabelVisible(face_indicator,true);
|
||||
Platform.runLater(()-> face_indicator.setVisible(true));
|
||||
|
||||
|
||||
} else {
|
||||
// no face detected, but let's not cancel the previous state immediately
|
||||
|
||||
if (no_face_counter<60){
|
||||
if (no_face_counter[0]<60){
|
||||
// toleransi no face selama 60 frame
|
||||
no_face_counter++;
|
||||
no_face_counter[0]++;
|
||||
continue;
|
||||
} else {
|
||||
// beneran dianggap no face detected
|
||||
eye_state = -1;
|
||||
last_blink = 0;
|
||||
waiting_for_second_blink = false;
|
||||
face_counter = 0;
|
||||
blink_counter = 0;
|
||||
no_eye_counter=0;
|
||||
have_eye_counter=0;
|
||||
|
||||
eye_state[0] = -1;
|
||||
last_blink[0] = 0;
|
||||
waiting_for_second_blink[0] = false;
|
||||
face_counter[0] = 0;
|
||||
blink_counter[0] = 0;
|
||||
|
||||
if (event!=null) {
|
||||
event.onFrontalFaceDetector(false, _face_width, _face_height);
|
||||
event.onProfileFaceDetector(false, _face_width, _face_height);
|
||||
event.onEyeDetector(false);
|
||||
event.onBlink(blink_counter);
|
||||
SetText(BlinkCounterLabel, "");
|
||||
LabelVisible(face_indicator,false);
|
||||
LabelVisible(eye_indicator,false);
|
||||
event.onBlink(blink_counter[0]);
|
||||
Platform.runLater(()->{
|
||||
face_indicator.setVisible(false);
|
||||
eye_indicator.setVisible(false);
|
||||
BlinkCounterLabel.setText("");
|
||||
});
|
||||
//LabelSetText(BlinkCounterLabel, "",null);
|
||||
//LabelVisible(face_indicator,false);
|
||||
//LabelVisible(eye_indicator,false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1098,7 +1079,7 @@ public class Cameradetail {
|
||||
Mat imgmat = new Mat();
|
||||
rgbmat.copyTo(imgmat); // copy back to CPU
|
||||
// Update Task Value usign matToWritableImage
|
||||
updateValue(matToWritableImage(imgmat, imgmat.cols(), imgmat.rows()));
|
||||
updateValue(matToWritableImage(imgmat));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (ValidString(e.getMessage())){
|
||||
@@ -1120,7 +1101,9 @@ public class Cameradetail {
|
||||
});
|
||||
|
||||
// start task
|
||||
new Thread(task).start();
|
||||
Thread thread = new Thread(task);
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
@@ -1229,11 +1212,13 @@ public class Cameradetail {
|
||||
return mean.get(0);
|
||||
}
|
||||
|
||||
private WritableImage matToWritableImage(Mat mat, int cols, int rows){
|
||||
private WritableImage matToWritableImage(Mat mat){
|
||||
int cols = mat.cols();
|
||||
int rows = mat.rows();
|
||||
WritableImage writableImage = new WritableImage(cols, rows);
|
||||
ByteBuffer buffer = mat.createBuffer();
|
||||
PixelFormat<ByteBuffer> pixelFormat = PixelFormat.getByteRgbInstance();
|
||||
writableImage.getPixelWriter().setPixels(0, 0, mat.cols(), mat.rows(), pixelFormat, buffer, mat.cols() * 3);
|
||||
writableImage.getPixelWriter().setPixels(0, 0, cols, rows, pixelFormat, buffer, cols * 3);
|
||||
return writableImage;
|
||||
}
|
||||
|
||||
|
||||
@@ -114,21 +114,21 @@ public class CaptureView {
|
||||
config.Save();
|
||||
}
|
||||
|
||||
private void trigger_autofocus(Cameradetail image) throws InterruptedException {
|
||||
private void trigger_autofocus(Cameradetail image) {
|
||||
if (image!=null){
|
||||
if (image.isCapturing()){
|
||||
image.setAutoFocus(false);
|
||||
Thread.sleep(5);
|
||||
Wait(5);
|
||||
image.setFocus(0.7);
|
||||
Thread.sleep(5);
|
||||
Wait(5);
|
||||
image.setAutoFocus(true);
|
||||
Thread.sleep(5);
|
||||
Wait(5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void AutoFocus() throws InterruptedException {
|
||||
private void AutoFocus() {
|
||||
trigger_autofocus(image1);
|
||||
trigger_autofocus(image2);
|
||||
trigger_autofocus(image3);
|
||||
@@ -533,12 +533,8 @@ public class CaptureView {
|
||||
long duration = (System.nanoTime() - nanostart) / 1000000; // in milliseconds
|
||||
System.out.println("TakePhotos duration: "+duration+" ms");
|
||||
|
||||
//AutoCloseAlert.show("Photos Taken", "Photos Taken", "Photos Taken", 5, null);
|
||||
if (AutoCloseAlert.banner_02!=null) {
|
||||
System.out.println("Showing banner 02 after photo taken");
|
||||
AutoCloseAlert.showbanner(AutoCloseAlert.banner_02, 0, null);
|
||||
|
||||
}
|
||||
|
||||
|
||||
String[] files = prc.compressed();
|
||||
if (files.length>0){
|
||||
@@ -553,8 +549,17 @@ public class CaptureView {
|
||||
|
||||
@Override
|
||||
public void onPlaybackFinished(String filename) {
|
||||
UploadFiles(prc, prefix);
|
||||
if (runningTask!=null) runningTask.cancel(false);
|
||||
AutoCloseAlert.showpictures(prc.compressed(),2, (s)->{
|
||||
if (AutoCloseAlert.banner_02!=null) {
|
||||
System.out.println("Showing banner 02 after photo taken");
|
||||
AutoCloseAlert.showbanner(AutoCloseAlert.banner_02, 0, null);
|
||||
|
||||
UploadFiles(prc, prefix);
|
||||
if (runningTask!=null) runningTask.cancel(false);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -615,7 +620,6 @@ public class CaptureView {
|
||||
uploadtask.setOnSucceeded(e-> {
|
||||
System.out.println("UploadTask succeeded");
|
||||
clear();
|
||||
AutoCloseAlert.close();
|
||||
});
|
||||
|
||||
uploadtask.setOnFailed(e-> {
|
||||
@@ -626,12 +630,12 @@ public class CaptureView {
|
||||
audioPlayer.PlayFile(audio_upload_gagal, null);
|
||||
}
|
||||
}
|
||||
AutoCloseAlert.show("Upload Failed", "Upload Failed", "Upload Failed", 5, s -> {
|
||||
clear();
|
||||
});
|
||||
AutoCloseAlert.show("Upload Failed", "Upload Failed", "Upload Failed", 5, s -> clear());
|
||||
});
|
||||
|
||||
new Thread(uploadtask).start();
|
||||
Thread uploadThread = new Thread(uploadtask);
|
||||
uploadThread.setDaemon(true);
|
||||
uploadThread.start();
|
||||
|
||||
} else ShowAlert(AlertType.ERROR, "Error", "No Photos Taken", "No Photos Taken, please check camera");
|
||||
}
|
||||
@@ -713,7 +717,9 @@ public class CaptureView {
|
||||
Logger.info("Left90 Index: "+indexleft90);
|
||||
if (indexleft90!=-1){
|
||||
final int finalindex = indexleft90;
|
||||
new Thread(()-> SetupCameraWithController(image1, camleft90, finalindex)).start();
|
||||
Thread c1 = new Thread(()-> SetupCameraWithController(image1, camleft90, finalindex));
|
||||
c1.setDaemon(true);
|
||||
c1.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -725,7 +731,9 @@ public class CaptureView {
|
||||
Logger.info("Left45 Index: "+indexleft45);
|
||||
if (indexleft45!=-1) {
|
||||
final int finalindex = indexleft45;
|
||||
new Thread(()-> SetupCameraWithController(image2, camleft45, finalindex)).start();
|
||||
Thread c2 = new Thread(()-> SetupCameraWithController(image2, camleft45, finalindex));
|
||||
c2.setDaemon(true);
|
||||
c2.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -737,7 +745,9 @@ public class CaptureView {
|
||||
Logger.info("Center Index: "+indexcenter);
|
||||
if (indexcenter!=-1) {
|
||||
final int finalindex = indexcenter;
|
||||
new Thread(()-> SetupCameraWithController(image3, camcenter, finalindex)).start();
|
||||
Thread c3 = new Thread(()-> SetupCameraWithController(image3, camcenter, finalindex));
|
||||
c3.setDaemon(true);
|
||||
c3.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -749,7 +759,9 @@ public class CaptureView {
|
||||
Logger.info("Right45 Index: "+indexright45);
|
||||
if (indexright45!=-1) {
|
||||
final int finalindex = indexright45;
|
||||
new Thread(()-> SetupCameraWithController(image4, camright45, finalindex)).start();
|
||||
Thread c4 = new Thread(()-> SetupCameraWithController(image4, camright45, finalindex));
|
||||
c4.setDaemon(true);
|
||||
c4.start();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -762,7 +774,9 @@ public class CaptureView {
|
||||
Logger.info("Right90 Index: "+indexright90);
|
||||
if (indexright90!=-1) {
|
||||
final int finalindex = indexright90;
|
||||
new Thread(()-> SetupCameraWithController(image5, camright90, finalindex)).start();
|
||||
Thread c5 = new Thread(()-> SetupCameraWithController(image5, camright90, finalindex));
|
||||
c5.setDaemon(true);
|
||||
c5.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -776,11 +790,9 @@ public class CaptureView {
|
||||
|
||||
private void clear(){
|
||||
isTakingPhoto.set(false);
|
||||
Platform.runLater(()->{
|
||||
medicalRecordID.setText("");
|
||||
PatientName.setText("");
|
||||
barcodeData.setText("");
|
||||
});
|
||||
TextAreaSetText(medicalRecordID,"");
|
||||
TextAreaSetText(PatientName,"");
|
||||
TextAreaSetText(barcodeData,"");
|
||||
}
|
||||
|
||||
public void Unload(){
|
||||
@@ -891,9 +903,7 @@ public class CaptureView {
|
||||
String prefix = barcodeData.getText();
|
||||
if (!barCode.equals(prefix)){
|
||||
final String finalbarCode = barCode;
|
||||
Platform.runLater(()->{
|
||||
barcodeData.setText(finalbarCode);
|
||||
});
|
||||
TextAreaSetText(barcodeData, finalbarCode);
|
||||
Task<PatientRecord> checkpatientID = new Task<>() {
|
||||
@Override
|
||||
protected PatientRecord call() throws Exception {
|
||||
@@ -916,17 +926,14 @@ public class CaptureView {
|
||||
}
|
||||
} else {
|
||||
Logger.error("Record associated with barcode ",finalbarCode," is empty");
|
||||
//AutoCloseAlert.show("Data Tidak Ditemukan","Data dengan barcode "+finalbarCode+" ditemukan di server, tetapi kosong","Pastikan data barcode anda benar", 5);
|
||||
throw new Exception("Data dengan barcode "+finalbarCode+" ditemukan di server, tetapi kosong");
|
||||
}
|
||||
} else {
|
||||
Logger.error("Record associated with barcode ",finalbarCode," is not found");
|
||||
//AutoCloseAlert.show("Data Tidak Ditemukan","Data dengan barcode "+finalbarCode+" tidak ditemukan di server","Pastikan data barcode anda benar",5);
|
||||
throw new Exception("Data dengan barcode "+finalbarCode+" tidak ditemukan di server");
|
||||
}
|
||||
} else {
|
||||
Logger.error("BarcodeResullt with barcode ",finalbarCode," is null");
|
||||
//AutoCloseAlert.show("Data Tidak Ditemukan", "BarcodeResult dengan barcode "+finalbarCode+" menghasilkan null", "Pastikan data barcode anda benar", 5);
|
||||
throw new Exception("BarcodeResult dengan barcode "+finalbarCode+" menghasilkan null");
|
||||
}
|
||||
}
|
||||
@@ -937,13 +944,13 @@ public class CaptureView {
|
||||
if (pr!=null){
|
||||
int medrecid = toInt(pr.medical_record_detail_id);
|
||||
System.out.println("checkpatientID.setOnSucceeded medrecid : "+medrecid);
|
||||
Platform.runLater(()->{
|
||||
medicalRecordID.setText(""+medrecid);
|
||||
PatientName.setText(pr.name);
|
||||
});
|
||||
TextAreaSetText(medicalRecordID,""+medrecid);
|
||||
TextAreaSetText(PatientName, pr.name);
|
||||
|
||||
|
||||
runningTask = timeoutExecutor.schedule(()->{
|
||||
// timeout
|
||||
System.out.println("runningTask timeout after "+timeout+" seconds");
|
||||
clear();
|
||||
}, timeout, TimeUnit.SECONDS);
|
||||
|
||||
@@ -970,16 +977,13 @@ public class CaptureView {
|
||||
System.out.println("checkpatientID.setOnFailed message : "+message);
|
||||
|
||||
|
||||
AutoCloseAlert.show("Data Tidak Ditemukan", message, "Pastikan data barcode anda benar", 5, s -> {
|
||||
clear();
|
||||
});
|
||||
AutoCloseAlert.show("Data Tidak Ditemukan", "Pastikan data barcode anda benar", message , 5, s -> clear());
|
||||
|
||||
});
|
||||
|
||||
new Thread(checkpatientID).start();
|
||||
|
||||
|
||||
|
||||
Thread checkpatientIDThread = new Thread(checkpatientID);
|
||||
checkpatientIDThread.setDaemon(true);
|
||||
checkpatientIDThread.start();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,4 +61,5 @@ public class DetectorResult {
|
||||
if (!haveEyes()) return 0;
|
||||
return Eyes.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,14 +9,10 @@ import org.tinylog.Logger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
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 double scaleFactor = 1.1;
|
||||
private final static int minNeighbors = 3;
|
||||
@@ -24,10 +20,6 @@ public class Detectors {
|
||||
private static Size FaceminSize;
|
||||
private static Size FacemaxSize;
|
||||
|
||||
private static final int EyetoFaceRatio = 6;
|
||||
private static Size EyeminSize;
|
||||
private static Size EyemaxSize;
|
||||
|
||||
public static void LoadAllDetectors(){
|
||||
|
||||
LoadFrontalFaceDetector();
|
||||
@@ -35,47 +27,10 @@ public class Detectors {
|
||||
|
||||
LoadProfileFaceDetector();
|
||||
|
||||
|
||||
//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{
|
||||
//
|
||||
// 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 LoadFrontalFaceDetector(){
|
||||
String filename = SomeCodes.ExtractResource("/haarcascade_frontalface_alt.xml");
|
||||
String filename = SomeCodes.ExtractResource("/haarcascade_frontalface_default.xml");
|
||||
if (filename!=null) {
|
||||
Logger.info("Face Detector file : " + filename);
|
||||
if (frontalfaceDetector==null) {
|
||||
@@ -123,22 +78,6 @@ public class Detectors {
|
||||
} else Logger.error("Unable to extract eye detector file");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 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;
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* Detect if there is a frontal face, containing 2 eyes
|
||||
* @param graymat Mat in Gray Scale
|
||||
@@ -150,12 +89,12 @@ public class Detectors {
|
||||
if (faces!=null && faces.size()>0){
|
||||
|
||||
for(Rect face : faces.get()){
|
||||
RectVector eyes = DetectEye(graymat);
|
||||
RectVector eyes = DetectEye(graymat, face.width());
|
||||
DetectorResult dr = new DetectorResult();
|
||||
dr.setFace(face);
|
||||
if (eyes!=null && eyes.size()>=2){
|
||||
for(Rect eye : eyes.get()){
|
||||
if (IsInsideRect(eye, face)) dr.AddEye(eye);
|
||||
if (SomeCodes.IsInsideRect(eye, face)) dr.AddEye(eye);
|
||||
}
|
||||
}
|
||||
result.add(dr);
|
||||
@@ -170,12 +109,12 @@ public class Detectors {
|
||||
if (faces!=null && faces.size()>0){
|
||||
|
||||
for(Rect face : faces.get()){
|
||||
RectVector eyes = DetectEye(graymat);
|
||||
RectVector eyes = DetectEye(graymat, face.width());
|
||||
DetectorResult dr = new DetectorResult();
|
||||
dr.setFace(face);
|
||||
if (eyes!=null && eyes.size()>0){
|
||||
for(Rect eye : eyes.get()){
|
||||
if (IsInsideRect(eye, face)) dr.AddEye(eye);
|
||||
if (SomeCodes.IsInsideRect(eye, face)) dr.AddEye(eye);
|
||||
}
|
||||
}
|
||||
result.add(dr);
|
||||
@@ -195,34 +134,28 @@ public class Detectors {
|
||||
if (FaceminSize!=null){
|
||||
if (FaceminSize.width()!=value || FaceminSize.height()!=value) {
|
||||
FaceminSize = new Size(value, value);
|
||||
EyeminSize = new Size(value/EyetoFaceRatio, value/EyetoFaceRatio);
|
||||
Logger.info("FaceMinSize changed to : " + FaceminSize.width());
|
||||
Logger.info("EyeMinSize changed to : " + EyeminSize.width());
|
||||
//Logger.info("FaceMinSize changed to : " + FaceminSize.width());
|
||||
}
|
||||
} else {
|
||||
FaceminSize = new Size(value, value);
|
||||
EyeminSize = new Size(value/EyetoFaceRatio, value/EyetoFaceRatio);
|
||||
Logger.info("FaceMinSize created with value : " + FaceminSize.width());
|
||||
Logger.info("EyeMinSize created with value : " + EyeminSize.width());
|
||||
//Logger.info("FaceMinSize created with value : " + FaceminSize.width());
|
||||
}
|
||||
|
||||
System.out.println("Face Min Size : " + FaceminSize.width());
|
||||
}
|
||||
|
||||
public static void setFaceMaxSize(int value){
|
||||
if (FacemaxSize!=null){
|
||||
if (FacemaxSize.width()!=value || FacemaxSize.height()!=value) {
|
||||
FacemaxSize = new Size(value, value);
|
||||
EyemaxSize = new Size(value/EyetoFaceRatio, value/EyetoFaceRatio);
|
||||
Logger.info("FaceMaxSize changed to : " + FacemaxSize.width());
|
||||
Logger.info("EyeMaxSize changed to : " + EyemaxSize.width());
|
||||
//Logger.info("FaceMaxSize changed to : " + FacemaxSize.width());
|
||||
}
|
||||
} else {
|
||||
FacemaxSize = new Size(value, value);
|
||||
EyemaxSize = new Size(value/EyetoFaceRatio, value/EyetoFaceRatio);
|
||||
Logger.info("FaceMaxSize created with value : " + FacemaxSize.width());
|
||||
Logger.info("EyeMaxSize created with value : " + EyemaxSize.width());
|
||||
//Logger.info("FaceMaxSize created with value : " + FacemaxSize.width());
|
||||
}
|
||||
|
||||
System.out.println("Face Max Size : " + FacemaxSize.width());
|
||||
}
|
||||
|
||||
|
||||
@@ -230,23 +163,6 @@ public class Detectors {
|
||||
return Detect(graymat, profilefaceDetector, scaleFactor, minNeighbors, flags, FaceminSize, FacemaxSize);
|
||||
}
|
||||
|
||||
public static RectVector DetectFrontalFace(Mat graymat, int minsize, int maxsize){
|
||||
Size min = new Size(minsize, minsize);
|
||||
Size max = new Size(maxsize, maxsize);
|
||||
RectVector rect = new RectVector();
|
||||
frontalfaceDetector.detectMultiScale(graymat, rect,scaleFactor, minNeighbors, flags, min, max);
|
||||
return rect;
|
||||
}
|
||||
|
||||
public static RectVector DetectProfileFace(Mat graymat, int minsize, int maxsize){
|
||||
Size min = new Size(minsize, minsize);
|
||||
Size max = new Size(maxsize, maxsize);
|
||||
RectVector rect = new RectVector();
|
||||
profilefaceDetector.detectMultiScale(graymat, rect,scaleFactor, minNeighbors, flags, min, max);
|
||||
return rect;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Detect Face from Mat
|
||||
* @param graymat Mat in Gray Scale
|
||||
@@ -256,18 +172,19 @@ public class Detectors {
|
||||
return Detect(graymat, frontalfaceDetector, scaleFactor, minNeighbors, flags, FaceminSize, FacemaxSize);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Detect Eye from Mat
|
||||
* If Eye detected, it will return RectVector with size is number of eyes detected
|
||||
* @param graymat Mat in Gray Scale
|
||||
* @return RectVector if eye detected, otherwise null
|
||||
*/
|
||||
public static RectVector DetectEye(UMat graymat){
|
||||
//return Detect(graymat, eyeDetector, scaleFactor, minNeighbors, flags, EyeminSize, EyemaxSize);
|
||||
return Detect(graymat, eyeDetector);
|
||||
public static RectVector DetectEye(UMat graymat, int facewidth){
|
||||
//return Detect(graymat, eyeDetector);
|
||||
int minwidth = (int)(facewidth*0.2);
|
||||
int maxwidth = (int)(facewidth*0.4);
|
||||
Size minsize = new Size(minwidth, minwidth);
|
||||
Size maxsize = new Size(maxwidth, maxwidth);
|
||||
return Detect(graymat, eyeDetector, scaleFactor, minNeighbors, flags, minsize, maxsize);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ public class MainApplication extends Application {
|
||||
Screen screen = Screen.getPrimary();
|
||||
Rectangle2D screenbound = screen.getBounds();
|
||||
Scene scene = new Scene(fxmlLoader.load(), screenbound.getWidth(), screenbound.getHeight());
|
||||
stage.setTitle("MultiCam Capture App for ERHA 09042025-002");
|
||||
stage.setTitle("MultiCam Capture App for ERHA 10042025-005");
|
||||
stage.setScene(scene);
|
||||
stage.setResizable(true);
|
||||
stage.setMaximized(true);
|
||||
|
||||
@@ -15,8 +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;
|
||||
import static Config.SomeCodes.*;
|
||||
|
||||
public class PhotoRow {
|
||||
@FXML
|
||||
@@ -29,13 +28,11 @@ public class PhotoRow {
|
||||
private final String borderstyle = "-fx-border-color: black; -fx-border-width: 1px;";
|
||||
|
||||
public void setDatetime(String datetime){
|
||||
this.datetime.setText(datetime);
|
||||
this.datetime.setStyle(borderstyle);
|
||||
LabelSetText(this.datetime, datetime, borderstyle);
|
||||
}
|
||||
|
||||
public void setPrefix(String prefix){
|
||||
this.prefix.setText(prefix);
|
||||
this.prefix.setStyle(borderstyle);
|
||||
LabelSetText(this.prefix,prefix,borderstyle);
|
||||
}
|
||||
|
||||
public void setPhotos(int width, int height, String... thumbnails){
|
||||
|
||||
@@ -2,8 +2,6 @@ package id.co.gtc.erhacam;
|
||||
|
||||
import FTP.FTPCheck;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.CheckBox;
|
||||
@@ -11,13 +9,9 @@ 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;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Objects;
|
||||
|
||||
import static Config.SomeCodes.*;
|
||||
|
||||
public class SettingView {
|
||||
@@ -78,7 +72,7 @@ public class SettingView {
|
||||
|
||||
config.SetPhotoDirectory(path);
|
||||
config.Save();
|
||||
PhotoDirectoryPath.setText(path);
|
||||
TextFieldSetText(PhotoDirectoryPath,path);
|
||||
}
|
||||
|
||||
@FXML
|
||||
@@ -191,23 +185,23 @@ public class SettingView {
|
||||
CameraRight45.setValue(config.getCameraRight45());
|
||||
CameraRight90.setValue(config.getCameraRight90());
|
||||
|
||||
FTPHost.setText(config.getFTPHost());
|
||||
FTPPort.setText(config.getFTPPort());
|
||||
FTPUser.setText(config.getFTPUser());
|
||||
FTPPass.setText(config.getFTPPass());
|
||||
FTPPath.setText(config.getFTPPath());
|
||||
TextFieldSetText(FTPHost,config.getFTPHost());
|
||||
TextFieldSetText(FTPPort,config.getFTPPort());
|
||||
TextFieldSetText(FTPUser,config.getFTPUser());
|
||||
TextFieldSetText(FTPPass,config.getFTPPass());
|
||||
TextFieldSetText(FTPPath,config.getFTPPath());
|
||||
|
||||
PhotoDirectoryPath.setText(config.getPhotoDirectory());
|
||||
TextFieldSetText(PhotoDirectoryPath,config.getPhotoDirectory());
|
||||
|
||||
TextFieldSetText(cascadeScaleFactor,String.valueOf(config.getCascadeScaleFactor()));
|
||||
TextFieldSetText(cascadeMinSize,String.valueOf(config.getCascadeMinSize()));
|
||||
TextFieldSetText(cascadeMaxSize,String.valueOf(config.getCascadeMaxSize()));
|
||||
|
||||
cascadeScaleFactor.setText(String.valueOf(config.getCascadeScaleFactor()));
|
||||
cascadeMinSize.setText(String.valueOf(config.getCascadeMinSize()));
|
||||
cascadeMaxSize.setText(String.valueOf(config.getCascadeMaxSize()));
|
||||
|
||||
MirrorCamera.setSelected(config.isMirrorCamera());
|
||||
FlipCamera.setSelected(config.isFlipCamera());
|
||||
|
||||
Sharpness.setText(String.valueOf(config.getSharpnessThreshold()));
|
||||
|
||||
TextFieldSetText(Sharpness,String.valueOf(config.getSharpnessThreshold()));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ProgressBar;
|
||||
|
||||
import static Config.SomeCodes.LabelSetText;
|
||||
import static Config.SomeCodes.ValidString;
|
||||
|
||||
public class UploadProgress {
|
||||
@@ -31,9 +32,7 @@ public class UploadProgress {
|
||||
* @param filename the filename to be displayed
|
||||
*/
|
||||
public void SetFile(String filename){
|
||||
if (ValidString(filename)){
|
||||
labelfile.setText(filename);
|
||||
}
|
||||
LabelSetText(this.labelfile, filename,null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,9 +40,7 @@ public class UploadProgress {
|
||||
* @param status the status to be displayed
|
||||
*/
|
||||
public void SetStatus(String status){
|
||||
if (ValidString(status)){
|
||||
labelstatus.setText(status);
|
||||
}
|
||||
LabelSetText(this.labelstatus, status,null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -197,11 +197,7 @@ public class Cameradetail_Arducam {
|
||||
* @param title Title of the Camera
|
||||
*/
|
||||
public void setCameraTitle(String title){
|
||||
if (ValidString(title)){
|
||||
if (cameratitle!=null){
|
||||
cameratitle.setText(title);
|
||||
}
|
||||
}
|
||||
LabelSetText(this.cameratitle, title, null);
|
||||
}
|
||||
|
||||
public void setSaturation(double value){
|
||||
@@ -259,11 +255,7 @@ public class Cameradetail_Arducam {
|
||||
* @param status Status of the Camera
|
||||
*/
|
||||
public void setCameraStatus(String status){
|
||||
if (ValidString(status)){
|
||||
if (camerastatus!=null){
|
||||
camerastatus.setText(status);
|
||||
}
|
||||
}
|
||||
LabelSetText(this.camerastatus, status,null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -519,13 +511,12 @@ public class Cameradetail_Arducam {
|
||||
* @param prefix filename prefix
|
||||
* @return filename path of the saved photo, or null if failed
|
||||
*/
|
||||
@SuppressWarnings("BusyWait")
|
||||
public String TakePhoto(String directory, String prefix){
|
||||
if (!ValidDirectory(directory)) directory = currentDirectory;
|
||||
if (mGrabber!=null){
|
||||
try{
|
||||
long nanos = System.nanoTime();
|
||||
while(IsGrabbingLiveView.get()) Thread.sleep(10);
|
||||
while(IsGrabbingLiveView.get()) Wait(10);
|
||||
long delta = System.nanoTime() - nanos;
|
||||
double ms = delta / 1000000.0;
|
||||
if (event!=null) event.onLog("Waited IsGrabbingLiveView for "+ms+" miliseconds");
|
||||
@@ -542,10 +533,10 @@ public class Cameradetail_Arducam {
|
||||
|
||||
|
||||
setAutoWB(true);
|
||||
Thread.sleep(1000);
|
||||
Wait(1000);
|
||||
|
||||
setAutoExposure(true);
|
||||
Thread.sleep(1000);
|
||||
Wait(1000);
|
||||
|
||||
long delta3 = System.nanoTime() - nanos;
|
||||
double ms3 = delta3 / 1000000.0;
|
||||
@@ -673,14 +664,13 @@ public class Cameradetail_Arducam {
|
||||
AutoWhiteBalance.setSelected(true);
|
||||
|
||||
val task = new Task<Image>() {
|
||||
@SuppressWarnings("BusyWait")
|
||||
@Override
|
||||
protected Image call() {
|
||||
while (Capturing.get()) {
|
||||
try {
|
||||
// selama proses pengambilan foto, jangan ambil frame
|
||||
while(TakingPhoto.get() && Capturing.get()){
|
||||
Thread.sleep(10);
|
||||
Wait(10);
|
||||
}
|
||||
|
||||
if (!Capturing.get()) return null;
|
||||
@@ -737,7 +727,10 @@ public class Cameradetail_Arducam {
|
||||
});
|
||||
|
||||
// start task
|
||||
new Thread(task).start();
|
||||
Thread taskThread = new Thread(task);
|
||||
taskThread.setDaemon(true);
|
||||
taskThread.start();
|
||||
|
||||
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
|
||||
Reference in New Issue
Block a user