Commit 21032025

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

View File

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