commit 10/04/2025

This commit is contained in:
rdkartono
2025-04-10 16:21:56 +07:00
parent 7cdefa6f1d
commit b6a3076993
23 changed files with 420 additions and 119681 deletions

View File

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