Commit 21032025
This commit is contained in:
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user