Compare commits
10 Commits
72e2789d50
...
revision15
| Author | SHA1 | Date | |
|---|---|---|---|
| 093c32058c | |||
| 80d468a79a | |||
| b248c59e32 | |||
| 64f5b619b7 | |||
| 00f9852fa8 | |||
| 30ef123832 | |||
| 29884c03ed | |||
| a60fe56510 | |||
| f80662a453 | |||
| 30660b9afb |
93
.idea/artifacts/ErhaCam_jar.xml
generated
93
.idea/artifacts/ErhaCam_jar.xml
generated
@@ -3,63 +3,50 @@
|
||||
<output-path>$PROJECT_DIR$/out/artifacts/ErhaCam_jar</output-path>
|
||||
<root id="archive" name="ErhaCam.jar">
|
||||
<element id="module-output" name="ErhaCam" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-fxml/21/javafx-fxml-21-win.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/xerial/sqlite-jdbc/3.46.0.0/sqlite-jdbc-3.46.0.0.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/controlsfx/controlsfx/11.2.1/controlsfx-11.2.1.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-base/21/javafx-base-21.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/javacv-platform/1.5.10/javacv-platform-1.5.10.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/javacv/1.5.10/javacv-1.5.10.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/javacpp/1.5.10/javacpp-1.5.10.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/openblas/0.3.26-1.5.10/openblas-0.3.26-1.5.10.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/opencv/4.9.0-1.5.10/opencv-4.9.0-1.5.10.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/ffmpeg/6.1.1-1.5.10/ffmpeg-6.1.1-1.5.10.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/flycapture/2.13.3.31-1.5.9/flycapture-2.13.3.31-1.5.9.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/libdc1394/2.2.6-1.5.9/libdc1394-2.2.6-1.5.9.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/libfreenect/0.5.7-1.5.9/libfreenect-0.5.7-1.5.9.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/libfreenect2/0.2.0-1.5.9/libfreenect2-0.2.0-1.5.9.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/librealsense/1.12.4-1.5.9/librealsense-1.12.4-1.5.9.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/librealsense2/2.53.1-1.5.9/librealsense2-2.53.1-1.5.9.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/videoinput/0.200-1.5.9/videoinput-0.200-1.5.9.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/artoolkitplus/2.3.1-1.5.9/artoolkitplus-2.3.1-1.5.9.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/leptonica/1.84.1-1.5.10/leptonica-1.84.1-1.5.10.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/tesseract/5.3.4-1.5.10/tesseract-5.3.4-1.5.10.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/javacpp-platform/1.5.10/javacpp-platform-1.5.10.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/javacpp/1.5.10/javacpp-1.5.10-windows-x86_64.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/openblas-platform/0.3.26-1.5.10/openblas-platform-0.3.26-1.5.10.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/opencv-platform/4.9.0-1.5.10/opencv-platform-4.9.0-1.5.10.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/opencv/4.9.0-1.5.10/opencv-4.9.0-1.5.10-windows-x86_64.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/ffmpeg-platform/6.1.1-1.5.10/ffmpeg-platform-6.1.1-1.5.10.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/flycapture-platform/2.13.3.31-1.5.9/flycapture-platform-2.13.3.31-1.5.9.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/libdc1394-platform/2.2.6-1.5.9/libdc1394-platform-2.2.6-1.5.9.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/libfreenect-platform/0.5.7-1.5.9/libfreenect-platform-0.5.7-1.5.9.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/libfreenect2-platform/0.2.0-1.5.9/libfreenect2-platform-0.2.0-1.5.9.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/librealsense-platform/1.12.4-1.5.9/librealsense-platform-1.12.4-1.5.9.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/librealsense2-platform/2.53.1-1.5.9/librealsense2-platform-2.53.1-1.5.9.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/videoinput-platform/0.200-1.5.9/videoinput-platform-0.200-1.5.9.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/videoinput/0.200-1.5.9/videoinput-0.200-1.5.9-windows-x86_64.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/artoolkitplus-platform/2.3.1-1.5.9/artoolkitplus-platform-2.3.1-1.5.9.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/leptonica-platform/1.84.1-1.5.10/leptonica-platform-1.84.1-1.5.10.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/tesseract-platform/5.3.4-1.5.10/tesseract-platform-5.3.4-1.5.10.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/commons-net/commons-net/3.11.1/commons-net-3.11.1.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/google/zxing/javase/3.5.3/javase-3.5.3.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/google/zxing/core/3.5.3/core-3.5.3.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/beust/jcommander/1.82/jcommander-1.82.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/github/jai-imageio/jai-imageio-core/1.4.0/jai-imageio-core-1.4.0.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/tinylog/tinylog-impl/2.7.0/tinylog-impl-2.7.0.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/tinylog/tinylog-api/2.7.0/tinylog-api-2.7.0.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-controls/21/javafx-controls-21.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-fxml/21/javafx-fxml-21.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-graphics/21/javafx-graphics-21-win.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/google/code/gson/gson/2.11.0/gson-2.11.0.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/google/errorprone/error_prone_annotations/2.27.0/error_prone_annotations-2.27.0.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-graphics/21/javafx-graphics-21.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-base/21/javafx-base-21-win.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/net/java/dev/jna/jna/5.15.0/jna-5.15.0.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/slf4j/slf4j-jcl/1.7.36/slf4j-jcl-1.7.36.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/javacpp/1.5.10/javacpp-1.5.10.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-controls/21/javafx-controls-21-win.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/tinylog/tinylog-impl/2.7.0/tinylog-impl-2.7.0.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/opencv/4.9.0-1.5.10/opencv-4.9.0-1.5.10-windows-x86_64.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/openblas/0.3.26-1.5.10/openblas-0.3.26-1.5.10-windows-x86_64.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/controlsfx/controlsfx/11.2.1/controlsfx-11.2.1.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-base/21/javafx-base-21-win.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-fxml/21/javafx-fxml-21.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/openblas/0.3.26-1.5.10/openblas-0.3.26-1.5.10.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/videoinput/0.200-1.5.9/videoinput-0.200-1.5.9.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/google/zxing/javase/3.5.3/javase-3.5.3.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-controls/21/javafx-controls-21.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/net/java/dev/jna/jna/5.15.0/jna-5.15.0.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/leptonica/1.84.1-1.5.10/leptonica-1.84.1-1.5.10.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/projectlombok/lombok/1.18.30/lombok-1.18.30.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-graphics/21/javafx-graphics-21-win.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-graphics/21/javafx-graphics-21.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/libfreenect/0.5.7-1.5.9/libfreenect-0.5.7-1.5.9.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/github/jai-imageio/jai-imageio-core/1.4.0/jai-imageio-core-1.4.0.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/librealsense2/2.53.1-1.5.9/librealsense2-2.53.1-1.5.9.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-fxml/21/javafx-fxml-21-win.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/libfreenect2/0.2.0-1.5.9/libfreenect2-0.2.0-1.5.9.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/google/errorprone/error_prone_annotations/2.27.0/error_prone_annotations-2.27.0.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/xerial/sqlite-jdbc/3.46.0.0/sqlite-jdbc-3.46.0.0.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/google/code/gson/gson/2.11.0/gson-2.11.0.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/videoinput/0.200-1.5.9/videoinput-0.200-1.5.9-windows-x86_64.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-controls/21/javafx-controls-21-win.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/slf4j/slf4j-jcl/1.7.36/slf4j-jcl-1.7.36.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/opencv/4.9.0-1.5.10/opencv-4.9.0-1.5.10.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/javacv/1.5.10/javacv-1.5.10.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/google/zxing/core/3.5.3/core-3.5.3.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/librealsense/1.12.4-1.5.9/librealsense-1.12.4-1.5.9.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/flycapture/2.13.3.31-1.5.9/flycapture-2.13.3.31-1.5.9.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/tesseract/5.3.4-1.5.10/tesseract-5.3.4-1.5.10.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/beust/jcommander/1.82/jcommander-1.82.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/tinylog/tinylog-api/2.7.0/tinylog-api-2.7.0.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/openjfx/javafx-base/21/javafx-base-21.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/ffmpeg/6.1.1-1.5.10/ffmpeg-6.1.1-1.5.10-windows-x86_64.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/ffmpeg/6.1.1-1.5.10/ffmpeg-6.1.1-1.5.10.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/javacpp/1.5.10/javacpp-1.5.10-windows-x86_64.jar" path-in-jar="/" />
|
||||
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/org/bytedeco/artoolkitplus/2.3.1-1.5.9/artoolkitplus-2.3.1-1.5.9.jar" path-in-jar="/" />
|
||||
</root>
|
||||
</artifact>
|
||||
</component>
|
||||
@@ -1,22 +1,26 @@
|
||||
#Thu Dec 19 11:49:05 WIB 2024
|
||||
#Mon Mar 17 15:01:40 WIB 2025
|
||||
AudioPhase1=C\:\\Users\\rdkar\\OneDrive\\Documents\\IntelliJ Project\\ErhaCam\\audio\\phase1.mp3
|
||||
AudioPhase2=C\:\\Users\\rdkar\\OneDrive\\Documents\\IntelliJ Project\\ErhaCam\\audio\\phase2.mp3
|
||||
AudioPhase3=C\:\\Users\\rdkar\\OneDrive\\Documents\\IntelliJ Project\\ErhaCam\\audio\\phase3.mp3
|
||||
AudioPhase4=C\:\\Users\\rdkar\\OneDrive\\Documents\\IntelliJ Project\\ErhaCam\\audio\\phase4.mp3
|
||||
AudioPhase5=C\:\\Users\\rdkar\\OneDrive\\Documents\\IntelliJ Project\\ErhaCam\\audio\\phase5.mp3
|
||||
CameraCenter=OBSBOT Meet 2 StreamCamera
|
||||
CameraConfigCenter={"Brightness"\:0.0,"Contrast"\:32.0,"Saturation"\:64.0,"Hue"\:0.0,"Gain"\:0.0,"Exposure"\:157.0,"Sharpness"\:3.0,"Gamma"\:100.0,"AutoExposure"\:true,"AutoFocus"\:true,"AutoWhiteBalance"\:true}
|
||||
CameraConfigLeft45={"Brightness"\:37.58730158730158,"Contrast"\:32.0,"Saturation"\:64.0,"Hue"\:0.0,"Gain"\:0.0,"Exposure"\:157.0,"Sharpness"\:3.0,"Gamma"\:100.0,"AutoExposure"\:true,"AutoFocus"\:true,"AutoWhiteBalance"\:true}
|
||||
CameraConfigLeft90={"Brightness"\:0.0,"Contrast"\:32.0,"Saturation"\:64.0,"Hue"\:0.0,"Gain"\:0.0,"Exposure"\:157.0,"Sharpness"\:3.0,"Gamma"\:100.0,"AutoExposure"\:true,"AutoFocus"\:true,"AutoWhiteBalance"\:true}
|
||||
CameraConfigRight45={"Brightness"\:0.0,"Contrast"\:32.0,"Saturation"\:64.0,"Hue"\:0.0,"Gain"\:0.0,"Exposure"\:157.0,"Sharpness"\:3.0,"Gamma"\:100.0,"AutoExposure"\:true,"AutoFocus"\:true,"AutoWhiteBalance"\:true}
|
||||
CameraConfigRight90={"Brightness"\:0.0,"Contrast"\:32.0,"Saturation"\:64.0,"Hue"\:0.0,"Gain"\:0.0,"Exposure"\:157.0,"Sharpness"\:3.0,"Gamma"\:100.0,"AutoExposure"\:true,"AutoFocus"\:true,"AutoWhiteBalance"\:true}
|
||||
CameraLeft45=OBSBOT Meet 2 StreamCamera
|
||||
CameraLeft90=OBSBOT Meet 2 StreamCamera
|
||||
CameraRight45=OBSBOT Meet 2 StreamCamera
|
||||
CameraRight90=OBSBOT Meet 2 StreamCamera
|
||||
CameraCenter=
|
||||
CameraConfigCenter={"Brightness"\:0.0,"Contrast"\:0.0,"Saturation"\:0.0,"Hue"\:0.0,"Gain"\:1.0,"Exposure"\:1.0,"Sharpness"\:0.0,"Gamma"\:0.0,"AutoExposure"\:true,"AutoFocus"\:true,"AutoWhiteBalance"\:true}
|
||||
CameraConfigLeft45={"Brightness"\:0.0,"Contrast"\:0.0,"Saturation"\:0.0,"Hue"\:0.0,"Gain"\:1.0,"Exposure"\:1.0,"Sharpness"\:0.0,"Gamma"\:0.0,"AutoExposure"\:true,"AutoFocus"\:true,"AutoWhiteBalance"\:true}
|
||||
CameraConfigLeft90={"Brightness"\:0.0,"Contrast"\:0.0,"Saturation"\:0.0,"Hue"\:0.0,"Gain"\:1.0,"Exposure"\:1.0,"Sharpness"\:0.0,"Gamma"\:0.0,"AutoExposure"\:true,"AutoFocus"\:true,"AutoWhiteBalance"\:true}
|
||||
CameraConfigRight45={"Brightness"\:0.0,"Contrast"\:0.0,"Saturation"\:0.0,"Hue"\:0.0,"Gain"\:1.0,"Exposure"\:1.0,"Sharpness"\:0.0,"Gamma"\:0.0,"AutoExposure"\:true,"AutoFocus"\:true,"AutoWhiteBalance"\:true}
|
||||
CameraConfigRight90={"Brightness"\:0.0,"Contrast"\:0.0,"Saturation"\:0.0,"Hue"\:0.0,"Gain"\:1.0,"Exposure"\:1.0,"Sharpness"\:0.0,"Gamma"\:0.0,"AutoExposure"\:true,"AutoFocus"\:true,"AutoWhiteBalance"\:true}
|
||||
CameraLeft45=
|
||||
CameraLeft90=ACER QHD User Facing
|
||||
CameraRight45=
|
||||
CameraRight90=
|
||||
FTPHost=192.168.10.2
|
||||
FTPPass=password
|
||||
FTPPath=/
|
||||
FTPPort=21
|
||||
FTPUser=user
|
||||
PhotoDirectory=C\:\\Users\\rdkar\\OneDrive\\Desktop\\photoresult
|
||||
PhotoDirectory=C\:\\Users\\rdkar\\OneDrive\\Desktop\\Erha Capture
|
||||
cascadeMaxSize=500
|
||||
cascadeMinNeighbors=3
|
||||
cascadeMinSize=250
|
||||
cascadeScaleFactor=1.1
|
||||
|
||||
BIN
database.db
BIN
database.db
Binary file not shown.
12213
haarcascade_eye.xml
Normal file
12213
haarcascade_eye.xml
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
29690
haarcascade_profileface.xml
Normal file
29690
haarcascade_profileface.xml
Normal file
File diff suppressed because it is too large
Load Diff
3527
haarcascades/fist.xml
Normal file
3527
haarcascades/fist.xml
Normal file
File diff suppressed because it is too large
Load Diff
12213
haarcascades/haarcascade_eye.xml
Normal file
12213
haarcascades/haarcascade_eye.xml
Normal file
File diff suppressed because it is too large
Load Diff
22619
haarcascades/haarcascade_eye_tree_eyeglasses.xml
Normal file
22619
haarcascades/haarcascade_eye_tree_eyeglasses.xml
Normal file
File diff suppressed because it is too large
Load Diff
33314
haarcascades/haarcascade_frontalface_default.xml
Normal file
33314
haarcascades/haarcascade_frontalface_default.xml
Normal file
File diff suppressed because it is too large
Load Diff
7390
haarcascades/haarcascade_lefteye_2splits.xml
Normal file
7390
haarcascades/haarcascade_lefteye_2splits.xml
Normal file
File diff suppressed because it is too large
Load Diff
7633
haarcascades/haarcascade_mcs_leftear.xml
Normal file
7633
haarcascades/haarcascade_mcs_leftear.xml
Normal file
File diff suppressed because it is too large
Load Diff
7931
haarcascades/haarcascade_mcs_rightear.xml
Normal file
7931
haarcascades/haarcascade_mcs_rightear.xml
Normal file
File diff suppressed because it is too large
Load Diff
29690
haarcascades/haarcascade_profileface.xml
Normal file
29690
haarcascades/haarcascade_profileface.xml
Normal file
File diff suppressed because it is too large
Load Diff
7407
haarcascades/haarcascade_righteye_2splits.xml
Normal file
7407
haarcascades/haarcascade_righteye_2splits.xml
Normal file
File diff suppressed because it is too large
Load Diff
5211
haarcascades/rpalm.xml
Normal file
5211
haarcascades/rpalm.xml
Normal file
File diff suppressed because it is too large
Load Diff
1361
hs_err_pid42244.log
1361
hs_err_pid42244.log
File diff suppressed because one or more lines are too long
BIN
libs/win32-x86-64/SecureDongleJ.dll
Normal file
BIN
libs/win32-x86-64/SecureDongleJ.dll
Normal file
Binary file not shown.
BIN
libs/win32-x86/SecureDongleJ.dll
Normal file
BIN
libs/win32-x86/SecureDongleJ.dll
Normal file
Binary file not shown.
Binary file not shown.
@@ -1,22 +1,26 @@
|
||||
#Wed Oct 23 10:37:24 WIB 2024
|
||||
AudioPhase1=C\:\\Users\\rdkar\\OneDrive\\Documents\\IntelliJ Project\\ErhaCam\\out\\artifacts\\ErhaCam_jar\\audio\\phase1.mp3
|
||||
AudioPhase2=C\:\\Users\\rdkar\\OneDrive\\Documents\\IntelliJ Project\\ErhaCam\\out\\artifacts\\ErhaCam_jar\\audio\\phase2.mp3
|
||||
AudioPhase3=C\:\\Users\\rdkar\\OneDrive\\Documents\\IntelliJ Project\\ErhaCam\\out\\artifacts\\ErhaCam_jar\\audio\\phase3.mp3
|
||||
AudioPhase4=C\:\\Users\\rdkar\\OneDrive\\Documents\\IntelliJ Project\\ErhaCam\\out\\artifacts\\ErhaCam_jar\\audio\\phase4.mp3
|
||||
AudioPhase5=C\:\\Users\\rdkar\\OneDrive\\Documents\\IntelliJ Project\\ErhaCam\\out\\artifacts\\ErhaCam_jar\\audio\\phase5.mp3
|
||||
CameraCenter=
|
||||
CameraConfigCenter={"Brightness"\:0.0,"Contrast"\:0.0,"Saturation"\:0.0,"Hue"\:0.0,"Gain"\:0.0,"Exposure"\:1.0,"Sharpness"\:0.0,"Gamma"\:0.0,"AutoExposure"\:true,"AutoFocus"\:true,"AutoWhiteBalance"\:true}
|
||||
CameraConfigLeft45={"Brightness"\:0.0,"Contrast"\:0.0,"Saturation"\:0.0,"Hue"\:0.0,"Gain"\:0.0,"Exposure"\:1.0,"Sharpness"\:0.0,"Gamma"\:0.0,"AutoExposure"\:true,"AutoFocus"\:true,"AutoWhiteBalance"\:true}
|
||||
CameraConfigLeft90={"Brightness"\:0.0,"Contrast"\:0.0,"Saturation"\:0.0,"Hue"\:0.0,"Gain"\:0.0,"Exposure"\:1.0,"Sharpness"\:0.0,"Gamma"\:0.0,"AutoExposure"\:true,"AutoFocus"\:true,"AutoWhiteBalance"\:true}
|
||||
CameraConfigRight45={"Brightness"\:0.0,"Contrast"\:0.0,"Saturation"\:0.0,"Hue"\:0.0,"Gain"\:0.0,"Exposure"\:1.0,"Sharpness"\:0.0,"Gamma"\:0.0,"AutoExposure"\:true,"AutoFocus"\:true,"AutoWhiteBalance"\:true}
|
||||
CameraConfigRight90={"Brightness"\:0.0,"Contrast"\:0.0,"Saturation"\:0.0,"Hue"\:0.0,"Gain"\:0.0,"Exposure"\:1.0,"Sharpness"\:0.0,"Gamma"\:0.0,"AutoExposure"\:true,"AutoFocus"\:true,"AutoWhiteBalance"\:true}
|
||||
CameraLeft45=
|
||||
CameraLeft90=
|
||||
CameraRight45=
|
||||
CameraRight90=
|
||||
#Mon Feb 03 15:09:08 ICT 2025
|
||||
AudioPhase1=\\\\RDKARTONO_SFG14\\ErhaCam_jar\\audio\\phase1.mp3
|
||||
AudioPhase2=\\\\RDKARTONO_SFG14\\ErhaCam_jar\\audio\\phase2.mp3
|
||||
AudioPhase3=\\\\RDKARTONO_SFG14\\ErhaCam_jar\\audio\\phase3.mp3
|
||||
AudioPhase4=\\\\RDKARTONO_SFG14\\ErhaCam_jar\\audio\\phase4.mp3
|
||||
AudioPhase5=\\\\RDKARTONO_SFG14\\ErhaCam_jar\\audio\\phase5.mp3
|
||||
CameraCenter=OBSBOT Meet 2 StreamCamera
|
||||
CameraConfigCenter={"Brightness"\:0.0,"Contrast"\:0.0,"Saturation"\:0.0,"Hue"\:0.0,"Gain"\:1.0,"Exposure"\:1.0,"Sharpness"\:0.0,"Gamma"\:0.0,"AutoExposure"\:true,"AutoFocus"\:true,"AutoWhiteBalance"\:true}
|
||||
CameraConfigLeft45={"Brightness"\:0.0,"Contrast"\:0.0,"Saturation"\:0.0,"Hue"\:0.0,"Gain"\:1.0,"Exposure"\:1.0,"Sharpness"\:0.0,"Gamma"\:0.0,"AutoExposure"\:true,"AutoFocus"\:true,"AutoWhiteBalance"\:true}
|
||||
CameraConfigLeft90={"Brightness"\:0.0,"Contrast"\:0.0,"Saturation"\:0.0,"Hue"\:0.0,"Gain"\:1.0,"Exposure"\:1.0,"Sharpness"\:0.0,"Gamma"\:0.0,"AutoExposure"\:true,"AutoFocus"\:true,"AutoWhiteBalance"\:true}
|
||||
CameraConfigRight45={"Brightness"\:0.0,"Contrast"\:0.0,"Saturation"\:0.0,"Hue"\:0.0,"Gain"\:1.0,"Exposure"\:1.0,"Sharpness"\:0.0,"Gamma"\:0.0,"AutoExposure"\:true,"AutoFocus"\:true,"AutoWhiteBalance"\:true}
|
||||
CameraConfigRight90={"Brightness"\:0.0,"Contrast"\:0.0,"Saturation"\:0.0,"Hue"\:0.0,"Gain"\:1.0,"Exposure"\:1.0,"Sharpness"\:0.0,"Gamma"\:0.0,"AutoExposure"\:true,"AutoFocus"\:true,"AutoWhiteBalance"\:true}
|
||||
CameraLeft45=OBSBOT Meet 2 StreamCamera
|
||||
CameraLeft90=OBSBOT Meet 2 StreamCamera
|
||||
CameraRight45=OBSBOT Meet 2 StreamCamera
|
||||
CameraRight90=OBSBOT Meet 2 StreamCamera
|
||||
FTPHost=192.168.10.2
|
||||
FTPPass=password
|
||||
FTPPath=/
|
||||
FTPPort=21
|
||||
FTPUser=user
|
||||
PhotoDirectory=C\:\\Users\\rdkar\\OneDrive\\Documents\\IntelliJ Project\\ErhaCam\\out\\artifacts\\ErhaCam_jar
|
||||
PhotoDirectory=\\\\RDKARTONO_SFG14\\ErhaCam_jar
|
||||
cascadeMaxSize=400
|
||||
cascadeMinNeighbors=3
|
||||
cascadeMinSize=200
|
||||
cascadeScaleFactor=1.1
|
||||
|
||||
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
BIN
pengambilan_berhasil.wav
Normal file
BIN
pengambilan_berhasil.wav
Normal file
Binary file not shown.
BIN
pengambilan_gagal.wav
Normal file
BIN
pengambilan_gagal.wav
Normal file
Binary file not shown.
105
pom.xml
105
pom.xml
@@ -36,16 +36,115 @@
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.bytedeco</groupId>-->
|
||||
<!-- <artifactId>javacv-platform</artifactId>-->
|
||||
<!-- <version>1.5.10</version>-->
|
||||
<!-- <exclusions>-->
|
||||
<!-- <exclusion>-->
|
||||
<!-- <groupId>org.bytedeco</groupId>-->
|
||||
<!-- <artifactId>leptonica-platform</artifactId>-->
|
||||
<!-- </exclusion>-->
|
||||
<!-- <exclusion>-->
|
||||
<!-- <groupId>org.bytedeco</groupId>-->
|
||||
<!-- <artifactId>artoolkitplus-platform</artifactId>-->
|
||||
<!-- </exclusion>-->
|
||||
<!-- <exclusion>-->
|
||||
<!-- <groupId>org.bytedeco</groupId>-->
|
||||
<!-- <artifactId>libdc1394-platform</artifactId>-->
|
||||
<!-- </exclusion>-->
|
||||
<!-- <exclusion>-->
|
||||
<!-- <groupId>org.bytedeco</groupId>-->
|
||||
<!-- <artifactId>libfreenect-platform</artifactId>-->
|
||||
<!-- </exclusion>-->
|
||||
<!-- <exclusion>-->
|
||||
<!-- <groupId>org.bytedeco</groupId>-->
|
||||
<!-- <artifactId>libfreenect2-platform</artifactId>-->
|
||||
<!-- </exclusion>-->
|
||||
<!-- <exclusion>-->
|
||||
<!-- <groupId>org.bytedeco</groupId>-->
|
||||
<!-- <artifactId>flycapture-platform</artifactId>-->
|
||||
<!-- </exclusion>-->
|
||||
<!-- <exclusion>-->
|
||||
<!-- <groupId>org.bytedeco</groupId>-->
|
||||
<!-- <artifactId>librealsense-platform</artifactId>-->
|
||||
<!-- </exclusion>-->
|
||||
<!-- <exclusion>-->
|
||||
<!-- <groupId>org.bytedeco</groupId>-->
|
||||
<!-- <artifactId>librealsense2-platform</artifactId>-->
|
||||
<!-- </exclusion>-->
|
||||
<!-- <exclusion>-->
|
||||
<!-- <groupId>org.bytedeco</groupId>-->
|
||||
<!-- <artifactId>tesseract-platform</artifactId>-->
|
||||
<!-- </exclusion>-->
|
||||
<!-- <!– platform dibuangin semua, kemudian tambah sendiri linux-arm64, windows-x86_64, linux-x86_64 –>-->
|
||||
<!-- <exclusion>-->
|
||||
<!-- <groupId>org.bytedeco</groupId>-->
|
||||
<!-- <artifactId>flandmark-platform</artifactId>-->
|
||||
<!-- </exclusion>-->
|
||||
|
||||
<!-- <exclusion>-->
|
||||
<!-- <groupId>org.bytedeco</groupId>-->
|
||||
<!-- <artifactId>openblas-platform</artifactId>-->
|
||||
<!-- </exclusion>-->
|
||||
|
||||
<!-- <exclusion>-->
|
||||
<!-- <groupId>org.bytedeco</groupId>-->
|
||||
<!-- <artifactId>ffmpeg-platform</artifactId>-->
|
||||
<!-- </exclusion>-->
|
||||
<!-- <exclusion>-->
|
||||
<!-- <groupId>org.bytedeco</groupId>-->
|
||||
<!-- <artifactId>videoinput-platform</artifactId>-->
|
||||
<!-- </exclusion>-->
|
||||
<!-- <exclusion>-->
|
||||
<!-- <groupId>org.bytedeco</groupId>-->
|
||||
<!-- <artifactId>javacpp-platform</artifactId>-->
|
||||
<!-- </exclusion>-->
|
||||
<!-- <exclusion>-->
|
||||
<!-- <groupId>org.bytedeco</groupId>-->
|
||||
<!-- <artifactId>opencv-platform</artifactId>-->
|
||||
<!-- </exclusion>-->
|
||||
|
||||
<!-- </exclusions>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>javacv-platform</artifactId>
|
||||
<artifactId>javacv</artifactId>
|
||||
<version>1.5.10</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>videoinput</artifactId>
|
||||
<version>0.200-1.5.9</version>
|
||||
<classifier>windows-x86_64</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>javacpp-platform</artifactId>
|
||||
<version>1.5.10</version>
|
||||
<artifactId>ffmpeg</artifactId>
|
||||
<version>6.1.1-1.5.10</version>
|
||||
<classifier>windows-x86_64</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>opencv</artifactId>
|
||||
<version>4.9.0-1.5.10</version>
|
||||
<classifier>windows-x86_64</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>javacpp</artifactId>
|
||||
<version>1.5.10</version>
|
||||
<classifier>windows-x86_64</classifier>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>openblas</artifactId>
|
||||
<version>0.3.26-1.5.10</version>
|
||||
<classifier>windows-x86_64</classifier>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-net</groupId>
|
||||
<artifactId>commons-net</artifactId>
|
||||
|
||||
BIN
posisikan_wajah.wav
Normal file
BIN
posisikan_wajah.wav
Normal file
Binary file not shown.
BIN
scan_barcode.wav
Normal file
BIN
scan_barcode.wav
Normal file
Binary file not shown.
@@ -3,10 +3,37 @@ package BASS;
|
||||
import lombok.Getter;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class AudioPlayer {
|
||||
private final Bass bass = Bass.Instance;
|
||||
private @Getter boolean inited = false;
|
||||
private @Getter String currentFile = "";
|
||||
private int currentFileHandle = 0;
|
||||
|
||||
public void WaitUntilFinished(){
|
||||
while(currentFileHandle!=0){
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPlaying(){
|
||||
return currentFileHandle!=0;
|
||||
}
|
||||
|
||||
public void StopCurrentPlayback(){
|
||||
if (currentFileHandle!=0){
|
||||
if (bass.BASS_ChannelStop(currentFileHandle)){
|
||||
Logger.info("AudioPlayer StopCurrentPlayback success");
|
||||
} else Logger.error("AudioPlayer StopCurrentPlayback failed, error code: "+bass.BASS_ErrorGetCode());
|
||||
}
|
||||
currentFileHandle = 0;
|
||||
currentFile = "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize AudioPlayer
|
||||
@@ -18,6 +45,7 @@ public class AudioPlayer {
|
||||
if (deviceid>-1){
|
||||
int initflags = Bass.BASS_DEVICE_16BITS | Bass.BASS_DEVICE_STEREO | Bass.BASS_DEVICE_FREQ | Bass.BASS_DEVICE_REINIT;
|
||||
if (bass.BASS_Init(deviceid,samplingrate,initflags)){
|
||||
currentFileHandle = 0;
|
||||
inited = true;
|
||||
} else Logger.error("AudioPlayer initialization failed, BASS_Init failed, error code: " + bass.BASS_ErrorGetCode());
|
||||
} else Logger.error("AudioPlayer initialization failed, deviceid is not correct");
|
||||
@@ -34,6 +62,8 @@ public class AudioPlayer {
|
||||
} else Logger.error("AudioPlayer Free failed, error code: "+bass.BASS_ErrorGetCode());
|
||||
inited = false;
|
||||
}
|
||||
currentFile = "";
|
||||
currentFileHandle = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,10 +105,12 @@ public class AudioPlayer {
|
||||
* @return true if success, false if failed
|
||||
*/
|
||||
public boolean PlayFile(final String filename, final PlaybackStatus playbackstatus){
|
||||
if (inited){
|
||||
if (inited && filename!=null && !filename.isEmpty()){
|
||||
int filehandle = bass.BASS_StreamCreateFile(false, filename, 0, 0, 0);
|
||||
if (filehandle!=0){
|
||||
if (bass.BASS_ChannelStart(filehandle)){
|
||||
currentFile = filename;
|
||||
currentFileHandle = filehandle;
|
||||
new Thread(()->{
|
||||
if (playbackstatus!=null) playbackstatus.onPlaybackStarted(filename);
|
||||
boolean iscontinue = true;
|
||||
@@ -101,6 +133,8 @@ public class AudioPlayer {
|
||||
}
|
||||
}
|
||||
if (playbackstatus!=null) playbackstatus.onPlaybackFinished(filename);
|
||||
currentFile = "";
|
||||
currentFileHandle = 0;
|
||||
}).start();
|
||||
return true;
|
||||
} else Logger.error("AudioPlayer PlayFile failed, BASS_ChannelStart failed, error code: "+bass.BASS_ErrorGetCode());
|
||||
|
||||
@@ -2,6 +2,13 @@ package Camera;
|
||||
|
||||
public interface LiveCamEvent {
|
||||
void onDetectedQRCode(String qrCode);
|
||||
void onFaceDetector(boolean hasface, int width, int height);
|
||||
void onFrontalFaceDetector(boolean hasface, int width, int height);
|
||||
void onProfileFaceDetector(boolean hasface, int width, int height);
|
||||
void onEyeDetector(boolean hasEye, int width, int height);
|
||||
void onLeftEarDetector(boolean hasLeftEar, int width, int height);
|
||||
void onRightEarDetector(boolean hasRightEar, int width, int height);
|
||||
void onLeftEyeDetector(boolean hasLeftEye, int width, int height);
|
||||
void onRightEyeDetector(boolean hasRightEye, int width, int height);
|
||||
void onLog(String log);
|
||||
void onBlink(int counter);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ public enum ObsbotMeet2 {
|
||||
Mode4(0.2, 640, 360, "16:9"),
|
||||
Mode5(0.3, 640, 480, "4:3"),
|
||||
ModeBest(8.3, 3840, 2160, "16:9"),
|
||||
ModeLive(0.3, 640, 480, "4:3");
|
||||
ModeLive(0.3, 640, 360, "16:9");
|
||||
|
||||
private final double Megapixel;
|
||||
private final int width;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package Config;
|
||||
|
||||
import id.co.gtc.erhacam.Detectors;
|
||||
import lombok.Getter;
|
||||
import lombok.val;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.io.File;
|
||||
@@ -40,6 +40,11 @@ public class ConfigFile {
|
||||
|
||||
private String PhotoDirectory;
|
||||
|
||||
private @Getter double cascadeScaleFactor;
|
||||
private @Getter int cascadeMinNeighbors;
|
||||
private @Getter int cascadeMinSize;
|
||||
private @Getter int cascadeMaxSize;
|
||||
|
||||
private boolean needsave = false;
|
||||
|
||||
public ConfigFile(){
|
||||
@@ -48,6 +53,34 @@ public class ConfigFile {
|
||||
Load();
|
||||
}
|
||||
|
||||
public void setCascadeScaleFactor(double value){
|
||||
if (cascadeScaleFactor != value){
|
||||
cascadeScaleFactor = value;
|
||||
needsave = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void setCascadeMinNeighbors(int value){
|
||||
if (cascadeMinNeighbors != value){
|
||||
cascadeMinNeighbors = value;
|
||||
needsave = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void setCascadeMinSize(int value){
|
||||
if (cascadeMinSize != value){
|
||||
cascadeMinSize = value;
|
||||
needsave = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void setCascadeMaxSize(int value){
|
||||
if (cascadeMaxSize != value){
|
||||
cascadeMaxSize = value;
|
||||
needsave = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetPhotoDirectory(String path){
|
||||
if (ValidString(path)){
|
||||
if (!path.equals(PhotoDirectory)){
|
||||
@@ -528,6 +561,11 @@ public class ConfigFile {
|
||||
if (prop.getProperty(CameraConfigEnum.CameraConfigRight45.toString()) == null) allcorrect = false;
|
||||
if (prop.getProperty(CameraConfigEnum.CameraConfigRight90.toString()) == null) allcorrect = false;
|
||||
|
||||
if (prop.getProperty("cascadeScaleFactor") == null) allcorrect = false;
|
||||
if (prop.getProperty("cascadeMinNeighbors") == null) allcorrect = false;
|
||||
if (prop.getProperty("cascadeMinSize") == null) allcorrect = false;
|
||||
if (prop.getProperty("cascadeMaxSize") == null) allcorrect = false;
|
||||
|
||||
if (allcorrect){
|
||||
AudioPhase1 = prop.getProperty("AudioPhase1");
|
||||
AudioPhase2 = prop.getProperty("AudioPhase2");
|
||||
@@ -554,7 +592,17 @@ public class ConfigFile {
|
||||
ConfigRight45 = gson.fromJson(prop.getProperty(CameraConfigEnum.CameraConfigRight45.toString()), CameraConfig.class);
|
||||
ConfigRight90 = gson.fromJson(prop.getProperty(CameraConfigEnum.CameraConfigRight90.toString()), CameraConfig.class);
|
||||
|
||||
cascadeScaleFactor = toDouble(prop.getProperty("cascadeScaleFactor"));
|
||||
cascadeMinNeighbors = toInt(prop.getProperty("cascadeMinNeighbors"));
|
||||
cascadeMinSize = toInt(prop.getProperty("cascadeMinSize"));
|
||||
cascadeMaxSize = toInt(prop.getProperty("cascadeMaxSize"));
|
||||
|
||||
Detectors.setFaceMaxSize(cascadeMaxSize);
|
||||
Detectors.setFaceMinSize(cascadeMinSize);
|
||||
Detectors.setScaleFactor(cascadeScaleFactor);
|
||||
|
||||
Logger.info("Config Loaded");
|
||||
MakeDirectories();
|
||||
return;
|
||||
} else {
|
||||
Logger.info("Config File Not Correct, Creating Default");
|
||||
@@ -568,6 +616,14 @@ public class ConfigFile {
|
||||
CreateDefault();
|
||||
}
|
||||
|
||||
private double toDouble(String cascadeScaleFactor) {
|
||||
try{
|
||||
return Double.parseDouble(cascadeScaleFactor);
|
||||
} catch (Exception e){
|
||||
return 1.1;
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateDefault(){
|
||||
AudioPhase1 = Path.of(currentDirectory, "audio", "phase1.mp3").toString();
|
||||
AudioPhase2 = Path.of(currentDirectory, "audio", "phase2.mp3").toString();
|
||||
@@ -590,9 +646,17 @@ public class ConfigFile {
|
||||
SetDefaultCameraConfig(ConfigCenter);
|
||||
SetDefaultCameraConfig(ConfigRight45);
|
||||
SetDefaultCameraConfig(ConfigRight90);
|
||||
cascadeScaleFactor = 1.1;
|
||||
cascadeMinNeighbors = 3;
|
||||
cascadeMinSize = 250;
|
||||
cascadeMaxSize = 500;
|
||||
Detectors.setFaceMaxSize(cascadeMaxSize);
|
||||
Detectors.setFaceMinSize(cascadeMinSize);
|
||||
Detectors.setScaleFactor(cascadeScaleFactor);
|
||||
Logger.info("Default Config Created");
|
||||
needsave = true;
|
||||
Save();
|
||||
MakeDirectories();
|
||||
}
|
||||
|
||||
private void SetDefaultCameraConfig(CameraConfig cc){
|
||||
@@ -640,6 +704,11 @@ public class ConfigFile {
|
||||
prop.setProperty(CameraConfigEnum.CameraConfigRight45.toString(), gson.toJson(ConfigRight45));
|
||||
prop.setProperty(CameraConfigEnum.CameraConfigRight90.toString(), gson.toJson(ConfigRight90));
|
||||
|
||||
prop.setProperty("cascadeScaleFactor", String.valueOf(cascadeScaleFactor));
|
||||
prop.setProperty("cascadeMinNeighbors", String.valueOf(cascadeMinNeighbors));
|
||||
prop.setProperty("cascadeMinSize", String.valueOf(cascadeMinSize));
|
||||
prop.setProperty("cascadeMaxSize", String.valueOf(cascadeMaxSize));
|
||||
|
||||
try{
|
||||
prop.store(new FileOutputStream(Path.of(currentDirectory, "config.properties").toString()), null);
|
||||
Logger.info("Config Saved");
|
||||
@@ -647,4 +716,23 @@ public class ConfigFile {
|
||||
Logger.error("Error Save Config: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private @Getter String FullQualityDirectory;
|
||||
private @Getter String FullQualityCropDirectory;
|
||||
private @Getter String CompressedDirectory;
|
||||
private @Getter String CompressedCropDirectory;
|
||||
private @Getter String ThumbsDirectory;
|
||||
|
||||
private void MakeDirectories(){
|
||||
FullQualityDirectory = Path.of(PhotoDirectory,"FullQuality").toString();
|
||||
FullQualityCropDirectory = Path.of(PhotoDirectory,"FullQualityCrop").toString();
|
||||
CompressedDirectory = Path.of(PhotoDirectory,"Compressed").toString();
|
||||
CompressedCropDirectory = Path.of(PhotoDirectory,"CompressedCrop").toString();
|
||||
ThumbsDirectory = Path.of(PhotoDirectory,"thumbs").toString();
|
||||
MakeDirectory(FullQualityDirectory);
|
||||
MakeDirectory(FullQualityCropDirectory);
|
||||
MakeDirectory(CompressedDirectory);
|
||||
MakeDirectory(CompressedCropDirectory);
|
||||
MakeDirectory(ThumbsDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,15 +4,17 @@ package Config;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.zxing.MultiFormatReader;
|
||||
import javafx.embed.swing.SwingFXUtils;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.image.Image;
|
||||
import lombok.val;
|
||||
import org.bytedeco.javacv.Java2DFrameConverter;
|
||||
import org.bytedeco.javacv.OpenCVFrameConverter;
|
||||
import org.bytedeco.opencv.global.opencv_core;
|
||||
import org.bytedeco.opencv.global.opencv_imgcodecs;
|
||||
import org.bytedeco.opencv.global.opencv_imgproc;
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
import org.bytedeco.opencv.opencv_core.Rect;
|
||||
import org.bytedeco.opencv.opencv_core.Size;
|
||||
import org.bytedeco.opencv.opencv_objdetect.CascadeClassifier;
|
||||
import org.bytedeco.opencv.opencv_core.UMat;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
@@ -28,6 +30,8 @@ import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.bytedeco.opencv.global.opencv_core.CV_64F;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class SomeCodes {
|
||||
public final static String currentDirectory = System.getProperty("user.dir");
|
||||
@@ -37,6 +41,10 @@ public class SomeCodes {
|
||||
public static final Gson gson = new Gson();
|
||||
public static final ConfigFile config = new ConfigFile();
|
||||
|
||||
public static String GetDateTimeString(){
|
||||
return LocalDateTime.now().format(dtf);
|
||||
}
|
||||
|
||||
public static Path GetLogsPath(){
|
||||
return Path.of(currentDirectory, "logs");
|
||||
}
|
||||
@@ -94,6 +102,14 @@ public class SomeCodes {
|
||||
|
||||
}
|
||||
|
||||
public static String RectToString(Rect rect){
|
||||
if (rect!=null){
|
||||
return "X:"+rect.x()+",Y:"+rect.y()+",W:"+rect.width()+",H:"+rect.height();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find thumbfile in thumbs directory
|
||||
* @param sourcejpg source jpg file
|
||||
@@ -101,12 +117,7 @@ public class SomeCodes {
|
||||
*/
|
||||
public static String FindThumbfile(String sourcejpg){
|
||||
File sourcefile = new File(sourcejpg);
|
||||
Path thumbpath = Path.of(sourcefile.getParent(), "thumbs");
|
||||
try{
|
||||
if (!Files.exists(thumbpath)) Files.createDirectories(thumbpath);
|
||||
} catch (Exception e){
|
||||
Logger.error("Error creating thumbs directory: "+thumbpath+", Msg : "+e.getMessage());
|
||||
}
|
||||
Path thumbpath = Path.of(config.getThumbsDirectory());
|
||||
Path thumbfile = thumbpath.resolve(sourcefile.getName());
|
||||
if (Files.exists(thumbfile)){
|
||||
return thumbfile.toString();
|
||||
@@ -114,6 +125,14 @@ public class SomeCodes {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void Wait(int millis){
|
||||
try{
|
||||
Thread.sleep(millis);
|
||||
} catch (Exception e){
|
||||
Logger.error("Error waiting: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make thumbfile from source jpg file
|
||||
* @param sourcejpg source jpg file
|
||||
@@ -124,23 +143,22 @@ public class SomeCodes {
|
||||
try{
|
||||
File ff = new File(sourcejpg);
|
||||
if (ff.exists()){
|
||||
Path thumbpath = Path.of(ff.getParent(), "thumbs");
|
||||
if (!Files.exists(thumbpath)) Files.createDirectories(thumbpath);
|
||||
String thumbfile = thumbpath.resolve(ff.getName()).toString();
|
||||
String thumbfile = Path.of(config.getPhotoDirectory(),"thumbs", ff.getName()).toString();
|
||||
File thumb = new File(thumbfile);
|
||||
if (thumb.exists()) return thumbfile;
|
||||
if (thumb.exists()) {
|
||||
return thumbfile;
|
||||
}
|
||||
|
||||
Mat source = opencv_imgcodecs.imread(sourcejpg);
|
||||
if (source!=null && !source.empty()){
|
||||
Mat resized = new Mat();
|
||||
opencv_imgproc.resize(source, resized, thumbsize);
|
||||
opencv_imgcodecs.imwrite(thumbfile, resized);
|
||||
Logger.info("Thumbfile created: "+thumbfile);
|
||||
return thumbfile;
|
||||
} else Logger.info("MakeThumbfile failed, Source File not valid image : "+sourcejpg);
|
||||
} else Logger.info("MakeThumbfile failed, Source File not found: "+sourcejpg);
|
||||
}
|
||||
}
|
||||
} catch (Exception e){
|
||||
Logger.error("Error making thumbfile: "+sourcejpg+", Msg : "+e.getMessage());
|
||||
System.out.println("Error making thumbfile: "+sourcejpg+", Msg : "+e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -153,6 +171,11 @@ public class SomeCodes {
|
||||
return x.format(dtf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract resource file to current directory
|
||||
* @param filename resource file name
|
||||
* @return extracted file path if success, or null if failed
|
||||
*/
|
||||
public static String ExtractResource(String filename){
|
||||
try{
|
||||
File destination = new File(currentDirectory, filename);
|
||||
@@ -171,6 +194,11 @@ public class SomeCodes {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if path is valid directory
|
||||
* @param path directory path
|
||||
* @return true if valid directory, false if not valid directory
|
||||
*/
|
||||
public static boolean ValidDirectory(String path){
|
||||
if (ValidString(path)){
|
||||
File ff = new File(path);
|
||||
@@ -179,10 +207,20 @@ public class SomeCodes {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if port number is valid
|
||||
* @param port port number
|
||||
* @return true if valid port number, false if not valid port number
|
||||
*/
|
||||
public static boolean ValidPortNumber(int port){
|
||||
return port>0 && port<65536;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert string to integer
|
||||
* @param x string
|
||||
* @return integer value if success, or 0 if failed
|
||||
*/
|
||||
public static int toInt(String x){
|
||||
try {
|
||||
return Integer.parseInt(x);
|
||||
@@ -191,6 +229,11 @@ public class SomeCodes {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if string is valid IPV4 address
|
||||
* @param ipaddress IPV4 address
|
||||
* @return true if valid IPV4 address, false if not valid IPV4 address
|
||||
*/
|
||||
public static boolean ValidIPV4(String ipaddress){
|
||||
if (ValidString(ipaddress)){
|
||||
try{
|
||||
@@ -206,6 +249,11 @@ public class SomeCodes {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if string is valid IPV6 address
|
||||
* @param ipaddress IPV6 address
|
||||
* @return true if valid IPV6 address, false if not valid IPV6 address
|
||||
*/
|
||||
public static boolean ValidIPV6(String ipaddress){
|
||||
if (ValidString(ipaddress)){
|
||||
try{
|
||||
@@ -221,6 +269,11 @@ public class SomeCodes {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file name from file path
|
||||
* @param filepath file path
|
||||
* @return file name if success, or empty string if failed
|
||||
*/
|
||||
public static String GetFileName(String filepath){
|
||||
if (ValidString(filepath)){
|
||||
File ff = new File(filepath);
|
||||
@@ -231,6 +284,11 @@ public class SomeCodes {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if string is valid file
|
||||
* @param filename file name
|
||||
* @return true if valid file, false if not valid file
|
||||
*/
|
||||
public static boolean ValidFile(String filename){
|
||||
if (ValidString(filename)){
|
||||
File ff = new File(filename);
|
||||
@@ -239,6 +297,113 @@ public class SomeCodes {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read file as byte array
|
||||
* @param filename file name
|
||||
* @return byte array if success, or null if failed
|
||||
*/
|
||||
public static byte[] ReadFile(String filename){
|
||||
if (ValidFile(filename)){
|
||||
try{
|
||||
return Files.readAllBytes(Path.of(filename));
|
||||
} catch (Exception e){
|
||||
Logger.error("Error reading file: "+filename+", Msg : "+e.getMessage());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Resize Rect
|
||||
* @param original original Rect
|
||||
* @param scaleX scale factor
|
||||
* @param scaleY scale factor
|
||||
* @param Xoffset X offset, positive value to increase width, negative value to decrease width
|
||||
* @param Yoffset Y offset, positive value to increase height, negative value to decrease height
|
||||
* @return resized Rect if success, or null if failed
|
||||
*/
|
||||
public static Rect ResizeRect(Rect original, double scaleX, double scaleY, int Xoffset, int Yoffset){
|
||||
if (original!=null){
|
||||
int newX = (int)(original.x()*scaleX);
|
||||
newX -= Xoffset;
|
||||
if (newX<0) newX = 0;
|
||||
int newY = (int)(original.y()*scaleY);
|
||||
newY -= Yoffset;
|
||||
if (newY<0) newY = 0;
|
||||
int newWidth = (int)(original.width()*scaleX);
|
||||
newWidth += Xoffset*2;
|
||||
int newHeight = (int)(original.height()*scaleX);
|
||||
newHeight += Yoffset*2;
|
||||
return new Rect(newX, newY, newWidth, newHeight);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static UMat CropUMat(UMat source, Rect ROI){
|
||||
if (source!=null && !source.empty() && ValidROI(ROI)){
|
||||
int x = ROI.x();
|
||||
int y = ROI.y();
|
||||
int width = ROI.width();
|
||||
int height = ROI.height();
|
||||
|
||||
if (x>=0 && y>=0 && width>0 && height>0){
|
||||
if (x+width>source.cols()) width = source.cols()-x;
|
||||
if (y+height>source.rows()) height = source.rows()-y;
|
||||
if (width>0 && height>0){
|
||||
Rect crop = new Rect(x, y, width, height);
|
||||
return new UMat(source, crop);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean Save(UMat source, String filename, int[] param){
|
||||
if (source!=null && !source.empty() && ValidString(filename)){
|
||||
try{
|
||||
return opencv_imgcodecs.imwrite(filename, source, param);
|
||||
} catch (Exception e){
|
||||
Logger.error("Error saving file: "+filename+", Msg : "+e.getMessage());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenate byte arrays
|
||||
* @param args byte arrays
|
||||
* @return concatenated byte array if success, or null if failed
|
||||
*/
|
||||
public static byte[] Concat(byte[]... args){
|
||||
if (args!=null && args.length>0){
|
||||
int total = 0;
|
||||
for(byte[] x : args){
|
||||
if (x!=null && x.length>0){
|
||||
total += x.length;
|
||||
}
|
||||
}
|
||||
if (total>0){
|
||||
byte[] result = new byte[total];
|
||||
int offset = 0;
|
||||
for(byte[] x : args){
|
||||
if (x!=null && x.length>0){
|
||||
System.arraycopy(x, 0, result, offset, x.length);
|
||||
offset += x.length;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if string is valid
|
||||
* @param x string
|
||||
* @return true if valid, false if not valid
|
||||
*/
|
||||
public static boolean ValidString(String x){
|
||||
if (x!=null){
|
||||
return !x.isEmpty();
|
||||
@@ -246,6 +411,10 @@ public class SomeCodes {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open picture in default viewer
|
||||
* @param filename picture file name
|
||||
*/
|
||||
public static void OpenPictureInDefaultViewer(String filename){
|
||||
try{
|
||||
File ff = new File(filename);
|
||||
@@ -275,20 +444,16 @@ public class SomeCodes {
|
||||
}
|
||||
|
||||
}
|
||||
public static CascadeClassifier faceDetector;
|
||||
public static void LoadFaceDetector(){
|
||||
String filename = SomeCodes.ExtractResource("/haarcascade_frontalface_alt.xml");
|
||||
if (filename!=null) {
|
||||
if (faceDetector==null) {
|
||||
faceDetector = new CascadeClassifier(filename);
|
||||
Logger.info("FaceDetector loaded");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make array from string arguments
|
||||
* @param args string arguments
|
||||
* @return array of strings if success, or empty array if failed
|
||||
*/
|
||||
public static String[] MakeArray(String... args){
|
||||
if (args!=null && args.length>0){
|
||||
List<String> ll = new ArrayList<String>();
|
||||
List<String> ll = new ArrayList<>();
|
||||
for(String x : args){
|
||||
if (ValidString(x)) ll.add(x);
|
||||
}
|
||||
@@ -297,8 +462,193 @@ public class SomeCodes {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
public static boolean ValidBarCode(String value){
|
||||
if (value!=null && value.length()==10){
|
||||
boolean valid = true;
|
||||
for(int i=0; i<value.length(); i++){
|
||||
if (!Character.isDigit(value.charAt(i))){
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Valid PatientID found
|
||||
* Patient ID is 10 digits number
|
||||
* @param patientid Patient ID
|
||||
* @return true if valid, false if not valid
|
||||
*/
|
||||
public static boolean ValidMedicalRecordId(String patientid){
|
||||
if (patientid!=null && !patientid.isEmpty()){
|
||||
boolean valid = true;
|
||||
for(int i=0; i<patientid.length(); i++){
|
||||
if (!Character.isDigit(patientid.charAt(i))){
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return valid;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Region of Interest is a valid Rect
|
||||
* @param ROI Region of Interest
|
||||
* @return true if valid, false if not valid
|
||||
*/
|
||||
public static boolean ValidROI(Rect ROI){
|
||||
if (ROI!=null){
|
||||
if (ROI.x()>=0){
|
||||
if (ROI.y()>=0){
|
||||
if (ROI.width()>0){
|
||||
if (ROI.height()>0){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void Print(String... x){
|
||||
if (x!=null && x.length>0){
|
||||
for(String xx : x){
|
||||
System.out.println(xx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Region of Interest is inside UMat
|
||||
* @param ROI Region of Interest
|
||||
* @param mat UMat
|
||||
* @return true if inside, false if not inside
|
||||
*/
|
||||
public static boolean ROIInsideUMat(Rect ROI, UMat mat){
|
||||
if (ValidROI(ROI)){
|
||||
if (mat!=null){
|
||||
return ROI.x()>=0 && ROI.y()>=0 &&
|
||||
ROI.x()+ROI.width()<=mat.cols() &&
|
||||
ROI.y()+ROI.height()<=mat.rows();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Region of Interest 1 is same with Region of Interest 2
|
||||
* @param ROI1 Region of Interest 1
|
||||
* @param ROI2 Region of Interest 2
|
||||
* @return true if same, false if not same
|
||||
*/
|
||||
public static boolean IsSameROI(Rect ROI1, Rect ROI2){
|
||||
if (ValidROI(ROI1) && ValidROI(ROI2)){
|
||||
return ROI1.x()==ROI2.x() && ROI1.y()==ROI2.y() &&
|
||||
ROI1.width()==ROI2.width() && ROI1.height()==ROI2.height();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Rect 1 is inside Rect 2
|
||||
* @param smaller Rect 1
|
||||
* @param bigger Rect 2
|
||||
* @return true if inside, false if not inside
|
||||
*/
|
||||
public static boolean IsInsideRect(Rect smaller, Rect bigger){
|
||||
if (smaller!=null && bigger!=null){
|
||||
return smaller.x()>=bigger.x() && smaller.y()>=bigger.y() &&
|
||||
smaller.x()+smaller.width()<=bigger.x()+bigger.width() &&
|
||||
smaller.y()+smaller.height()<=bigger.y()+bigger.height();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make directory if not exists
|
||||
* @param path directory path
|
||||
*/
|
||||
public static void MakeDirectory(String path){
|
||||
if (ValidString(path)){
|
||||
File ff = new File(path);
|
||||
if (!ff.isDirectory()){
|
||||
try{
|
||||
Files.createDirectories(ff.toPath());
|
||||
Logger.info("Directory created: "+path);
|
||||
} catch (Exception e){
|
||||
Logger.info("Error creating directory: "+path+", Msg : "+e.getMessage());
|
||||
}
|
||||
} else Logger.info("Directory exists: "+path);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static short ToShort(String x){
|
||||
try{
|
||||
return Short.parseShort(x);
|
||||
} catch (Exception e){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static void ShowAlert(Alert.AlertType type, String title, String header, String content){
|
||||
Alert alert = new Alert(type);
|
||||
alert.setTitle(title);
|
||||
alert.setHeaderText(header);
|
||||
alert.setContentText(content);
|
||||
alert.showAndWait();
|
||||
}
|
||||
|
||||
public static double CalculateSharpness(String filename){
|
||||
if (ValidFile(filename)){
|
||||
try(Mat mat = opencv_imgcodecs.imread(filename)){
|
||||
return CalculateSharpness(new UMat(mat));
|
||||
} catch (Exception e){
|
||||
Logger.error("Error calculating sharpness: "+filename+", Msg : "+e.getMessage());
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static double FindLowestValue(double... values){
|
||||
if (values!=null && values.length>0){
|
||||
double lowest = values[0];
|
||||
for(double x : values){
|
||||
if (x<lowest){
|
||||
lowest = x;
|
||||
}
|
||||
}
|
||||
return lowest;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static double CalculateSharpness(UMat mat){
|
||||
if (mat!=null && !mat.empty()){
|
||||
UMat gray = new UMat();
|
||||
opencv_imgproc.cvtColor(mat, gray, opencv_imgproc.COLOR_BGR2GRAY);
|
||||
UMat laplacian = new UMat();
|
||||
|
||||
opencv_imgproc.Laplacian(gray, laplacian, CV_64F);
|
||||
UMat mean = new UMat(1,1, CV_64F);
|
||||
UMat stddev = new UMat(1,1, CV_64F);
|
||||
opencv_core.meanStdDev(laplacian, mean, stddev);
|
||||
|
||||
Mat _std = new Mat();
|
||||
stddev.copyTo(_std);
|
||||
|
||||
return _std.ptr(0).getDouble() * _std.ptr(0).getDouble();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static boolean IsBlurred(UMat mat, double threshold){
|
||||
return CalculateSharpness(mat)<threshold;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,10 +10,25 @@ public class PhotoReviewClass {
|
||||
private String DateTime;
|
||||
private String Prefix;
|
||||
private String FileLeft90;
|
||||
private String CompressedLeft90;
|
||||
private String CroppedLeft90;
|
||||
private String CompressedCropLeft90;
|
||||
private String FileLeft45;
|
||||
private String CompressedLeft45;
|
||||
private String CroppedLeft45;
|
||||
private String CompressedCropLeft45;
|
||||
private String FileCenter;
|
||||
private String CompressedCenter;
|
||||
private String CroppedCenter;
|
||||
private String CompressedCropCenter;
|
||||
private String FileRight45;
|
||||
private String CompressedRight45;
|
||||
private String CroppedRight45;
|
||||
private String CompressedCropRight45;
|
||||
private String FileRight90;
|
||||
private String CompressedRight90;
|
||||
private String CroppedRight90;
|
||||
private String CompressedCropRight90;
|
||||
private String ThumbLeft90;
|
||||
private String ThumbLeft45;
|
||||
private String ThumbCenter;
|
||||
@@ -52,16 +67,49 @@ public class PhotoReviewClass {
|
||||
this.ThumbRight90 = ThumbRight90;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "id: "+id+"\r\nDateTime: "+DateTime+"\r\nPrefix: "+Prefix+"\r\nFileLeft90: "+FileLeft90+"\r\nFileLeft45: "+FileLeft45+"\r\nFileCenter: "+FileCenter+"\r\nFileRight45: "+FileRight45+"\r\nFileRight90: "+FileRight90+"\r\nThumbLeft90: "+ThumbLeft90+"\r\nThumbLeft45: "+ThumbLeft45+"\r\nThumbCenter: "+ThumbCenter+"\r\nThumbRight45: "+ThumbRight45+"\r\nThumbRight90: "+ThumbRight90;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all files that are not null
|
||||
* Get all Full Resolution files that are not null
|
||||
* @return array of files
|
||||
*/
|
||||
public String[] files(){
|
||||
public String[] fullres(){
|
||||
return MakeArray(FileLeft90, FileLeft45, FileCenter, FileRight45, FileRight90);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all Thumbnail files that are not null
|
||||
* @return array of files
|
||||
*/
|
||||
public String[] thumbnails(){
|
||||
return MakeArray(ThumbLeft90, ThumbLeft45, ThumbCenter, ThumbRight45, ThumbRight90);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all Compressed files that are not null
|
||||
* @return array of files
|
||||
*/
|
||||
public String[] compressed(){
|
||||
return MakeArray(CompressedLeft90, CompressedLeft45, CompressedCenter, CompressedRight45, CompressedRight90);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all Cropped full resolution files that are not null
|
||||
* @return array of files
|
||||
*/
|
||||
public String[] cropped(){
|
||||
return MakeArray(CroppedLeft90, CroppedLeft45, CroppedCenter, CroppedRight45, CroppedRight90);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all Cropped compressed files that are not null
|
||||
* @return array of files
|
||||
*/
|
||||
public String[] compressedcrop(){
|
||||
return MakeArray(CompressedCropLeft90, CompressedCropLeft45, CompressedCropCenter, CompressedCropRight45, CompressedCropRight90);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package Database;
|
||||
import static Config.SomeCodes.LocalDateTimeToString;
|
||||
import static Config.SomeCodes.ValidString;
|
||||
|
||||
import lombok.val;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.sql.*;
|
||||
@@ -41,6 +40,8 @@ public class Sqlite {
|
||||
*/
|
||||
public void Insert(PhotoReviewClass pr){
|
||||
if (pr!=null){
|
||||
// System.out.println("Inserting PhotoReviewClass");
|
||||
// System.out.println(pr);
|
||||
Insert(pr.getPrefix(), pr.getFileLeft90(), pr.getFileLeft45(), pr.getFileCenter(), pr.getFileRight45(), pr.getFileRight90(), pr.getThumbLeft90(), pr.getThumbLeft45(), pr.getThumbCenter(), pr.getThumbRight45(), pr.getThumbRight90());
|
||||
}
|
||||
}
|
||||
@@ -107,6 +108,13 @@ public class Sqlite {
|
||||
try{
|
||||
Connection conn = GetConnection();
|
||||
if (conn != null){
|
||||
// System.out.println("Inserting data");
|
||||
// System.out.println("prefix: "+prefix);
|
||||
// System.out.println("fileLeft90: "+fileLeft90);
|
||||
// System.out.println("fileLeft45: "+fileLeft45);
|
||||
// System.out.println("fileCenter: "+fileCenter);
|
||||
// System.out.println("fileRight45: "+fileRight45);
|
||||
// System.out.println("fileRight90: "+fileRight90);
|
||||
|
||||
PreparedStatement stmt = conn.prepareStatement("INSERT INTO photos (DateTime, Prefix, FileLeft90, FileLeft45, FileCenter, FileRight45, FileRight90, ThumbLeft90, ThumbLeft45, ThumbCenter, ThumbRight45, ThumbRight90 ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
stmt.setString(1, LocalDateTimeToString(LocalDateTime.now()));
|
||||
|
||||
29
src/main/java/ErhaAPI/BarcodeResullt.java
Normal file
29
src/main/java/ErhaAPI/BarcodeResullt.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package ErhaAPI;
|
||||
|
||||
|
||||
public class BarcodeResullt {
|
||||
public int currentPage;
|
||||
public int limit;
|
||||
public int totalPages;
|
||||
public int totalRecords;
|
||||
public String message;
|
||||
public boolean error;
|
||||
public String errorId;
|
||||
public String errorMessage;
|
||||
public String errorCode;
|
||||
public PatientRecord[] data;
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("currentPage : ").append(currentPage).append(", limit : ").append(limit).append(", totalPages : ").append(totalPages).append(", totalRecords : ").append(totalRecords).append(", message : ").append(message).append(", error : ").append(error);
|
||||
if (data != null){
|
||||
sb.append(", data : [");
|
||||
for (PatientRecord pr : data){
|
||||
sb.append(pr.toString()).append(", ");
|
||||
}
|
||||
sb.append("]");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
195
src/main/java/ErhaAPI/ErhaAPI.java
Normal file
195
src/main/java/ErhaAPI/ErhaAPI.java
Normal file
@@ -0,0 +1,195 @@
|
||||
package ErhaAPI;
|
||||
|
||||
import Config.SomeCodes;
|
||||
import com.google.gson.Gson;
|
||||
import lombok.Getter;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Base64;
|
||||
import java.util.UUID;
|
||||
|
||||
import static Config.SomeCodes.*;
|
||||
|
||||
|
||||
public class ErhaAPI {
|
||||
private @Getter String API_USERNAME = "erha-pb-001";
|
||||
private @Getter String API_PASSWORD = "bM0tH!s";
|
||||
|
||||
|
||||
|
||||
private String auth;
|
||||
private final String API_URL;
|
||||
|
||||
private final Gson gson = new Gson();
|
||||
|
||||
/**
|
||||
* Create Erha API object
|
||||
* @param isProduction if true will use Production URL, if false will use Staging URL
|
||||
*/
|
||||
public ErhaAPI(boolean isProduction){
|
||||
final String API_URL_PROD = "https://connect-api.aryanoble.co.id/api";
|
||||
final String API_URL_STAGING = "https://connect-api-staging.aryanoble.web.id/api";
|
||||
API_URL = isProduction ? API_URL_PROD : API_URL_STAGING;
|
||||
update_auth();
|
||||
}
|
||||
/**
|
||||
* Set API Username
|
||||
* @param API_USERNAME API Username
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public void setAPI_USERNAME(String API_USERNAME){
|
||||
if (ValidString(API_USERNAME)){
|
||||
if (!API_USERNAME.equals(this.API_USERNAME)){
|
||||
this.API_USERNAME = API_USERNAME;
|
||||
update_auth();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set API Password
|
||||
* @param API_PASSWORD API Password
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public void setAPI_PASSWORD(String API_PASSWORD){
|
||||
if (ValidString(API_PASSWORD)){
|
||||
if (!API_PASSWORD.equals(this.API_PASSWORD)){
|
||||
this.API_PASSWORD = API_PASSWORD;
|
||||
update_auth();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate Barcode data
|
||||
* @param Barcode Barcode to verify
|
||||
* @return BarcodeResullt object if success, or null if failed
|
||||
*/
|
||||
public BarcodeResullt Validate_Barcode(String Barcode, boolean printdebug){
|
||||
if (ValidBarCode(Barcode)){
|
||||
|
||||
try (HttpClient client = HttpClient.newHttpClient()) {
|
||||
int medical_record_detail_id = toInt(Barcode);
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(java.net.URI.create(API_URL+"/photobooth/photobooth/" + medical_record_detail_id))
|
||||
.header("Authorization", "Basic " + auth)
|
||||
.GET()
|
||||
.build();
|
||||
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
if (response.statusCode()==200){
|
||||
String body = response.body();
|
||||
if (printdebug){
|
||||
System.out.println("Validate_Barcode status code : " + response.statusCode());
|
||||
System.out.println("Validate_Barcode HTTP body : ");
|
||||
System.out.println(body);
|
||||
}
|
||||
return gson.fromJson(body, BarcodeResullt.class);
|
||||
} else {
|
||||
Logger.error("Validate_Barcode failed, status code : " , response.statusCode());
|
||||
System.out.println("Validate Barcode status code : " + response.statusCode());
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
System.out.println("Validate_Barcode IO Exception, Msg : " + e.getMessage());
|
||||
Logger.error("Validate_Barcode IO Exception, Msg : " , e.getMessage());
|
||||
} catch (InterruptedException e) {
|
||||
System.out.println("Validate_Barcode Interrupted Exception, Msg : " + e.getMessage());
|
||||
Logger.error("Validate_Barcode Interrupted Exception, Msg : " , e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Upload File
|
||||
* @param patientID Patient ID
|
||||
* @param filename File to upload
|
||||
* @return null if failed, or response body if success
|
||||
*/
|
||||
public UploadResult Upload_File(String patientID, String filename, boolean printdebug) {
|
||||
if (ValidMedicalRecordId(patientID)){
|
||||
int medical_record_detail_id = toInt(patientID);
|
||||
if (ValidFile(filename)){
|
||||
File ff = new File(filename);
|
||||
try (HttpClient client = HttpClient.newHttpClient()){
|
||||
byte[] fileBytes = Files.readAllBytes(new java.io.File(filename).toPath());
|
||||
String fn = ff.getName();
|
||||
// Unique boundary for multipart data
|
||||
String boundary = "----JavaHttpClientBoundary" + UUID.randomUUID();
|
||||
String CRLF = "\r\n";
|
||||
|
||||
// Form Data (Text Field)
|
||||
String formData1 = "--" + boundary + CRLF +
|
||||
"Content-Disposition: form-data; name=\"medical_record_detail_id\"" + CRLF + CRLF +
|
||||
medical_record_detail_id + CRLF;
|
||||
|
||||
// Form Data (File)
|
||||
String formData2 = "--" + boundary + CRLF +
|
||||
"Content-Disposition: form-data; name=\"file\"; filename=\"" + fn + "\"" + CRLF +
|
||||
"Content-Type: image/jpeg" + CRLF + CRLF; // Change Content-Type accordingly
|
||||
|
||||
// End Boundary
|
||||
String endBoundary = CRLF + "--" + boundary + "--" + CRLF;
|
||||
|
||||
// Combine all parts into a single byte array
|
||||
byte[] multipartData = SomeCodes.Concat(
|
||||
formData1.getBytes(),
|
||||
formData2.getBytes(),
|
||||
fileBytes,
|
||||
endBoundary.getBytes()
|
||||
);
|
||||
|
||||
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(new URI(API_URL + "/photobooth/photobooth"))
|
||||
.header("Authorization", "Basic " + auth)
|
||||
.header("Content-Type", "multipart/form-data; boundary=" + boundary)
|
||||
.POST(HttpRequest.BodyPublishers.ofByteArray(multipartData))
|
||||
.build();
|
||||
|
||||
// Send request
|
||||
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
|
||||
if (printdebug){
|
||||
System.out.println("Upload_File status code : " + response.statusCode());
|
||||
System.out.println("Upload_File HTTP body : ");
|
||||
System.out.println(response.body());
|
||||
}
|
||||
|
||||
|
||||
if (response.statusCode()==200){
|
||||
return gson.fromJson(response.body(), UploadResult.class);
|
||||
|
||||
} else {
|
||||
System.out.println("Upload_File status code : " + response.statusCode());
|
||||
Logger.error("Upload_File file ",filename," failed, status code : " , response.statusCode());
|
||||
}
|
||||
|
||||
|
||||
} catch (Exception e){
|
||||
System.out.println("Upload_File Exception, Msg : " + e.getMessage());
|
||||
Logger.error("Upload_File file ",filename," failed, Exception, Msg : " , e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private void update_auth(){
|
||||
auth = Base64.getEncoder().encodeToString((API_USERNAME + ":" + API_PASSWORD).getBytes());
|
||||
}
|
||||
|
||||
}
|
||||
23
src/main/java/ErhaAPI/PatientRecord.java
Normal file
23
src/main/java/ErhaAPI/PatientRecord.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package ErhaAPI;
|
||||
|
||||
public class PatientRecord {
|
||||
public String medical_record_detail_id;
|
||||
public String medical_staff_id;
|
||||
public String medical_staff_name;
|
||||
public String branch_id;
|
||||
public String branch_code;
|
||||
public String branch_name;
|
||||
public String registration_id;
|
||||
public String registration_date;
|
||||
public String patient_id;
|
||||
public String mrnl;
|
||||
public String name;
|
||||
public String phone;
|
||||
public String birthdate;
|
||||
public String service;
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "medical_record_detail_id : " + medical_record_detail_id + ", medical_staff_id : " + medical_staff_id + ", medical_staff_name : " + medical_staff_name + ", branch_id : " + branch_id + ", branch_code : " + branch_code + ", branch_name : " + branch_name + ", registration_id : " + registration_id + ", registration_date : " + registration_date + ", patient_id : " + patient_id + ", mrnl : " + mrnl + ", name : " + name + ", phone : " + phone + ", birthdate : " + birthdate + ", service : " + service;
|
||||
}
|
||||
}
|
||||
48
src/main/java/ErhaAPI/PhotoResult.java
Normal file
48
src/main/java/ErhaAPI/PhotoResult.java
Normal file
@@ -0,0 +1,48 @@
|
||||
package ErhaAPI;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bytedeco.opencv.opencv_core.Rect;
|
||||
|
||||
@Getter @Setter
|
||||
public class PhotoResult {
|
||||
private final String cameraname;
|
||||
private String fullres;
|
||||
private String compressedfile;
|
||||
private String fullcrop;
|
||||
private String compressedcrop;
|
||||
private String thumbnail;
|
||||
private Rect BestROI;
|
||||
private Rect ReducedROI;
|
||||
private double sharpscore;
|
||||
public PhotoResult(String cameraname){
|
||||
this.cameraname = cameraname;
|
||||
this.fullres = "";
|
||||
this.compressedfile = "";
|
||||
this.fullcrop = "";
|
||||
this.compressedcrop = "";
|
||||
this.thumbnail = "";
|
||||
this.BestROI = null;
|
||||
this.ReducedROI = null;
|
||||
}
|
||||
public PhotoResult(String cameraname,String fullres, String compressedfile, String fullcrop, String compressedcrop, String thumbnail){
|
||||
this.cameraname = cameraname;
|
||||
this.fullres = fullres;
|
||||
this.compressedfile = compressedfile;
|
||||
this.fullcrop = fullcrop;
|
||||
this.compressedcrop = compressedcrop;
|
||||
this.thumbnail = thumbnail;
|
||||
this.BestROI = null;
|
||||
this.ReducedROI = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "Camera Name: " + cameraname + "\n" +
|
||||
"Full Resolution: " + fullres + "\n" +
|
||||
"Compressed File: " + compressedfile + "\n" +
|
||||
"Full Crop: " + fullcrop + "\n" +
|
||||
"Compressed Crop: " + compressedcrop + "\n" +
|
||||
"Thumbnail: " + thumbnail + "\n";
|
||||
}
|
||||
}
|
||||
18
src/main/java/ErhaAPI/UploadResult.java
Normal file
18
src/main/java/ErhaAPI/UploadResult.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package ErhaAPI;
|
||||
|
||||
public class UploadResult {
|
||||
public int currentPage;
|
||||
public int limit;
|
||||
public int totalPages;
|
||||
public int totalRecords;
|
||||
public boolean error;
|
||||
public String errorId;
|
||||
public String errorMessage;
|
||||
public String errorCode;
|
||||
public String message;
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "message : " + message + ", error : " + error + ", errorId : " + errorId + ", errorMessage : " + errorMessage + ", errorCode : " + errorCode ;
|
||||
}
|
||||
}
|
||||
107
src/main/java/SecureDongle/LibSecureDongle.java
Normal file
107
src/main/java/SecureDongle/LibSecureDongle.java
Normal file
@@ -0,0 +1,107 @@
|
||||
package SecureDongle;
|
||||
|
||||
import com.sun.jna.Library;
|
||||
import com.sun.jna.Native;
|
||||
|
||||
public interface LibSecureDongle extends Library {
|
||||
LibSecureDongle Instance = (LibSecureDongle) Native.load("SecureDongleJ", LibSecureDongle.class);
|
||||
short SD_FIND=1;
|
||||
short SD_FIND_NEXT=2;
|
||||
short SD_OPEN=3;
|
||||
short SD_CLOSE=4;
|
||||
short SD_READ=5;
|
||||
short SD_WRITE=6;
|
||||
short SD_RANDOM=7;
|
||||
short SD_SEED=8;
|
||||
short SD_WRITE_USERID=9;
|
||||
short SD_READ_USERID=10;
|
||||
short SD_SET_MODULE=11;
|
||||
short SD_CHECK_MODULE=12;
|
||||
short SD_WRITE_ARITHMETIC=13;
|
||||
short SD_CALCULATE1=14;
|
||||
short SD_CALCULATE2=15;
|
||||
short SD_CALCULATE3=16;
|
||||
short SD_DECREASE=17;
|
||||
|
||||
short SD_SET_RSAKEY_N=29;
|
||||
short SD_SET_RSAKEY_D=30;
|
||||
|
||||
short SD_SET_DES_KEY=41;
|
||||
short SD_DES_ENC=42;
|
||||
short SD_DES_DEC=43;
|
||||
short SD_RSA_ENC=44;
|
||||
short SD_RSA_DEC=45;
|
||||
|
||||
short SD_READ_EX=46;
|
||||
short SD_WRITE_EX=47;
|
||||
|
||||
short SD_SET_COUNTER_EX=160;
|
||||
short SD_GET_COUNTER_EX=161;
|
||||
short SD_SET_TIMER_EX=162;
|
||||
short SD_GET_TIMER_EX=163;
|
||||
short SD_ADJUST_TIMER_EX=164;
|
||||
short SD_UPDATE_GEN_HEADER_EX=165;
|
||||
short SD_UPDATE_GEN_EX=166;
|
||||
short SD_UPDATE_CHECK_EX=167;
|
||||
short SD_UPDATE_EX=168;
|
||||
short SD_SET_UPDATE_KEY=169;
|
||||
short SD_ADD_UPDATE_HEADER=170;
|
||||
short SD_ADD_UPDATE_CONTENT=171;
|
||||
short SD_GET_TIME_DWORD=172;
|
||||
|
||||
short SD_VERSION=100;
|
||||
|
||||
short DES_SINGLE_MODE=0;
|
||||
short DES_TRIPLE_MODE=1;
|
||||
short RSA_PRIVATE_KEY=0;
|
||||
short RSA_PUBLIC_KEY=1;
|
||||
short RSA_SECUREDONGLE_PADDING=0;
|
||||
short RSA_USER_PADDING=1;
|
||||
|
||||
//error code
|
||||
short ERR_SUCCESS=0;
|
||||
short ERR_NO_ROCKEY=3;
|
||||
short ERR_INVALID_PASSWORD=4;
|
||||
short ERR_INVALID_PASSWORD_OR_ID=5;
|
||||
short ERR_SETID=6;
|
||||
short ERR_INVALID_ADDR_OR_SIZE=7;
|
||||
short ERR_UNKNOWN_COMMAND=8;
|
||||
short ERR_NOTBELEVEL3=9;
|
||||
short ERR_READ=10;
|
||||
short ERR_WRITE=11;
|
||||
short ERR_RANDOM=12;
|
||||
short ERR_SEED=13;
|
||||
short ERR_CALCULATE=14;
|
||||
short ERR_NO_OPEN=15;
|
||||
short ERR_OPEN_OVERFLOW=16;
|
||||
short ERR_NOMORE=17;
|
||||
short ERR_NEED_FIND=18;
|
||||
short ERR_DECREASE=19;
|
||||
short ERR_AR_BADCOMMAND=20;
|
||||
short ERR_AR_UNKNOWN_OPCODE=21;
|
||||
short ERR_AR_WRONGBEGIN=22;
|
||||
short ERR_AR_WRONG_END=23;
|
||||
short ERR_AR_VALUEOVERFLOW=24;
|
||||
|
||||
short ERR_TOOMUCHTHREAD=25;
|
||||
short ERR_INVALID_SD=30;
|
||||
short ERR_INVALID_PARAMETER=31;
|
||||
short ERR_INVALID_TIMEVALUE=32;
|
||||
|
||||
short ERR_SET_DES_KEY=40;
|
||||
short ERR_DES_ENCRYPT=41;
|
||||
short ERR_DES_DECRYPT=42;
|
||||
short ERR_SET_RSAKEY_N=43;
|
||||
short ERR_SET_RSAKEY_D=44;
|
||||
short ERR_RSA_ENCRYPT=45;
|
||||
short ERR_RSA_DECRYPT=46;
|
||||
short ERR_INVALID_LENGTH=47;
|
||||
|
||||
short ERR_UNKNOWN=-1;
|
||||
short ERR_RECEIVE_NULL=256;
|
||||
short ERR_INVALID_BUFFER=257;
|
||||
short ERR_UNKNOWN_SYSTEM=258;
|
||||
short ERR_UNINIT_TIME_UNIT=259;
|
||||
|
||||
short SecureDongle(short command, short[] handle, int[] lp1, int[] lp2, short[] p1, short[] p2, short[] p3, short[] p4, byte[] buffer);
|
||||
}
|
||||
273
src/main/java/SecureDongle/SecureDongle.java
Normal file
273
src/main/java/SecureDongle/SecureDongle.java
Normal file
@@ -0,0 +1,273 @@
|
||||
package SecureDongle;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static Config.SomeCodes.ToShort;
|
||||
|
||||
public class SecureDongle {
|
||||
|
||||
private final int[] lp1 = new int[1];
|
||||
private final int[] lp2 = new int[1];
|
||||
// for Open/Close Handle
|
||||
private final short[] handle = new short[1];
|
||||
// P1
|
||||
private final short[] p1 = new short[1];
|
||||
// P2
|
||||
private final short[] p2 = new short[1];
|
||||
// P3
|
||||
private final short[] p3 = new short[1];
|
||||
// P4
|
||||
private final short[] p4 = new short[1];
|
||||
|
||||
private final byte[] buffer = new byte[1024];
|
||||
|
||||
LibSecureDongle SD;
|
||||
|
||||
private @Getter boolean Opened = false;
|
||||
private @Getter short Handle;
|
||||
private @Getter int HardwareID = 0;
|
||||
private @Getter int UserID = 0;
|
||||
|
||||
private @Setter SecureDongleEvent event;
|
||||
|
||||
/**
|
||||
* Create SecureDongle with P1, P2, P3, P4
|
||||
* @param P1 Password 1
|
||||
* @param P2 Password 2
|
||||
* @param P3 Password 3
|
||||
* @param P4 Password 4
|
||||
*/
|
||||
public SecureDongle(Short P1, Short P2, Short P3, Short P4){
|
||||
this.p1[0] = P1;
|
||||
this.p2[0] = P2;
|
||||
this.p3[0] = P3;
|
||||
this.p4[0] = P4;
|
||||
SD = LibSecureDongle.Instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create SecureDongle with P1, P2, P3, P4
|
||||
* @param P1 Password 1
|
||||
* @param P2 Password 2
|
||||
* @param P3 Password 3
|
||||
* @param P4 Password 4
|
||||
*/
|
||||
public SecureDongle(String P1, String P2, String P3, String P4){
|
||||
this.p1[0] = ToShort(P1);
|
||||
this.p2[0] = ToShort(P2);
|
||||
this.p3[0] = ToShort(P3);
|
||||
this.p4[0] = ToShort(P4);
|
||||
SD = LibSecureDongle.Instance;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Find SecureDongle
|
||||
* This must be executed first time
|
||||
* @return true if found
|
||||
*/
|
||||
public boolean Find(){
|
||||
HardwareID = 0;
|
||||
short result = SD.SecureDongle(LibSecureDongle.SD_FIND, handle, lp1, lp2, p1, p2, p3, p4, buffer);
|
||||
|
||||
if (result== LibSecureDongle.ERR_SUCCESS){
|
||||
HardwareID = lp1[0];
|
||||
//System.out.println("SecureDongle found with HardwareID="+HardwareID);
|
||||
return true;
|
||||
} else {
|
||||
if (event!=null) event.onDongleError("Find", result);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open SecureDongle
|
||||
* @return true if success
|
||||
*/
|
||||
public boolean Open(){
|
||||
Handle=0;
|
||||
if (HardwareID!=0){
|
||||
lp1[0] = HardwareID;
|
||||
short result = SD.SecureDongle(LibSecureDongle.SD_OPEN, handle, lp1, lp2, p1, p2, p3, p4, buffer);
|
||||
if (result== LibSecureDongle.ERR_SUCCESS){
|
||||
Handle = handle[0];
|
||||
Opened = true;
|
||||
return true;
|
||||
} else if (event!=null) event.onDongleError("Open", result);
|
||||
} //else System.out.println("HardwareID not found, Find SecureDongle first");
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close SecureDongle
|
||||
* @return true if success
|
||||
*/
|
||||
public boolean Close(){
|
||||
handle[0] = Handle;
|
||||
short result = SD.SecureDongle(LibSecureDongle.SD_CLOSE, handle, lp1, lp2, p1, p2, p3, p4, buffer);
|
||||
if (result== LibSecureDongle.ERR_SUCCESS){
|
||||
return true;
|
||||
} else if (event!=null) event.onDongleError("Close", result);
|
||||
Opened = false;
|
||||
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
|
||||
*/
|
||||
public byte[] Read(short StartAddress, short Length){
|
||||
if (Opened){
|
||||
handle[0] = Handle;
|
||||
p1[0] = StartAddress>=0 ? StartAddress : 0;
|
||||
if (Length<1) Length=1;
|
||||
if (Length>1000) Length=1000;
|
||||
p2[0] = Length;
|
||||
short result = SD.SecureDongle(LibSecureDongle.SD_READ, handle, lp1, lp2, p1, p2, p3, p4, buffer);
|
||||
if (result== LibSecureDongle.ERR_SUCCESS){
|
||||
//System.out.println("SecureDongle HardwareID="+HardwareID+" read success ");
|
||||
byte[] data = new byte[Length];
|
||||
System.arraycopy(buffer, 0, data, 0, Length);
|
||||
return data;
|
||||
} else if (event!=null) event.onDongleError("Read", result);
|
||||
} //else System.out.println("SecureDongle not opened");
|
||||
|
||||
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
|
||||
*/
|
||||
public short[] GenerateRandomNumber(){
|
||||
short[] random = new short[4];
|
||||
if (Opened){
|
||||
handle[0] = Handle;
|
||||
short result = SD.SecureDongle(LibSecureDongle.SD_RANDOM, handle, lp1, lp2, p1, p2, p3, p4, buffer);
|
||||
if (result== LibSecureDongle.ERR_SUCCESS){
|
||||
//System.out.println("SecureDongle HardwareID="+HardwareID+" generate random success ");
|
||||
random[0] = p1[0];
|
||||
random[1] = p2[0];
|
||||
random[2] = p3[0];
|
||||
random[3] = p4[0];
|
||||
return random;
|
||||
} else if (event!=null) event.onDongleError("GenerateRandomNumber", result);
|
||||
} //else System.out.println("SecureDongle not opened");
|
||||
|
||||
return random;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write UserID to SecureDongle
|
||||
* @param UserID UserID to write
|
||||
* @return true if success
|
||||
*/
|
||||
public boolean WriteUserID(int UserID){
|
||||
if (Opened){
|
||||
handle[0] = Handle;
|
||||
lp1[0] = UserID;
|
||||
short result = SD.SecureDongle(LibSecureDongle.SD_WRITE_USERID, handle, lp1, lp2, p1, p2, p3, p4, buffer);
|
||||
if (result== LibSecureDongle.ERR_SUCCESS){
|
||||
//System.out.println("SecureDongle HardwareID="+HardwareID+" set UserID success ");
|
||||
this.UserID = UserID;
|
||||
return true;
|
||||
} else if (event!=null) event.onDongleError("WriteUserID", result);
|
||||
} //else System.out.println("SecureDongle not opened");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read UserID from SecureDongle
|
||||
* @return UserID, 0 if failed
|
||||
*/
|
||||
public int ReadUserID(){
|
||||
if (Opened){
|
||||
handle[0] = Handle;
|
||||
short result = SD.SecureDongle(LibSecureDongle.SD_READ_USERID, handle, lp1, lp2, p1, p2, p3, p4, buffer);
|
||||
if (result== LibSecureDongle.ERR_SUCCESS){
|
||||
this.UserID = lp1[0];
|
||||
//System.out.println("SecureDongle HardwareID="+HardwareID+" read UserID success, value = "+UserID);
|
||||
return UserID;
|
||||
} else if (event!=null) event.onDongleError("ReadUserID", result);
|
||||
} //else System.out.println("SecureDongle not opened");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
boolean ismonitoring = false;
|
||||
|
||||
/**
|
||||
* Stop Monitoring SecureDongle
|
||||
*/
|
||||
public void StopMonitor(){
|
||||
ismonitoring = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start Monitoring SecureDongle
|
||||
* if dongle missing, will raise event onDongleMissing
|
||||
*/
|
||||
public void StartMonitor(){
|
||||
new Thread(()->{
|
||||
if (HardwareID==0) Find();
|
||||
Open();
|
||||
int firstUserID = ReadUserID();
|
||||
Close();
|
||||
if (firstUserID!=0){
|
||||
ismonitoring = true;
|
||||
Logger.info("Start Monitoring UserID="+Integer.toHexString(firstUserID));
|
||||
while (ismonitoring){
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Open();
|
||||
int newUserID = ReadUserID();
|
||||
Close();
|
||||
if (newUserID!=firstUserID){
|
||||
if (event!=null) event.onDongleMissing();
|
||||
}
|
||||
|
||||
}
|
||||
System.out.println("Stop Monitoring");
|
||||
} else System.out.println("Canceled Monitoring, UserID not found");
|
||||
|
||||
}).start();
|
||||
}
|
||||
|
||||
}
|
||||
6
src/main/java/SecureDongle/SecureDongleEvent.java
Normal file
6
src/main/java/SecureDongle/SecureDongleEvent.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package SecureDongle;
|
||||
|
||||
public interface SecureDongleEvent {
|
||||
void onDongleMissing();
|
||||
void onDongleError(String function,int errorCode);
|
||||
}
|
||||
99
src/main/java/id/co/gtc/erhacam/AutoCloseAlert.java
Normal file
99
src/main/java/id/co/gtc/erhacam/AutoCloseAlert.java
Normal file
@@ -0,0 +1,99 @@
|
||||
package id.co.gtc.erhacam;
|
||||
|
||||
import javafx.animation.PauseTransition;
|
||||
import javafx.application.Platform;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Screen;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.StageStyle;
|
||||
import javafx.util.Duration;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class AutoCloseAlert {
|
||||
|
||||
private static Stage currentAlertStage;
|
||||
public static String shownTitle = "";
|
||||
public static String shownContent = "";
|
||||
public static String shownHeader = "";
|
||||
|
||||
private static void clear(){
|
||||
shownTitle = "";
|
||||
shownContent = "";
|
||||
shownHeader = "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the current alert if it is shown
|
||||
*/
|
||||
public static void close(){
|
||||
Optional.ofNullable(currentAlertStage).ifPresent(Stage::close);
|
||||
currentAlertStage = null;
|
||||
clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show an alert with a title, header, content, and automatically close after a few seconds
|
||||
* If called several times, the previous alert will be closed before showing a new one
|
||||
* @param title the title of the alert
|
||||
* @param header the header 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
|
||||
*/
|
||||
public static void show(String title, String header, String content, int seconds) {
|
||||
Platform.runLater(()->{
|
||||
// close previous alert before showing a new one
|
||||
Optional.ofNullable(currentAlertStage).ifPresent(Stage::close);
|
||||
|
||||
Stage alertStage = new Stage();
|
||||
alertStage.initModality(Modality.APPLICATION_MODAL);
|
||||
alertStage.initStyle(StageStyle.UTILITY);
|
||||
alertStage.setAlwaysOnTop(true);
|
||||
alertStage.setResizable(false);
|
||||
|
||||
double screenwidth = Screen.getPrimary().getVisualBounds().getWidth();
|
||||
double width = screenwidth/4;
|
||||
double height = width * 9 / 16;
|
||||
Label headerLabel = new Label(header);
|
||||
headerLabel.setStyle("-fx-font-weight: bold; -fx-font-size: 16px;");
|
||||
headerLabel.setMinHeight(height*0.25);
|
||||
Label contentLabel = new Label(content);
|
||||
contentLabel.setStyle("-fx-font-size: 12px;");
|
||||
contentLabel.setMinHeight(height*0.75);
|
||||
|
||||
VBox root = new VBox(10, headerLabel, contentLabel);
|
||||
root.setPrefSize(width, height);
|
||||
root.setAlignment(Pos.CENTER);
|
||||
|
||||
Scene scene = new Scene(root);
|
||||
alertStage.setScene(scene);
|
||||
|
||||
alertStage.setTitle(title);
|
||||
currentAlertStage = alertStage;
|
||||
|
||||
alertStage.show();
|
||||
|
||||
shownHeader = header;
|
||||
shownContent = content;
|
||||
shownTitle = title;
|
||||
|
||||
if (seconds>0){
|
||||
PauseTransition delay = new PauseTransition(Duration.seconds(seconds));
|
||||
delay.setOnFinished(e -> {
|
||||
alertStage.close();
|
||||
if (currentAlertStage == alertStage) {
|
||||
currentAlertStage = null;
|
||||
}
|
||||
clear();
|
||||
} );
|
||||
delay.play();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
package id.co.gtc.erhacam;
|
||||
|
||||
import Camera.ArducamIMX477Preset;
|
||||
import Camera.CameraProperty;
|
||||
import Camera.LiveCamEvent;
|
||||
import Camera.ObsbotMeet2Preset;
|
||||
import Config.CameraConfigEnum;
|
||||
import ErhaAPI.PhotoResult;
|
||||
import com.google.zxing.BinaryBitmap;
|
||||
import com.google.zxing.NotFoundException;
|
||||
import com.google.zxing.Result;
|
||||
@@ -11,8 +12,6 @@ import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
|
||||
import com.google.zxing.common.HybridBinarizer;
|
||||
import javafx.application.Platform;
|
||||
|
||||
import javafx.beans.InvalidationListener;
|
||||
import javafx.beans.Observable;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Slider;
|
||||
@@ -24,11 +23,15 @@ import javafx.scene.image.WritableImage;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import org.bytedeco.javacv.Frame;
|
||||
import org.bytedeco.javacv.OpenCVFrameGrabber;
|
||||
import org.bytedeco.opencv.global.opencv_core;
|
||||
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;
|
||||
@@ -36,19 +39,31 @@ import java.awt.image.DataBufferByte;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.file.Path;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
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"})
|
||||
public class Cameradetail {
|
||||
private static final boolean isCudaAvailable ;
|
||||
static{
|
||||
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");
|
||||
}
|
||||
|
||||
}
|
||||
private final AtomicBoolean Capturing = new AtomicBoolean(false);
|
||||
private final AtomicBoolean TakingPhoto = new AtomicBoolean(false);
|
||||
private final AtomicBoolean IsGrabbingLiveView = new AtomicBoolean(false);
|
||||
@@ -87,11 +102,35 @@ public class Cameradetail {
|
||||
@FXML
|
||||
private Slider exposureSlider;
|
||||
|
||||
private @Getter final UMat BestMat = new UMat();
|
||||
private @Getter final UMat LiveMat = new UMat();
|
||||
private @Getter final UMat ReducedMat = new UMat();
|
||||
|
||||
private @Getter Rect BestMatROI;
|
||||
private @Getter Rect ReducedMatROI;
|
||||
private @Getter Rect LiveMatROI;
|
||||
|
||||
private boolean IsPortrait = false;
|
||||
|
||||
// putar portrait
|
||||
private @Getter Size LiveSize = new Size(360, 640);
|
||||
private @Getter Size ReducedSize = new Size(720, 1280);
|
||||
private @Getter Size BestSize = new Size(2160, 3840);
|
||||
|
||||
//TODO ini angka dari Erha, cek apakah masih cocok atau tidak
|
||||
private @Getter @Setter Size FullCropSize = new Size(1036,1036);
|
||||
|
||||
public int getBestWidth(){
|
||||
return BestSize.width();
|
||||
}
|
||||
|
||||
public int getBestHeight(){
|
||||
return BestSize.height();
|
||||
}
|
||||
|
||||
int[] paramjpeg = {opencv_imgcodecs.IMWRITE_JPEG_QUALITY, 100};
|
||||
int[] parampng = {opencv_imgcodecs.IMWRITE_PNG_COMPRESSION, 0};
|
||||
|
||||
private final UMat BestMat = new UMat();
|
||||
private final UMat LiveMat = new UMat();
|
||||
private Size LiveSize = new Size(640, 480);
|
||||
private Size PhotoSize = new Size(1920, 1080);
|
||||
|
||||
private void setSliderValue(Slider sld, CameraProperty prop, double value){
|
||||
if (sld!=null){
|
||||
@@ -121,12 +160,12 @@ public class Cameradetail {
|
||||
streamanchor.widthProperty().addListener(obs -> resize_streamanchor());
|
||||
|
||||
Platform.runLater(()->{
|
||||
setSliderValue(brightnessSlider, ArducamIMX477Preset.Brightness, config.getBrightness(cameraConfigEnum));
|
||||
setSliderValue(contrastSlider, ArducamIMX477Preset.Contrast, config.getContrast(cameraConfigEnum));
|
||||
setSliderValue(saturationSlider, ArducamIMX477Preset.Saturation, config.getSaturation(cameraConfigEnum));
|
||||
setSliderValue(hueSlider, ArducamIMX477Preset.Hue, config.getHue(cameraConfigEnum));
|
||||
setSliderValue(gainSlider, ArducamIMX477Preset.Gain, config.getGain(cameraConfigEnum));
|
||||
setSliderValue(exposureSlider, ArducamIMX477Preset.ExposureTime, config.getExposure(cameraConfigEnum));
|
||||
setSliderValue(brightnessSlider, ObsbotMeet2Preset.Brightness, config.getBrightness(cameraConfigEnum));
|
||||
setSliderValue(contrastSlider, ObsbotMeet2Preset.Contrast, config.getContrast(cameraConfigEnum));
|
||||
setSliderValue(saturationSlider, ObsbotMeet2Preset.Saturation, config.getSaturation(cameraConfigEnum));
|
||||
setSliderValue(hueSlider, ObsbotMeet2Preset.Hue, config.getHue(cameraConfigEnum));
|
||||
setSliderValue(gainSlider, ObsbotMeet2Preset.Gain, config.getGain(cameraConfigEnum));
|
||||
setSliderValue(exposureSlider, ObsbotMeet2Preset.ExposureTime, config.getExposure(cameraConfigEnum));
|
||||
|
||||
});
|
||||
|
||||
@@ -167,12 +206,12 @@ public class Cameradetail {
|
||||
|
||||
@FXML
|
||||
public void resetClick(){
|
||||
brightnessSlider.adjustValue(ArducamIMX477Preset.Brightness.Default);
|
||||
contrastSlider.adjustValue(ArducamIMX477Preset.Contrast.Default);
|
||||
saturationSlider.adjustValue(ArducamIMX477Preset.Saturation.Default);
|
||||
hueSlider.adjustValue(ArducamIMX477Preset.Hue.Default);
|
||||
gainSlider.adjustValue(ArducamIMX477Preset.Gain.Default);
|
||||
exposureSlider.adjustValue(ArducamIMX477Preset.ExposureTime.Default);
|
||||
brightnessSlider.adjustValue(ObsbotMeet2Preset.Brightness.Default);
|
||||
contrastSlider.adjustValue(ObsbotMeet2Preset.Contrast.Default);
|
||||
saturationSlider.adjustValue(ObsbotMeet2Preset.Saturation.Default);
|
||||
hueSlider.adjustValue(ObsbotMeet2Preset.Hue.Default);
|
||||
gainSlider.adjustValue(ObsbotMeet2Preset.Gain.Default);
|
||||
exposureSlider.adjustValue(ObsbotMeet2Preset.ExposureTime.Default);
|
||||
|
||||
}
|
||||
|
||||
@@ -310,14 +349,32 @@ public class Cameradetail {
|
||||
* @param liveheight Height used on live view
|
||||
* @param photowidth Width used on photo capture
|
||||
* @param photoheight Height used on photo capture
|
||||
* @param reducedwidth Width used on reduced resolution
|
||||
* @param reducedheight Height used on reduced resolution
|
||||
* @param isPotrait if true, set to portrait mode, otherwise landscape
|
||||
*/
|
||||
public void SetGrabber(OpenCVFrameGrabber grabber, int livewidth, int liveheight, int photowidth, int photoheight){
|
||||
public void SetGrabber(OpenCVFrameGrabber grabber, int livewidth, int liveheight, int photowidth, int photoheight, int reducedwidth, int reducedheight, boolean isPotrait){
|
||||
if (mGrabber!=null) {
|
||||
StopLiveView();
|
||||
}
|
||||
LiveSize = new Size(livewidth, liveheight);
|
||||
PhotoSize = new Size(photowidth, photoheight);
|
||||
|
||||
IsPortrait = isPotrait;
|
||||
|
||||
if (IsPortrait){
|
||||
// putar portrait
|
||||
LiveSize = new Size(liveheight, livewidth);
|
||||
BestSize = new Size(photoheight, photowidth);
|
||||
ReducedSize = new Size(reducedheight, reducedwidth);
|
||||
} else {
|
||||
LiveSize = new Size(livewidth, liveheight);
|
||||
BestSize = new Size(photowidth, photoheight);
|
||||
ReducedSize = new Size(reducedwidth, reducedheight);
|
||||
}
|
||||
|
||||
|
||||
|
||||
mGrabber = grabber;
|
||||
|
||||
}
|
||||
|
||||
//Exposure and Focus Tricks :
|
||||
@@ -330,7 +387,7 @@ public class Cameradetail {
|
||||
*/
|
||||
public void setAutoExposure(boolean ON){
|
||||
if (mGrabber!=null){
|
||||
mGrabber.setOption(Videoio.CAP_PROP_AUTO_EXPOSURE, ON?ArducamIMX477Preset.AutoExposure.On:ArducamIMX477Preset.AutoExposure.Off);
|
||||
mGrabber.setOption(Videoio.CAP_PROP_AUTO_EXPOSURE, ON?ObsbotMeet2Preset.AutoExposure.On:ObsbotMeet2Preset.AutoExposure.Off);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,7 +397,7 @@ public class Cameradetail {
|
||||
*/
|
||||
public boolean getAutoExposure(){
|
||||
if (mGrabber!=null){
|
||||
return mGrabber.getOption(Videoio.CAP_PROP_AUTO_EXPOSURE)==ArducamIMX477Preset.AutoExposure.On;
|
||||
return mGrabber.getOption(Videoio.CAP_PROP_AUTO_EXPOSURE)==ObsbotMeet2Preset.AutoExposure.On;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -372,7 +429,7 @@ public class Cameradetail {
|
||||
*/
|
||||
public void setAutoFocus(boolean ON){
|
||||
if (mGrabber!=null){
|
||||
mGrabber.setOption(Videoio.CAP_PROP_AUTOFOCUS, ON?ArducamIMX477Preset.AutoFocus.On:ArducamIMX477Preset.AutoFocus.Off);
|
||||
mGrabber.setOption(Videoio.CAP_PROP_AUTOFOCUS, ON?ObsbotMeet2Preset.AutoFocus.On:ObsbotMeet2Preset.AutoFocus.Off);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,20 +439,20 @@ public class Cameradetail {
|
||||
*/
|
||||
public boolean getAutoFocus(){
|
||||
if (mGrabber!=null){
|
||||
return mGrabber.getOption(Videoio.CAP_PROP_AUTOFOCUS)==ArducamIMX477Preset.AutoFocus.On;
|
||||
return mGrabber.getOption(Videoio.CAP_PROP_AUTOFOCUS)==ObsbotMeet2Preset.AutoFocus.On;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setAutoWB(boolean ON){
|
||||
if (mGrabber!=null){
|
||||
mGrabber.setOption(Videoio.CAP_PROP_AUTO_WB, ON?ArducamIMX477Preset.AutoWhiteBalance.On:ArducamIMX477Preset.AutoWhiteBalance.Off);
|
||||
mGrabber.setOption(Videoio.CAP_PROP_AUTO_WB, ON?ObsbotMeet2Preset.AutoWhiteBalance.On:ObsbotMeet2Preset.AutoWhiteBalance.Off);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getAutoWB(){
|
||||
if (mGrabber!=null){
|
||||
return mGrabber.getOption(Videoio.CAP_PROP_AUTO_WB)==ArducamIMX477Preset.AutoWhiteBalance.On;
|
||||
return mGrabber.getOption(Videoio.CAP_PROP_AUTO_WB)==ObsbotMeet2Preset.AutoWhiteBalance.On;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -499,7 +556,81 @@ public class Cameradetail {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean PutText(String filename, String text, double fontScale, Scalar textColor, int thickness){
|
||||
if (ValidString(filename)){
|
||||
Mat mat = opencv_imgcodecs.imread(filename);
|
||||
if (PutText(mat, text, fontScale, textColor, thickness)){
|
||||
return opencv_imgcodecs.imwrite(filename, mat);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean PutText(UMat Mat, String text, double fontScale, Scalar textColor, int thickness){
|
||||
if (!Mat.empty()){
|
||||
if (text!=null && !text.isEmpty()){
|
||||
//String timestamp = prefix+" "+SomeCodes.GetDateTimeString();
|
||||
int fontFace = FONT_HERSHEY_SIMPLEX;
|
||||
//double fontScale = 4.0;
|
||||
//int thickness = 2;
|
||||
//Scalar textColor = new Scalar(255, 255, 255, 0); // white color in BGR format
|
||||
int[] baseline = {0};
|
||||
Size textSize = getTextSize(text, fontFace, fontScale, thickness, baseline);
|
||||
// position of the text in the bottom right corner
|
||||
int textX = Mat.cols() - textSize.width() - 10; // 10 pixels from the right
|
||||
int textY = Mat.rows() - 10; // 10 pixels from the bottom
|
||||
opencv_imgproc.putText(Mat, text, new Point(textX, textY), fontFace, fontScale, textColor, thickness, LINE_8, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean PutText(Mat Mat, String text, double fontScale, Scalar textColor, int thickness){
|
||||
if (!Mat.empty()){
|
||||
if (text!=null && !text.isEmpty()){
|
||||
//String timestamp = prefix+" "+SomeCodes.GetDateTimeString();
|
||||
int fontFace = FONT_HERSHEY_SIMPLEX;
|
||||
//double fontScale = 4.0;
|
||||
//int thickness = 2;
|
||||
//Scalar textColor = new Scalar(255, 255, 255, 0); // white color in BGR format
|
||||
int[] baseline = {0};
|
||||
Size textSize = getTextSize(text, fontFace, fontScale, thickness, baseline);
|
||||
// position of the text in the bottom right corner
|
||||
int textX = Mat.cols() - textSize.width() - 10; // 10 pixels from the right
|
||||
int textY = Mat.rows() - 10; // 10 pixels from the bottom
|
||||
opencv_imgproc.putText(Mat, text, new Point(textX, textY), fontFace, fontScale, textColor, thickness, LINE_8, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String GetFullQualityPhotoPath(String directory, String prefix){
|
||||
//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();
|
||||
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();
|
||||
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();
|
||||
return Path.of(config.getCompressedCropDirectory(), makeFileName(prefix,".jpg")).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Take Photo from Camera
|
||||
@@ -507,23 +638,44 @@ public class Cameradetail {
|
||||
* @param prefix filename prefix
|
||||
* @return filename path of the saved photo, or null if failed
|
||||
*/
|
||||
@SuppressWarnings("BusyWait")
|
||||
public String TakePhoto(String directory, String prefix) throws InterruptedException {
|
||||
String result = null;
|
||||
public PhotoResult TakePhoto(String directory, String prefix) throws InterruptedException {
|
||||
PhotoResult result = new PhotoResult(cameratitle.getText());
|
||||
if (!ValidDirectory(directory)) directory = currentDirectory;
|
||||
|
||||
if (mGrabber!=null){
|
||||
while(IsGrabbingLiveView.get()){
|
||||
Thread.sleep(10);
|
||||
}
|
||||
TakingPhoto.set(true);
|
||||
if (!BestMat.empty()){
|
||||
Size sz = BestMat.size();
|
||||
raise_log("TakePhoto got frame with width: " + sz.width() + " and height: " + sz.height());
|
||||
String filename = Path.of(directory, makeFileName(prefix)).toString();
|
||||
if (imwrite(filename, BestMat)){
|
||||
raise_log("TakePhoto success, Photo saved to " + filename);
|
||||
result = filename;
|
||||
} else raise_log("TakePhoto failed, Unable to Save Photo");
|
||||
|
||||
// save BestMat at quality 9 PNG
|
||||
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());
|
||||
|
||||
String xx = CropBestMat(directory, prefix, BestMatROI);
|
||||
if (ValidFile(xx)) {
|
||||
result.setFullcrop(xx);
|
||||
result.setBestROI(new Rect(BestMatROI.x(), BestMatROI.y(), BestMatROI.width(), BestMatROI.height()));
|
||||
}
|
||||
|
||||
|
||||
// save ReducedMat at 100% JPEG
|
||||
String reducedfilename = GetReducedPhotoPath(directory, prefix);
|
||||
opencv_imgproc.resize(BestMat, ReducedMat, ReducedSize);
|
||||
if (!opencv_imgcodecs.imwrite(reducedfilename, ReducedMat, paramjpeg)){
|
||||
System.out.println("TakePhoto failed, Unable to Save Reduced Photo for camera "+cameratitle.getText());
|
||||
} else result.setCompressedfile(reducedfilename);
|
||||
|
||||
String xy = CropReducedMat(directory, prefix, ReducedMatROI);
|
||||
if (ValidFile(xy)){
|
||||
result.setCompressedcrop(xy);
|
||||
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");
|
||||
TakingPhoto.set(false);
|
||||
@@ -531,21 +683,68 @@ public class Cameradetail {
|
||||
}
|
||||
|
||||
|
||||
//TODO Revisi nama file
|
||||
private String makeFileName(String prefix){
|
||||
//make filename with prefix_POSITION_YYYY-MM-DD_HH-MM-SS
|
||||
|
||||
public String CropBestMat(String directory, String prefix, Rect ROI){
|
||||
UMat cloned = new UMat();
|
||||
BestMat.copyTo(cloned);
|
||||
if (!cloned.empty()) {
|
||||
if (ValidROI(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)) {
|
||||
Logger.info("CropBestMat success, saved as " + filename);
|
||||
return filename;
|
||||
} 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;
|
||||
}
|
||||
|
||||
public String CropReducedMat(String directory, String prefix, Rect ROI){
|
||||
if (!ReducedMat.empty()){
|
||||
if (ValidROI(ROI)){
|
||||
if (ROIInsideUMat(ROI,ReducedMat)){
|
||||
UMat cropped = CropUMat(ReducedMat, ROI);
|
||||
if (cropped!=null){
|
||||
String filename = GetReducedCropPhotoPath(directory, prefix);
|
||||
if (opencv_imgcodecs.imwrite(filename, cropped, paramjpeg)){
|
||||
Logger.info("CropReducedMat success, saved as ",filename);
|
||||
return filename;
|
||||
} 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
private String makeFileName(String prefix, String extension){
|
||||
LocalDateTime ldt = LocalDateTime.now();
|
||||
String timetag = ldt.getYear() + "-" + ldt.getMonthValue() + "-" + ldt.getDayOfMonth() + "_" + ldt.getHour() + "-" + ldt.getMinute() + "-" + ldt.getSecond();
|
||||
return prefix+" "+timetag+" "+cameratitle.getText() + ".jpg";
|
||||
return prefix+" "+timetag+" "+cameratitle.getText() + extension;
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
private String makeReducedFileName(String prefix, String extension){
|
||||
LocalDateTime ldt = LocalDateTime.now();
|
||||
String timetag = ldt.getYear() + "-" + ldt.getMonthValue() + "-" + ldt.getDayOfMonth() + "_" + ldt.getHour() + "-" + ldt.getMinute() + "-" + ldt.getSecond();
|
||||
return prefix+" "+timetag+" "+cameratitle.getText() + "_reduced" + extension;
|
||||
}
|
||||
|
||||
public void StopLiveView(){
|
||||
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());
|
||||
@@ -556,6 +755,33 @@ public class Cameradetail {
|
||||
IsGrabbingLiveView.set(false);
|
||||
}
|
||||
|
||||
public Rect GetFace(UMat mat, boolean isfrontal){
|
||||
if (!mat.empty()){
|
||||
Mat originalmat = new Mat();
|
||||
mat.copyTo(originalmat);
|
||||
Mat graymat = new Mat();
|
||||
opencv_imgproc.cvtColor(originalmat,graymat, COLOR_BGR2GRAY); // convert to grayscale
|
||||
int size = Math.min(graymat.cols(), graymat.rows());
|
||||
int minsize = (int) (size * 0.4);
|
||||
int maxsize = (int) (size * 0.9);
|
||||
System.out.println("GetFace size = "+size+" minsize = "+minsize+" maxsize = "+maxsize);
|
||||
RectVector faces = isfrontal ? Detectors.DetectFrontalFace(graymat, minsize, maxsize) : Detectors.DetectProfileFace(graymat, minsize, maxsize);
|
||||
if (faces.size()>0){
|
||||
Rect result = null;
|
||||
for(Rect xx : faces.get()){
|
||||
if (result==null){
|
||||
result = xx;
|
||||
} else {
|
||||
if (xx.area()>result.area()){
|
||||
result = xx;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} else raise_log("GetFace failed, Mat is empty");
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean StartLiveView(LiveCamEvent event, String cameratitle, final boolean use_qr , final boolean use_face) {
|
||||
this.event = event;
|
||||
@@ -565,15 +791,22 @@ public class Cameradetail {
|
||||
if (use_qr) raise_log("QR Reader loaded");
|
||||
if (use_face) raise_log("Face detector loaded");
|
||||
// capture with best resolution
|
||||
setFrameHeight(PhotoSize.height());
|
||||
setFrameWidth(PhotoSize.width());
|
||||
if (IsPortrait){
|
||||
setFrameHeight(BestSize.width());
|
||||
setFrameWidth(BestSize.height());
|
||||
} else {
|
||||
setFrameHeight(BestSize.height());
|
||||
setFrameWidth(BestSize.width());
|
||||
}
|
||||
|
||||
LiveFPS = 0;
|
||||
mGrabber.start();
|
||||
mGrabber.flush();
|
||||
System.out.println("Camera "+cameratitle+" started");
|
||||
|
||||
Capturing.set(true);
|
||||
// just information
|
||||
String ss = String.format("Camera Started with resolution %dx%d@%d", PhotoSize.width(), PhotoSize.height(),LiveFPS);
|
||||
String ss = String.format("Camera Started with resolution %dx%d@%d", BestSize.width(), BestSize.height(),LiveFPS);
|
||||
Platform.runLater(()->setCameraStatus(ss));
|
||||
raise_log(ss);
|
||||
|
||||
@@ -585,14 +818,37 @@ public class Cameradetail {
|
||||
protected Image call() {
|
||||
// repeat until capturing is false
|
||||
AtomicInteger fps = new AtomicInteger(0);
|
||||
TimerTask timerTask = new TimerTask() {
|
||||
// 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;
|
||||
|
||||
TimerTask fpsTask = new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
LiveFPS = fps.getAndSet(0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Timer timer = new java.util.Timer();
|
||||
timer.scheduleAtFixedRate(timerTask, 1000, 1000);
|
||||
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 open_eye_counter = 0;
|
||||
int close_eye_counter = 0;
|
||||
|
||||
while (Capturing.get()) {
|
||||
try {
|
||||
// selama proses pengambilan foto, jangan ambil frame
|
||||
@@ -602,41 +858,190 @@ public class Cameradetail {
|
||||
|
||||
if (!Capturing.get()) return null;
|
||||
IsGrabbingLiveView.set(true);
|
||||
Frame frame = mGrabber.grab(); // grab frame
|
||||
Mat mat = matconverter.convert(frame); // convert to Mat
|
||||
if (mat.empty()) continue; // kalau gak ada data, continue
|
||||
int counter = fps.incrementAndGet();
|
||||
if (counter % 5 != 0) continue; // frame skip to 6 fps
|
||||
Frame frame;
|
||||
try{
|
||||
frame = mGrabber.grab(); // grab frame
|
||||
} catch (Exception e){
|
||||
frame = null;
|
||||
|
||||
mat.copyTo(BestMat); // copy to BestMat for using OpenCL
|
||||
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
|
||||
fps.incrementAndGet();
|
||||
|
||||
UMat originalmat = new UMat();
|
||||
mat.copyTo(originalmat); // copy to BestMat for using OpenCL
|
||||
// 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 (frame != null) {
|
||||
if (!BestMat.empty()) {
|
||||
opencv_imgproc.resize(BestMat, LiveMat, LiveSize); // resize to LiveSize
|
||||
UMat graymat = new UMat(); // use OpenCL for grayscale
|
||||
opencv_imgproc.cvtColor(LiveMat,graymat, COLOR_BGR2GRAY); // convert to grayscale
|
||||
if (use_qr){
|
||||
String qr = DetectQRFromMat(graymat);
|
||||
if (qr!=null) {
|
||||
if (!qr.equals(qrtext)){
|
||||
qrtext = qr;
|
||||
raise_log("QR Detected: " + qr);
|
||||
if (event!=null) event.onDetectedQRCode(qr);
|
||||
}
|
||||
if (ValidBarCode(qr)){
|
||||
qrtext = qr;
|
||||
if (event!=null) event.onDetectedQRCode(qrtext);
|
||||
}
|
||||
}
|
||||
if (use_face){
|
||||
RectVector face = DetectFace(graymat);
|
||||
if (face!=null && face.size()>0){
|
||||
if (event!=null) event.onFaceDetector(true, PhotoSize.width(), PhotoSize.height());
|
||||
for(int i=0; i<face.size(); i++){
|
||||
Rect rect = face.get(i);
|
||||
rectangle(LiveMat, rect, Scalar.GREEN);
|
||||
DetectorResult theface = null;
|
||||
have_frontal_face = false;
|
||||
have_left_45_face = false;
|
||||
_face_width = 0;
|
||||
_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;
|
||||
}
|
||||
}
|
||||
} else if (event!=null) event.onFaceDetector(false, PhotoSize.width(), PhotoSize.height());
|
||||
} else {
|
||||
// gak punya frontal face
|
||||
// coba cek punya profile left face 45 gak
|
||||
List<DetectorResult> Left45Faces = HaveLeft45Face(graymat);
|
||||
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 (have_frontal_face){
|
||||
|
||||
if (face_counter<5){
|
||||
face_counter++;
|
||||
//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);
|
||||
|
||||
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)
|
||||
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("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);
|
||||
if (event!=null) event.onBlink((int)diff);
|
||||
}
|
||||
} else {
|
||||
waiting_for_second_blink = true;
|
||||
System.out.println("First Blink Detected from camera "+cameratitle);
|
||||
}
|
||||
last_blink = now;
|
||||
}
|
||||
eye_state = 1;
|
||||
} 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("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>30){
|
||||
// kalau tidak ada face selama 30 frame, reset state
|
||||
// 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);
|
||||
}
|
||||
} else no_face_counter++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// if (HavePalm(graymat)) {
|
||||
// if (!have_palm){
|
||||
// have_fist = false;
|
||||
// have_palm = true;
|
||||
// System.out.println("Palm Detected from camera " + cameratitle);
|
||||
// }
|
||||
// }
|
||||
// if (HaveFist(graymat)) {
|
||||
// if (!have_fist) {
|
||||
// have_palm = false;
|
||||
// have_fist = true;
|
||||
// System.out.println("Fist Detected from camera "+cameratitle);
|
||||
// }
|
||||
// }
|
||||
|
||||
UMat rgbmat = new UMat(LiveMat.size(), CV_8UC3);
|
||||
cvtColor(LiveMat, rgbmat, COLOR_BGR2RGB);
|
||||
@@ -647,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);
|
||||
}
|
||||
}
|
||||
@@ -674,6 +1081,73 @@ 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, boolean printdebug){
|
||||
BestMatROI = null;
|
||||
ReducedMatROI = null;
|
||||
if (ValidROI(LiveMatROI)){
|
||||
if (ROIInsideUMat(LiveMatROI, LiveMat)){
|
||||
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();
|
||||
int XBest = (int) (LiveMatROI.x()*scaleXBest);
|
||||
int YBest = (int) (LiveMatROI.y()*scaleYBest);
|
||||
int WBest = (int) (LiveMatROI.width()*scaleXBest);
|
||||
int HBest = (int) (LiveMatROI.height()*scaleYBest);
|
||||
int deltaWBest = (int) (BestSize.width() * scaleX);
|
||||
int deltaHBest = (int) (BestSize.height() * scaleY);
|
||||
XBest = XBest - deltaWBest/2;
|
||||
if (XBest<0) XBest = 0;
|
||||
YBest = YBest - deltaHBest/2;
|
||||
if (YBest<0) YBest = 0;
|
||||
WBest = WBest + deltaWBest;
|
||||
if (WBest>BestSize.width()) WBest = BestSize.width();
|
||||
HBest = HBest + deltaHBest;
|
||||
if (HBest>BestSize.height()) HBest = BestSize.height();
|
||||
BestMatROI = new Rect(XBest, YBest, WBest, HBest);
|
||||
|
||||
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();
|
||||
int XReduced = (int) (LiveMatROI.x()*scaleXReduced);
|
||||
int YReduced = (int) (LiveMatROI.y()*scaleYReduced);
|
||||
int WReduced = (int) (LiveMatROI.width()*scaleXReduced);
|
||||
int HReduced = (int) (LiveMatROI.height()*scaleYReduced);
|
||||
int deltaWReduced = (int) (ReducedSize.width() * scaleX);
|
||||
int deltaHReduced = (int) (ReducedSize.height() * scaleY);
|
||||
XReduced = XReduced - deltaWReduced/2;
|
||||
if (XReduced<0) XReduced = 0;
|
||||
YReduced = YReduced - deltaHReduced/2;
|
||||
if (YReduced<0) YReduced = 0;
|
||||
WReduced = WReduced + deltaWReduced;
|
||||
if (WReduced>ReducedSize.width()) WReduced = ReducedSize.width();
|
||||
HReduced = HReduced + deltaHReduced;
|
||||
if (HReduced>ReducedSize.height()) HReduced = ReducedSize.height();
|
||||
ReducedMatROI = new Rect(XReduced, YReduced, WReduced, HReduced);
|
||||
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());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Detect QR Code from Mat
|
||||
* @param graymat Mat in Gray Scale
|
||||
@@ -697,19 +1171,9 @@ public class Cameradetail {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect Face from Mat
|
||||
* @param graymat Mat in Gray Scale
|
||||
* @return RectVector if face detected, otherwise false
|
||||
*/
|
||||
private RectVector DetectFace(UMat graymat){
|
||||
if (faceDetector!=null){
|
||||
RectVector face = new RectVector();
|
||||
faceDetector.detectMultiScale(graymat, face);
|
||||
return face;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private double getBrightnessFromGrayMat(Mat graymat){
|
||||
Scalar mean = mean(graymat);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
59
src/main/java/id/co/gtc/erhacam/DetectorResult.java
Normal file
59
src/main/java/id/co/gtc/erhacam/DetectorResult.java
Normal file
@@ -0,0 +1,59 @@
|
||||
package id.co.gtc.erhacam;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bytedeco.opencv.opencv_core.Rect;
|
||||
import org.bytedeco.opencv.opencv_core.Scalar;
|
||||
import org.bytedeco.opencv.opencv_core.UMat;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.bytedeco.opencv.global.opencv_imgproc.rectangle;
|
||||
|
||||
@Getter
|
||||
public class DetectorResult {
|
||||
private @Setter Rect Face;
|
||||
private List<Rect> Eyes;
|
||||
|
||||
public void AddEye(Rect eye){
|
||||
if (Eyes == null) Eyes = new java.util.ArrayList<>();
|
||||
Eyes.add(eye);
|
||||
}
|
||||
|
||||
public void FaceRectangle(UMat mat){
|
||||
if (haveFace()){
|
||||
rectangle(mat, Face, Scalar.GREEN);
|
||||
}
|
||||
}
|
||||
|
||||
public void EyesRectangle(UMat mat){
|
||||
if (haveEyes()){
|
||||
for(Rect eye : Eyes){
|
||||
rectangle(mat, eye, Scalar.BLUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean haveFace(){
|
||||
return Face != null && Face.width() > 0 && Face.height() > 0;
|
||||
}
|
||||
|
||||
public int getFaceWidth(){
|
||||
if (!haveFace()) return 0;
|
||||
return Face.width();
|
||||
}
|
||||
|
||||
public int getFaceHeight(){
|
||||
if (!haveFace()) return 0;
|
||||
return Face.height();
|
||||
}
|
||||
|
||||
public boolean haveEyes(){
|
||||
return Eyes != null && !Eyes.isEmpty();
|
||||
}
|
||||
|
||||
public int getEyesCount(){
|
||||
if (!haveEyes()) return 0;
|
||||
return Eyes.size();
|
||||
}
|
||||
}
|
||||
313
src/main/java/id/co/gtc/erhacam/Detectors.java
Normal file
313
src/main/java/id/co/gtc/erhacam/Detectors.java
Normal file
@@ -0,0 +1,313 @@
|
||||
package id.co.gtc.erhacam;
|
||||
|
||||
import Config.SomeCodes;
|
||||
import lombok.NonNull;
|
||||
import org.bytedeco.opencv.opencv_core.*;
|
||||
import org.bytedeco.opencv.opencv_objdetect.CascadeClassifier;
|
||||
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;
|
||||
private final static int flags = 0;
|
||||
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();
|
||||
LoadEyeDetector();
|
||||
|
||||
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");
|
||||
if (filename!=null) {
|
||||
Logger.info("Face Detector file : " + filename);
|
||||
if (frontalfaceDetector==null) {
|
||||
try{
|
||||
frontalfaceDetector = new CascadeClassifier(filename);
|
||||
Logger.info("FaceDetector loaded");
|
||||
} catch (Exception e){
|
||||
Logger.error("Exception on loading FaceDetector : " + e.getMessage());
|
||||
}
|
||||
|
||||
} else Logger.info("FaceDetector already loaded");
|
||||
} else Logger.error("Unable to extract face detector file");
|
||||
}
|
||||
|
||||
private static void LoadProfileFaceDetector(){
|
||||
String filename = SomeCodes.ExtractResource("/haarcascade_profileface.xml");
|
||||
if (filename!=null) {
|
||||
Logger.info("Profile Face Detector file : " + filename);
|
||||
if (profilefaceDetector==null) {
|
||||
try{
|
||||
profilefaceDetector = new CascadeClassifier(filename);
|
||||
Logger.info("ProfileFaceDetector loaded");
|
||||
} catch (Exception e){
|
||||
Logger.error("Exception on loading ProfileFaceDetector : " + e.getMessage());
|
||||
}
|
||||
|
||||
} else Logger.info("ProfileFaceDetector already loaded");
|
||||
} else Logger.error("Unable to extract profile face detector file");
|
||||
}
|
||||
|
||||
private static void LoadEyeDetector(){
|
||||
String filename = SomeCodes.ExtractResource("/haarcascade_eye.xml");
|
||||
if (filename!=null) {
|
||||
Logger.info("Eye Detector file : " + filename);
|
||||
if (eyeDetector==null) {
|
||||
try{
|
||||
|
||||
eyeDetector = new CascadeClassifier(filename);
|
||||
Logger.info("EyeDetector loaded");
|
||||
} catch (Exception e){
|
||||
Logger.error("Exception on loading EyeDetector : " + e.getMessage());
|
||||
}
|
||||
|
||||
} else Logger.info("EyeDetector already loaded");
|
||||
} 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
|
||||
* @return List of Rect if face detected, otherwise empty list
|
||||
*/
|
||||
public static @NonNull List<DetectorResult> HaveFrontalFace(UMat graymat){
|
||||
List<DetectorResult> result = new ArrayList<>();
|
||||
RectVector faces = DetectFrontalFace(graymat);
|
||||
if (faces!=null && faces.size()>0){
|
||||
|
||||
for(Rect face : faces.get()){
|
||||
RectVector eyes = DetectEye(graymat);
|
||||
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);
|
||||
}
|
||||
}
|
||||
result.add(dr);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static @NonNull List<DetectorResult> HaveLeft45Face(UMat graymat){
|
||||
List<DetectorResult> result = new ArrayList<>();
|
||||
RectVector faces = DetectProfileFace(graymat);
|
||||
if (faces!=null && faces.size()>0){
|
||||
|
||||
for(Rect face : faces.get()){
|
||||
RectVector eyes = DetectEye(graymat);
|
||||
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);
|
||||
}
|
||||
}
|
||||
result.add(dr);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static void setScaleFactor(double value){
|
||||
if (scaleFactor!=value) scaleFactor = value;
|
||||
}
|
||||
|
||||
public static void setFaceMinSize(int value){
|
||||
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());
|
||||
}
|
||||
} 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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
} 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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static RectVector DetectProfileFace(UMat graymat){
|
||||
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
|
||||
* @return RectVector if face detected, otherwise null
|
||||
*/
|
||||
public static RectVector DetectFrontalFace(UMat graymat){
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static RectVector Detect(UMat graymat, CascadeClassifier detector){
|
||||
if (detector!=null){
|
||||
if (graymat!=null){
|
||||
if (!graymat.empty()){
|
||||
RectVector detected = new RectVector();
|
||||
detector.detectMultiScale(graymat, detected);
|
||||
return detected;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
private static RectVector Detect(UMat graymat, CascadeClassifier detector, double scaleFactor, int minNeighbors, int flags, Size minSize, Size maxSize){
|
||||
if (detector!=null){
|
||||
if (graymat!=null){
|
||||
if (!graymat.empty()){
|
||||
if (minSize!=null){
|
||||
if (maxSize!=null){
|
||||
RectVector detected = new RectVector();
|
||||
detector.detectMultiScale(graymat, detected, scaleFactor, minNeighbors, flags, minSize, maxSize);
|
||||
return detected;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,45 +1,97 @@
|
||||
package id.co.gtc.erhacam;
|
||||
|
||||
import Config.SomeCodes;
|
||||
import SecureDongle.SecureDongle;
|
||||
import SecureDongle.SecureDongleEvent;
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.geometry.Rectangle2D;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.stage.Screen;
|
||||
import javafx.stage.Stage;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static Config.SomeCodes.ShowAlert;
|
||||
import static Config.SomeCodes.config;
|
||||
|
||||
|
||||
public class MainApplication extends Application {
|
||||
@Override
|
||||
public void start(Stage stage) throws IOException {
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(MainApplication.class.getResource("main-view.fxml"));
|
||||
Screen screen = Screen.getPrimary();
|
||||
Rectangle2D screenbound = screen.getVisualBounds();
|
||||
Scene scene = new Scene(fxmlLoader.load(), screenbound.getWidth(), screenbound.getHeight());
|
||||
stage.setTitle("MultiCam Capture App for ERHA");
|
||||
stage.setScene(scene);
|
||||
stage.setResizable(true);
|
||||
stage.setMaximized(true);
|
||||
stage.setOnCloseRequest(e->{
|
||||
config.Save();
|
||||
MainView mainView = fxmlLoader.getController();
|
||||
mainView.Unload();
|
||||
Logger.info("Application closed");
|
||||
});
|
||||
SomeCodes.LoadQRReader();
|
||||
SomeCodes.LoadFaceDetector();
|
||||
stage.show();
|
||||
Logger.info("Application started");
|
||||
SecureDongle sd = new SecureDongle((short)0x4B30, (short)0xA66C, (short)0x3109, (short)0x37B1);
|
||||
if (sd.Find()){
|
||||
if (sd.Open()){
|
||||
String UserID = Integer.toHexString(sd.ReadUserID()) ;
|
||||
sd.Close();
|
||||
|
||||
if (UserID.equals("14022025")){
|
||||
Logger.info("Secure Dongle UserID valid");
|
||||
FXMLLoader fxmlLoader = new FXMLLoader(MainApplication.class.getResource("main-view.fxml"));
|
||||
Screen screen = Screen.getPrimary();
|
||||
Rectangle2D screenbound = screen.getVisualBounds();
|
||||
Scene scene = new Scene(fxmlLoader.load(), screenbound.getWidth(), screenbound.getHeight());
|
||||
stage.setTitle("MultiCam Capture App for ERHA 11032025-006");
|
||||
stage.setScene(scene);
|
||||
stage.setResizable(true);
|
||||
stage.setMaximized(true);
|
||||
stage.setOnCloseRequest(e->{
|
||||
sd.StopMonitor();
|
||||
config.Save();
|
||||
MainView mainView = fxmlLoader.getController();
|
||||
mainView.Unload();
|
||||
Logger.info("Application closed");
|
||||
});
|
||||
SomeCodes.LoadQRReader();
|
||||
Detectors.LoadAllDetectors();
|
||||
|
||||
stage.show();
|
||||
|
||||
Logger.info("Application started");
|
||||
sd.setEvent(new SecureDongleEvent() {
|
||||
@Override
|
||||
public void onDongleMissing() {
|
||||
Logger.error("Secure Dongle Missing");
|
||||
Platform.runLater(()->{
|
||||
ShowAlert(Alert.AlertType.ERROR, "Secure Dongle Missing", "Secure Dongle Missing", "Secure Dongle Missing");
|
||||
Platform.exit();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDongleError(String function, int errorCode) {
|
||||
|
||||
}
|
||||
});
|
||||
sd.StartMonitor();
|
||||
|
||||
} else {
|
||||
ShowAlert(Alert.AlertType.ERROR, "Secure Dongle UserID not valid", "Secure Dongle UserID not valid", "Secure Dongle UserID not valid");
|
||||
Logger.error("Secure Dongle UserID not valid");
|
||||
Platform.exit();
|
||||
}
|
||||
|
||||
} else {
|
||||
ShowAlert(Alert.AlertType.ERROR, "Secure Dongle cannot be opened", "Secure Dongle cannot be opened", "Secure Dongle cannot be opened");
|
||||
Logger.error("Secure Dongle cannot be opened");
|
||||
Platform.exit();
|
||||
}
|
||||
} else {
|
||||
ShowAlert(Alert.AlertType.ERROR, "Secure Dongle not found", "Secure Dongle not found", "Secure Dongle not found");
|
||||
Logger.error("Secure Dongle not found");
|
||||
Platform.exit();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SomeCodes.ExtractResource("/tinylog.properties");
|
||||
launch();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -59,7 +59,7 @@ public class MainView {
|
||||
|
||||
@FXML
|
||||
private void initialize(){
|
||||
ReviewClick(null);
|
||||
CaptureClick(null);
|
||||
}
|
||||
|
||||
public void Unload(){
|
||||
@@ -92,8 +92,8 @@ public class MainView {
|
||||
currentcontroller = loader.getController();
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.error("Unable to load " + fxmlfile + ", exception : " + e.getMessage());
|
||||
Logger.error("Unable to load " ,fxmlfile, ", exception : ", e.getMessage());
|
||||
}
|
||||
} else Logger.info("Not loading empty fxml file");
|
||||
} else Logger.error("loadContent Not loading empty fxml file");
|
||||
}
|
||||
}
|
||||
@@ -15,6 +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;
|
||||
|
||||
public class PhotoRow {
|
||||
@@ -47,18 +48,22 @@ public class PhotoRow {
|
||||
imgview.setStyle(borderstyle);
|
||||
imgview.setOnMouseClicked(e->{
|
||||
if (e.getClickCount()>=2){
|
||||
//System.out.println("Photo path: "+photopath);
|
||||
File ff = new File(photopath);
|
||||
String hires = Path.of(config.getPhotoDirectory(), ff.getName()).toString();
|
||||
// System.out.println("Config exists : "+(config!=null));
|
||||
// System.out.println("Photo directory: "+config.getPhotoDirectory());
|
||||
// System.out.println("Full quality directory: "+config.getFullQualityDirectory());
|
||||
// System.out.println("Full Quality Crop directory: "+config.getFullQualityCropDirectory());
|
||||
// System.out.println("Reduced quality directory: "+config.getCompressedDirectory());
|
||||
// System.out.println("Reduced quality crop directory: "+config.getCompressedCropDirectory());
|
||||
//String hires = Path.of(config.getPhotoDirectory(), ff.getName()).toString();
|
||||
String hires = Path.of(config.getFullQualityDirectory(), ff.getName()).toString();
|
||||
//System.out.println("Hires: "+hires);
|
||||
File hiresfile = new File(hires);
|
||||
if (hiresfile.isFile()){
|
||||
System.out.println("Opening file: "+hires);
|
||||
SomeCodes.OpenPictureInDefaultViewer(hires);
|
||||
} else {
|
||||
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||
alert.setTitle("Error");
|
||||
alert.setHeaderText("File not found");
|
||||
alert.setContentText("File not found: "+hires);
|
||||
alert.showAndWait();
|
||||
}
|
||||
} else ShowAlert(Alert.AlertType.ERROR, "Error", "File not found", "File not found: "+hires);
|
||||
e.consume();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -6,6 +6,7 @@ import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Alert;
|
||||
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;
|
||||
@@ -13,20 +14,9 @@ import org.tinylog.Logger;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static Config.SomeCodes.config;
|
||||
import static Config.SomeCodes.*;
|
||||
|
||||
public class SettingView {
|
||||
@FXML
|
||||
private TextField AudioPhase1;
|
||||
@FXML
|
||||
private TextField AudioPhase2;
|
||||
@FXML
|
||||
private TextField AudioPhase3;
|
||||
@FXML
|
||||
private TextField AudioPhase4;
|
||||
@FXML
|
||||
private TextField AudioPhase5;
|
||||
|
||||
@FXML
|
||||
private ComboBox<String> CameraLeft90;
|
||||
@FXML
|
||||
@@ -49,10 +39,77 @@ public class SettingView {
|
||||
@FXML
|
||||
private TextField FTPPath;
|
||||
|
||||
@FXML
|
||||
private TextField PhotoDirectoryPath;
|
||||
|
||||
|
||||
|
||||
final FileChooser jfc = new FileChooser();
|
||||
|
||||
String[] cameranames = null;
|
||||
|
||||
@FXML
|
||||
private TextField cascadeMinSize;
|
||||
|
||||
@FXML
|
||||
private TextField cascadeScaleFactor;
|
||||
|
||||
@FXML
|
||||
private TextField cascadeMaxSize;
|
||||
|
||||
@FXML
|
||||
private void ChangePhotoDirectoryPath(){
|
||||
DirectoryChooser dc = new DirectoryChooser();
|
||||
dc.setTitle("Select Directory");
|
||||
String path = dc.showDialog(null).getAbsolutePath();
|
||||
|
||||
config.SetPhotoDirectory(path);
|
||||
config.Save();
|
||||
PhotoDirectoryPath.setText(path);
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void CascadeSettingApply(){
|
||||
String minsize = cascadeMinSize.getText();
|
||||
String scalefactor = cascadeScaleFactor.getText();
|
||||
String maxsize = cascadeMaxSize.getText();
|
||||
|
||||
if (ValidString(minsize)){
|
||||
if (ValidString(maxsize)){
|
||||
if (ValidString(scalefactor)){
|
||||
try{
|
||||
int min = Integer.parseInt(minsize);
|
||||
double scale = Double.parseDouble(scalefactor);
|
||||
int max = Integer.parseInt(maxsize);
|
||||
if (scale> 1.0){
|
||||
if (min>0){
|
||||
if (max>min){
|
||||
config.setCascadeMaxSize(max);
|
||||
config.setCascadeMinSize(min);
|
||||
config.setCascadeScaleFactor(scale);
|
||||
config.Save();
|
||||
|
||||
Detectors.setFaceMaxSize(max);
|
||||
Detectors.setFaceMinSize(min);
|
||||
Detectors.setScaleFactor(scale);
|
||||
ShowAlert(Alert.AlertType.INFORMATION, "Cascade Setting", "Cascade Setting Saved", "Cascade Setting Saved Successfully");
|
||||
|
||||
} else show_cascade_alert("Max Size must be greater than Min Size");
|
||||
} else show_cascade_alert("Min Size must be greater than 0");
|
||||
} else show_cascade_alert("Scale Factor must be greater than 1.0");
|
||||
} catch (NumberFormatException e){
|
||||
show_cascade_alert("Min Size, Scale Factor, and Max Size must be a number");
|
||||
}
|
||||
} else show_cascade_alert("Scale Factor must not empty");
|
||||
} else show_cascade_alert("Max Size must not empty");
|
||||
} else show_cascade_alert("Min Size must not empty");
|
||||
|
||||
}
|
||||
|
||||
private void show_cascade_alert(String content){
|
||||
ShowAlert(Alert.AlertType.ERROR, "Cascade Setting Error", "Cascade Setting Error", content);
|
||||
}
|
||||
|
||||
@FXML
|
||||
public void initialize(){
|
||||
FileChooser.ExtensionFilter filter = new FileChooser.ExtensionFilter("Audio File", "wav","mp3");
|
||||
@@ -70,11 +127,6 @@ public class SettingView {
|
||||
|
||||
|
||||
Platform.runLater(()->{
|
||||
AudioPhase1.setText(config.getAudioPhase1());
|
||||
AudioPhase2.setText(config.getAudioPhase2());
|
||||
AudioPhase3.setText(config.getAudioPhase3());
|
||||
AudioPhase4.setText(config.getAudioPhase4());
|
||||
AudioPhase5.setText(config.getAudioPhase5());
|
||||
|
||||
CameraLeft90.getItems().clear();
|
||||
CameraLeft45.getItems().clear();
|
||||
@@ -108,6 +160,12 @@ public class SettingView {
|
||||
FTPUser.setText(config.getFTPUser());
|
||||
FTPPass.setText(config.getFTPPass());
|
||||
FTPPath.setText(config.getFTPPath());
|
||||
|
||||
PhotoDirectoryPath.setText(config.getPhotoDirectory());
|
||||
|
||||
cascadeScaleFactor.setText(String.valueOf(config.getCascadeScaleFactor()));
|
||||
cascadeMinSize.setText(String.valueOf(config.getCascadeMinSize()));
|
||||
cascadeMaxSize.setText(String.valueOf(config.getCascadeMaxSize()));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -115,52 +173,6 @@ public class SettingView {
|
||||
config.Save();
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void BrowseAudioPhase1(){
|
||||
File file = jfc.showOpenDialog(null);
|
||||
if (file!=null){
|
||||
config.SetAudioPhase1(file.getAbsolutePath());
|
||||
AudioPhase1.setText(config.getAudioPhase1());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void BrowseAudioPhase2(){
|
||||
File file = jfc.showOpenDialog(null);
|
||||
if (file!=null){
|
||||
config.SetAudioPhase2(file.getAbsolutePath());
|
||||
AudioPhase2.setText(config.getAudioPhase2());
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void BrowseAudioPhase3(){
|
||||
File file = jfc.showOpenDialog(null);
|
||||
if (file!=null){
|
||||
config.SetAudioPhase3(file.getAbsolutePath());
|
||||
AudioPhase3.setText(config.getAudioPhase3());
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void BrowseAudioPhase4(){
|
||||
File file = jfc.showOpenDialog(null);
|
||||
if (file!=null){
|
||||
config.SetAudioPhase4(file.getAbsolutePath());
|
||||
AudioPhase4.setText(config.getAudioPhase4());
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void BrowseAudioPhase5(){
|
||||
File file = jfc.showOpenDialog(null);
|
||||
if (file!=null){
|
||||
config.SetAudioPhase5(file.getAbsolutePath());
|
||||
AudioPhase5.setText(config.getAudioPhase5());
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void ApplyCameraLeft90(){
|
||||
config.SetCameraLeft90(CameraLeft90.getValue());
|
||||
@@ -198,18 +210,8 @@ public class SettingView {
|
||||
config.SetFTPPass(FTPPass.getText());
|
||||
config.SetFTPPath(FTPPath.getText());
|
||||
|
||||
val alert = new Alert(Alert.AlertType.INFORMATION);
|
||||
alert.setTitle("FTP Configuration");
|
||||
alert.setHeaderText("FTP Configuration Saved");
|
||||
alert.setContentText("FTP Configuration Saved Successfully");
|
||||
alert.showAndWait();
|
||||
} else {
|
||||
val alert = new Alert(Alert.AlertType.ERROR);
|
||||
alert.setTitle("FTP Error");
|
||||
alert.setHeaderText("FTP Configuration Error");
|
||||
alert.setContentText("FTP Configuration is incorrect, please check your FTP Configuration");
|
||||
alert.showAndWait();
|
||||
}
|
||||
ShowAlert(Alert.AlertType.INFORMATION, "FTP Configuration", "FTP Configuration Saved", "FTP Configuration Saved Successfully");
|
||||
} else ShowAlert(Alert.AlertType.ERROR, "FTP Error", "FTP Configuration Error", "FTP Configuration is incorrect, please check your FTP Configuration");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,11 +15,14 @@ module id.co.gtc.erhacam {
|
||||
requires org.tinylog.api;
|
||||
requires java.sql;
|
||||
requires javafx.graphics;
|
||||
requires java.net.http;
|
||||
|
||||
|
||||
opens id.co.gtc.erhacam to javafx.fxml;
|
||||
opens BASS to com.sun.jna;
|
||||
opens Config to com.google.gson;
|
||||
opens Database to javafx.base;
|
||||
opens ErhaAPI to com.google.gson;
|
||||
exports id.co.gtc.erhacam;
|
||||
|
||||
}
|
||||
@@ -39,6 +39,7 @@ import java.time.LocalDateTime;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static Config.SomeCodes.*;
|
||||
import static id.co.gtc.erhacam.Detectors.frontalfaceDetector;
|
||||
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;
|
||||
@@ -638,7 +639,7 @@ public class Cameradetail_Arducam {
|
||||
Capturing.set(false);
|
||||
if (mGrabber!=null){
|
||||
try{
|
||||
mGrabber.stop();
|
||||
mGrabber.close();
|
||||
Platform.runLater(()->setCameraStatus("Camera Stopped"));
|
||||
} catch (Exception e){
|
||||
if (event!=null) event.onLog("StopLiveView failed, Unable to Stop Camera, Error: " + e.getMessage());
|
||||
@@ -705,12 +706,12 @@ public class Cameradetail_Arducam {
|
||||
if (use_face){
|
||||
RectVector face = DetectFace(graymat);
|
||||
if (face!=null && face.size()>0){
|
||||
if (event!=null) event.onFaceDetector(true,photoWidth, photoHeight);
|
||||
if (event!=null) event.onFrontalFaceDetector(true,photoWidth, photoHeight);
|
||||
for(int i=0; i<face.size(); i++){
|
||||
val rect = face.get(i);
|
||||
rectangle(umat, rect, Scalar.GREEN);
|
||||
}
|
||||
} else if (event!=null) event.onFaceDetector(false, photoWidth, photoHeight);
|
||||
} else if (event!=null) event.onFrontalFaceDetector(false, photoWidth, photoHeight);
|
||||
|
||||
}
|
||||
|
||||
@@ -782,9 +783,9 @@ public class Cameradetail_Arducam {
|
||||
* @return true if face detected, otherwise false
|
||||
*/
|
||||
private RectVector DetectFace(UMat graymat){
|
||||
if (faceDetector!=null){
|
||||
if (frontalfaceDetector!=null){
|
||||
val face = new RectVector();
|
||||
faceDetector.detectMultiScale(graymat, face);
|
||||
frontalfaceDetector.detectMultiScale(graymat, face);
|
||||
return face;
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<?import javafx.scene.image.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
|
||||
<AnchorPane prefHeight="280.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.14-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="id.co.gtc.erhacam.Cameradetail">
|
||||
<AnchorPane prefHeight="720.0" prefWidth="360.0" xmlns="http://javafx.com/javafx/11.0.14-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="id.co.gtc.erhacam.Cameradetail">
|
||||
<children>
|
||||
<GridPane layoutX="5.0" layoutY="5.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<columnConstraints>
|
||||
@@ -46,15 +46,31 @@
|
||||
<GridPane layoutX="-28.0" layoutY="-29.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
|
||||
<ColumnConstraints fillWidth="false" minWidth="10.0" percentWidth="20.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="-Infinity" minHeight="10.0" prefHeight="10.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<AnchorPane GridPane.columnIndex="1">
|
||||
<AnchorPane fx:id="streamanchor">
|
||||
<children>
|
||||
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="240.0" prefWidth="140.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<StackPane layoutY="5.0" prefHeight="669.6" prefWidth="350.4" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<children>
|
||||
<ImageView fx:id="camerastream" fitWidth="340.0" pickOnBounds="true" preserveRatio="true" smooth="false" StackPane.alignment="CENTER">
|
||||
<viewport>
|
||||
<Rectangle2D height="640.0" width="360.0" />
|
||||
</viewport>
|
||||
</ImageView>
|
||||
</children>
|
||||
</StackPane>
|
||||
</children>
|
||||
<GridPane.margin>
|
||||
<Insets />
|
||||
</GridPane.margin>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="240.0" prefWidth="140.0" visible="false" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<children>
|
||||
<Label text="Brightness" />
|
||||
<Slider fx:id="brightnessSlider" min="-100.0">
|
||||
@@ -101,19 +117,6 @@
|
||||
</VBox>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane fx:id="streamanchor">
|
||||
<children>
|
||||
<StackPane prefHeight="240.0" prefWidth="351.2" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<children>
|
||||
<ImageView fx:id="camerastream" fitHeight="240.0" pickOnBounds="true">
|
||||
<image>
|
||||
<Image url="@gtcbackground.png" />
|
||||
</image>
|
||||
</ImageView>
|
||||
</children>
|
||||
</StackPane>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</children>
|
||||
</GridPane>
|
||||
</children>
|
||||
|
||||
127
src/main/resources/id/co/gtc/erhacam/cameradetail_landscape.fxml
Normal file
127
src/main/resources/id/co/gtc/erhacam/cameradetail_landscape.fxml
Normal file
@@ -0,0 +1,127 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.image.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
|
||||
<AnchorPane prefHeight="280.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.14-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="id.co.gtc.erhacam.Cameradetail">
|
||||
<children>
|
||||
<GridPane layoutX="5.0" layoutY="5.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="-Infinity" minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<AnchorPane minHeight="30.0" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<GridPane AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="20.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<AnchorPane>
|
||||
<children>
|
||||
<Label fx:id="cameratitle" alignment="CENTER" style="-fx-border-color: black;" text="Camera Title" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane GridPane.columnIndex="1">
|
||||
<children>
|
||||
<Label fx:id="camerastatus" alignment="CENTER" style="-fx-border-color: black;" text="Camera Status" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</children>
|
||||
</GridPane>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0">
|
||||
<children>
|
||||
<GridPane layoutX="-28.0" layoutY="-29.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
|
||||
<ColumnConstraints fillWidth="false" minWidth="10.0" percentWidth="20.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<AnchorPane GridPane.columnIndex="1">
|
||||
<children>
|
||||
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="240.0" prefWidth="140.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<children>
|
||||
<Label text="Brightness" />
|
||||
<Slider fx:id="brightnessSlider" min="-100.0">
|
||||
<VBox.margin>
|
||||
<Insets />
|
||||
</VBox.margin>
|
||||
</Slider>
|
||||
<Label text="Contrast" />
|
||||
<Slider fx:id="contrastSlider" layoutX="10.0" layoutY="28.0" min="-100.0">
|
||||
<VBox.margin>
|
||||
<Insets />
|
||||
</VBox.margin>
|
||||
</Slider>
|
||||
<Label layoutX="10.0" layoutY="42.0" text="Saturation" />
|
||||
<Slider fx:id="saturationSlider" layoutX="10.0" layoutY="60.0" min="-100.0">
|
||||
<VBox.margin>
|
||||
<Insets />
|
||||
</VBox.margin>
|
||||
</Slider>
|
||||
<Label layoutX="10.0" layoutY="74.0" text="Hue" />
|
||||
<Slider fx:id="hueSlider" layoutX="10.0" layoutY="92.0" min="-100.0" prefHeight="14.0" prefWidth="63.0">
|
||||
<VBox.margin>
|
||||
<Insets />
|
||||
</VBox.margin>
|
||||
</Slider>
|
||||
<Label layoutX="10.0" layoutY="106.0" text="Gain" />
|
||||
<Slider fx:id="gainSlider" layoutX="10.0" layoutY="124.0" min="-100.0">
|
||||
<VBox.margin>
|
||||
<Insets />
|
||||
</VBox.margin>
|
||||
</Slider>
|
||||
<Label layoutX="10.0" layoutY="138.0" text="Exposure" />
|
||||
<Slider fx:id="exposureSlider" layoutX="10.0" layoutY="156.0" min="-100.0">
|
||||
<VBox.margin>
|
||||
<Insets />
|
||||
</VBox.margin>
|
||||
</Slider>
|
||||
<Button maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#resetClick" text="Reset">
|
||||
<VBox.margin>
|
||||
<Insets left="5.0" right="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</Button>
|
||||
</children>
|
||||
</VBox>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane fx:id="streamanchor">
|
||||
<children>
|
||||
<StackPane AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<children>
|
||||
<ImageView fx:id="camerastream" fitWidth="240.0" pickOnBounds="true">
|
||||
<image>
|
||||
<Image url="@gtcbackground.png" />
|
||||
</image>
|
||||
</ImageView>
|
||||
</children>
|
||||
</StackPane>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</children>
|
||||
</GridPane>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</children>
|
||||
</GridPane>
|
||||
</children>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding>
|
||||
</AnchorPane>
|
||||
@@ -3,108 +3,112 @@
|
||||
<?import javafx.geometry.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
|
||||
<AnchorPane fx:id="CaptureViewAnchor" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="768.0" prefWidth="1024.0" xmlns="http://javafx.com/javafx/11.0.14-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="id.co.gtc.erhacam.CaptureView">
|
||||
<children>
|
||||
<GridPane layoutX="99.0" layoutY="147.0" style="-fx-grid-lines-visible: true;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<GridPane layoutX="147.0" layoutY="239.0" AnchorPane.bottomAnchor="200.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<AnchorPane fx:id="cam1" prefHeight="200.0" prefWidth="200.0" />
|
||||
<AnchorPane fx:id="cam2" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" />
|
||||
<AnchorPane fx:id="cam3" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2" />
|
||||
<AnchorPane fx:id="cam4" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="3" />
|
||||
<AnchorPane fx:id="cam5" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="4" />
|
||||
</children>
|
||||
</GridPane>
|
||||
<GridPane layoutX="99.0" layoutY="147.0" style="-fx-grid-lines-visible: true;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="-Infinity" minHeight="10.0" prefHeight="175.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<AnchorPane fx:id="cam1" prefHeight="200.0" prefWidth="200.0" />
|
||||
<AnchorPane fx:id="cam3" prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="1" />
|
||||
<AnchorPane fx:id="cam5" prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="2" />
|
||||
<AnchorPane fx:id="cam2" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" />
|
||||
<AnchorPane fx:id="cam4" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="1" />
|
||||
<AnchorPane fx:id="controlpane" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<VBox layoutX="108.0" layoutY="14.0" prefHeight="256.0" prefWidth="512.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<children>
|
||||
<GridPane>
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="30.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0">
|
||||
<children>
|
||||
<Label layoutX="28.0" layoutY="8.0" prefHeight="30.0" prefWidth="154.0" text="Save Directory" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<Label layoutX="31.0" layoutY="6.0" prefHeight="30.0" prefWidth="154.0" text="Patient ID" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1">
|
||||
<children>
|
||||
<TextArea fx:id="directorypath" editable="false" layoutX="14.0" layoutY="-86.0" prefHeight="114.0" prefWidth="358.0" promptText="Directory to save Photos" wrapText="true" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<TextArea fx:id="prefixfile" layoutX="-21.0" layoutY="-85.0" prefHeight="115.0" prefWidth="358.0" promptText="Some identification for easy find" wrapText="true" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</children>
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</GridPane>
|
||||
<GridPane>
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0">
|
||||
<children>
|
||||
<Button layoutX="42.0" layoutY="14.0" mnemonicParsing="false" onAction="#ChangeDirectory" prefHeight="70.0" prefWidth="171.0" text="Change Directory" wrapText="true" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1">
|
||||
<children>
|
||||
<Button layoutX="72.0" layoutY="35.0" mnemonicParsing="false" onAction="#AutoFocus" prefHeight="70.0" prefWidth="171.0" text="Auto Focus" wrapText="true" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2">
|
||||
<children>
|
||||
<Button fx:id="btnTakePhoto" layoutX="59.0" layoutY="23.0" mnemonicParsing="false" onAction="#TakePhotos" prefHeight="70.0" prefWidth="170.0" text="Take Photos" wrapText="true" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</children>
|
||||
<VBox.margin>
|
||||
<Insets top="5.0" />
|
||||
</VBox.margin>
|
||||
</GridPane>
|
||||
<ScrollPane prefHeight="200.0" prefWidth="200.0">
|
||||
<content>
|
||||
<AnchorPane fx:id="progressanchor" />
|
||||
</content>
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</ScrollPane>
|
||||
</children>
|
||||
</VBox>
|
||||
</children>
|
||||
<AnchorPane fx:id="controlpane" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1">
|
||||
<padding>
|
||||
<Insets top="5.0" />
|
||||
</padding></AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0">
|
||||
<children>
|
||||
<GridPane layoutX="68.0" layoutY="14.0" prefHeight="175.2" prefWidth="512.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="30.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0">
|
||||
<children>
|
||||
<Label layoutX="31.0" layoutY="6.0" prefHeight="30.0" prefWidth="154.0" text="Nomor Barcode" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0">
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<Label layoutX="63.0" layoutY="6.0" prefHeight="30.4" prefWidth="154.4" text="Medical Record ID" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0">
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<Label layoutX="63.0" layoutY="5.0" prefHeight="30.4" prefWidth="154.4" text="Patient Name" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0">
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1">
|
||||
<children>
|
||||
<TextArea fx:id="barcodeData" editable="false" layoutX="-21.0" layoutY="-85.0" prefHeight="115.0" prefWidth="358.0" promptText="barcode read result" wrapText="true" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0">
|
||||
<font>
|
||||
<Font size="18.0" />
|
||||
</font>
|
||||
</TextArea>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<TextArea fx:id="medicalRecordID" editable="false" layoutX="14.0" layoutY="-84.0" prefHeight="116.0" prefWidth="358.4" promptText="medical record ID" wrapText="true" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0">
|
||||
<font>
|
||||
<Font size="18.0" />
|
||||
</font>
|
||||
</TextArea>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<TextArea fx:id="PatientName" editable="false" layoutX="-21.0" layoutY="-84.0" prefHeight="116.0" prefWidth="358.4" promptText="patient name" wrapText="true" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0">
|
||||
<font>
|
||||
<Font size="18.0" />
|
||||
</font>
|
||||
</TextArea>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</children>
|
||||
</GridPane>
|
||||
</children></AnchorPane>
|
||||
</children>
|
||||
</GridPane>
|
||||
</children>
|
||||
|
||||
111
src/main/resources/id/co/gtc/erhacam/capture-view_landscape.fxml
Normal file
111
src/main/resources/id/co/gtc/erhacam/capture-view_landscape.fxml
Normal file
@@ -0,0 +1,111 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
|
||||
<AnchorPane fx:id="CaptureViewAnchor" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefHeight="768.0" prefWidth="1024.0" xmlns="http://javafx.com/javafx/11.0.14-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="id.co.gtc.erhacam.CaptureView">
|
||||
<children>
|
||||
<GridPane layoutX="99.0" layoutY="147.0" style="-fx-grid-lines-visible: true;" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<AnchorPane fx:id="cam1" prefHeight="200.0" prefWidth="200.0" />
|
||||
<AnchorPane fx:id="cam3" prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="1" />
|
||||
<AnchorPane fx:id="cam5" prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="2" />
|
||||
<AnchorPane fx:id="cam2" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" />
|
||||
<AnchorPane fx:id="cam4" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="1" />
|
||||
<AnchorPane fx:id="controlpane" prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<VBox layoutX="108.0" layoutY="14.0" prefHeight="256.0" prefWidth="512.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<children>
|
||||
<GridPane>
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="30.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0">
|
||||
<children>
|
||||
<Label layoutX="28.0" layoutY="8.0" prefHeight="30.0" prefWidth="154.0" text="Save Directory" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<Label layoutX="31.0" layoutY="6.0" prefHeight="30.0" prefWidth="154.0" text="Patient ID" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1">
|
||||
<children>
|
||||
<TextArea fx:id="directorypath" editable="false" layoutX="14.0" layoutY="-86.0" prefHeight="114.0" prefWidth="358.0" promptText="Directory to save Photos" wrapText="true" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<TextArea fx:id="prefixfile" layoutX="-21.0" layoutY="-85.0" prefHeight="115.0" prefWidth="358.0" promptText="Some identification for easy find" wrapText="true" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</children>
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</GridPane>
|
||||
<GridPane>
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0">
|
||||
<children>
|
||||
<Button layoutX="42.0" layoutY="14.0" mnemonicParsing="false" onAction="#ChangeDirectory" prefHeight="70.0" prefWidth="171.0" text="Change Directory" wrapText="true" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1">
|
||||
<children>
|
||||
<Button fx:id="btnAutoFocus" layoutX="72.0" layoutY="35.0" mnemonicParsing="false" onAction="#AutoFocus" prefHeight="70.0" prefWidth="171.0" text="Auto Focus" wrapText="true" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2">
|
||||
<children>
|
||||
<Button fx:id="btnTakePhoto" layoutX="59.0" layoutY="23.0" mnemonicParsing="false" onAction="#TakePhotos" prefHeight="70.0" prefWidth="170.0" text="Take Photos" wrapText="true" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</children>
|
||||
<VBox.margin>
|
||||
<Insets top="5.0" />
|
||||
</VBox.margin>
|
||||
</GridPane>
|
||||
<ScrollPane prefHeight="200.0" prefWidth="200.0">
|
||||
<content>
|
||||
<AnchorPane fx:id="progressanchor" />
|
||||
</content>
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</ScrollPane>
|
||||
</children>
|
||||
</VBox>
|
||||
</children>
|
||||
<padding>
|
||||
<Insets top="5.0" />
|
||||
</padding></AnchorPane>
|
||||
</children>
|
||||
</GridPane>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
@@ -19,16 +19,19 @@
|
||||
<RowConstraints minHeight="36.0" prefHeight="36.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0">
|
||||
<children>
|
||||
<Button fx:id="ReviewButton" layoutX="99.0" layoutY="2.0" mnemonicParsing="false" onAction="#ReviewClick" text="Review" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1">
|
||||
<children>
|
||||
<Button fx:id="CaptureButton" layoutX="103.0" layoutY="6.0" mnemonicParsing="false" onAction="#CaptureClick" text="Capture" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
<children>
|
||||
<Button fx:id="CaptureButton" layoutX="103.0" layoutY="6.0" mnemonicParsing="false" onAction="#CaptureClick" text="Capture" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2">
|
||||
<children>
|
||||
<Button fx:id="SettingButton" layoutX="64.0" layoutY="2.0" mnemonicParsing="false" onAction="#SettingClick" text="Setting" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="0.0" />
|
||||
|
||||
@@ -1,16 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.ComboBox?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.TextField?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
|
||||
<AnchorPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefWidth="1024.0" xmlns="http://javafx.com/javafx/22" xmlns:fx="http://javafx.com/fxml/1" fx:controller="id.co.gtc.erhacam.SettingView">
|
||||
<AnchorPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" prefWidth="1024.0" xmlns="http://javafx.com/javafx/11.0.14-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="id.co.gtc.erhacam.SettingView">
|
||||
<children>
|
||||
<GridPane layoutX="70.0" layoutY="78.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<columnConstraints>
|
||||
@@ -21,217 +14,205 @@
|
||||
<RowConstraints minHeight="200.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="200.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="200.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="40.0" prefHeight="40.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0">
|
||||
<children>
|
||||
<Label alignment="CENTER" layoutX="44.0" layoutY="7.0" text="Audio Setting" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<Label alignment="CENTER" layoutX="195.0" layoutY="7.0" text="Camera Setting" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="4">
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<Label alignment="CENTER" layoutX="239.0" layoutY="8.0" text="FTP Setting" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<GridPane layoutX="149.0" layoutY="-29.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="15.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="15.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0">
|
||||
<GridPane AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="40.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<GridPane>
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="15.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="15.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<Label layoutX="62.0" layoutY="8.0" text="Phase 1 File" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0">
|
||||
<children>
|
||||
<Label layoutX="30.0" layoutY="12.0" prefHeight="40.8" prefWidth="87.2" text="Left 90" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<Label layoutX="44.0" layoutY="12.0" prefHeight="40.8" prefWidth="87.2" text="Left 45" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<Label layoutX="30.0" layoutY="6.0" prefHeight="40.8" prefWidth="87.2" text="Center" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="3">
|
||||
<children>
|
||||
<Label layoutX="24.0" layoutY="6.0" prefHeight="40.0" prefWidth="87.2" text="Right 45" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="4">
|
||||
<children>
|
||||
<Label layoutX="36.0" layoutY="11.0" prefHeight="40.0" prefWidth="87.2" text="Right 90" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1">
|
||||
<children>
|
||||
<ComboBox fx:id="CameraLeft90" layoutX="54.0" layoutY="8.0" prefHeight="40.8" prefWidth="408.0" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<ComboBox fx:id="CameraLeft45" layoutX="26.0" layoutY="14.0" prefHeight="40.8" prefWidth="408.0" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<ComboBox fx:id="CameraCenter" layoutX="88.0" layoutY="8.0" prefHeight="40.8" prefWidth="408.0" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="3">
|
||||
<children>
|
||||
<ComboBox fx:id="CameraRight45" layoutX="54.0" layoutY="8.0" prefHeight="40.0" prefWidth="408.0" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="4">
|
||||
<children>
|
||||
<ComboBox fx:id="CameraRight90" layoutX="75.0" layoutY="1.0" prefHeight="40.0" prefWidth="408.0" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2">
|
||||
<children>
|
||||
<Button layoutY="8.0" mnemonicParsing="false" onAction="#ApplyCameraLeft90" prefHeight="40.8" prefWidth="88.0" text="Apply" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<Button layoutX="22.0" layoutY="2.0" mnemonicParsing="false" onAction="#ApplyCameraLeft45" prefHeight="40.8" prefWidth="88.0" text="Apply" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<Button layoutX="18.0" layoutY="2.0" mnemonicParsing="false" onAction="#ApplyCameraFront" prefHeight="40.8" prefWidth="88.0" text="Apply" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2" GridPane.rowIndex="3">
|
||||
<children>
|
||||
<Button layoutX="22.0" layoutY="8.0" mnemonicParsing="false" onAction="#ApplyCameraRight45" prefHeight="40.0" prefWidth="88.0" text="Apply" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2" GridPane.rowIndex="4">
|
||||
<children>
|
||||
<Button layoutX="22.0" layoutY="8.0" mnemonicParsing="false" onAction="#ApplyCameraRight90" prefHeight="40.0" prefWidth="88.0" text="Apply" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</children>
|
||||
</GridPane>
|
||||
<GridPane GridPane.columnIndex="1">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="-Infinity" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<AnchorPane GridPane.rowIndex="2">
|
||||
<children>
|
||||
<Button mnemonicParsing="false" onAction="#CascadeSettingApply" prefHeight="40.0" prefWidth="410.4" text="Apply" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane>
|
||||
<children>
|
||||
<Label alignment="CENTER" prefHeight="30.4" prefWidth="410.4" text="Detection Parameters" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane GridPane.rowIndex="1">
|
||||
<children>
|
||||
<ScrollPane layoutY="0.7999992370605469" prefHeight="200.8" prefWidth="410.4" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0">
|
||||
<content>
|
||||
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="200.0" minWidth="0.0" prefWidth="350.0">
|
||||
<children>
|
||||
<GridPane prefHeight="200.0" prefWidth="300.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="40.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="40.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="40.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<AnchorPane>
|
||||
<children>
|
||||
<Label prefHeight="40.0" prefWidth="175.2" text="Scale Factor" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane GridPane.rowIndex="1">
|
||||
<children>
|
||||
<Label prefHeight="40.0" prefWidth="175.2" text="Minimum Size" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane GridPane.rowIndex="2">
|
||||
<children>
|
||||
<Label prefHeight="40.0" prefWidth="175.2" text="Maximum Size" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane GridPane.columnIndex="1">
|
||||
<children>
|
||||
<TextField fx:id="cascadeScaleFactor" alignment="CENTER" prefHeight="40.0" prefWidth="175.2" text="1.2" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane GridPane.columnIndex="1" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<TextField fx:id="cascadeMinSize" alignment="CENTER" prefHeight="40.0" prefWidth="175.2" text="200" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane GridPane.columnIndex="1" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<TextField fx:id="cascadeMaxSize" alignment="CENTER" prefHeight="40.0" prefWidth="175.2" text="400" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</children>
|
||||
</GridPane>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<Label layoutX="49.0" layoutY="8.0" prefHeight="30.4" prefWidth="180.0" text="Phase 2 File" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<Label layoutX="62.0" layoutY="5.0" prefHeight="30.4" prefWidth="180.0" text="Phase 3 File" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="3">
|
||||
<children>
|
||||
<Label layoutX="22.0" layoutY="6.0" prefHeight="30.4" prefWidth="180.0" text="Phase 4 File" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="4">
|
||||
<children>
|
||||
<Label layoutX="34.0" layoutY="6.0" prefHeight="30.4" prefWidth="180.0" text="Phase 5 File" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1">
|
||||
<children>
|
||||
<TextField fx:id="AudioPhase1" layoutX="14.0" layoutY="4.0" prefHeight="30.4" prefWidth="329.6" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<TextField fx:id="AudioPhase2" layoutX="-32.0" layoutY="1.0" prefHeight="30.4" prefWidth="329.6" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<TextField fx:id="AudioPhase3" layoutY="2.0" prefHeight="30.4" prefWidth="329.6" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="3">
|
||||
<children>
|
||||
<TextField fx:id="AudioPhase4" layoutX="51.0" layoutY="2.0" prefHeight="30.4" prefWidth="329.6" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="4">
|
||||
<children>
|
||||
<TextField fx:id="AudioPhase5" layoutX="14.0" layoutY="2.0" prefHeight="30.4" prefWidth="329.6" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2">
|
||||
<children>
|
||||
<Button layoutX="14.0" layoutY="3.0" mnemonicParsing="false" onAction="#BrowseAudioPhase1" prefHeight="30.4" prefWidth="90.4" text="Browse" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<Button layoutX="19.0" layoutY="4.0" mnemonicParsing="false" onAction="#BrowseAudioPhase2" prefHeight="30.4" prefWidth="90.4" text="Browse" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<Button layoutX="19.0" layoutY="4.0" mnemonicParsing="false" onAction="#BrowseAudioPhase3" prefHeight="30.4" prefWidth="90.4" text="Browse" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2" GridPane.rowIndex="3">
|
||||
<children>
|
||||
<Button layoutX="14.0" layoutY="14.0" mnemonicParsing="false" onAction="#BrowseAudioPhase4" prefHeight="40.0" prefWidth="90.4" text="Browse" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2" GridPane.rowIndex="4">
|
||||
<children>
|
||||
<Button layoutY="4.0" mnemonicParsing="false" onAction="#BrowseAudioPhase5" prefHeight="30.4" prefWidth="90.4" text="Browse" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</children>
|
||||
</GridPane>
|
||||
</content>
|
||||
</ScrollPane>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</children>
|
||||
</GridPane>
|
||||
</children>
|
||||
</GridPane>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="3">
|
||||
<children>
|
||||
<GridPane layoutX="166.0" layoutY="-29.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="15.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="15.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0">
|
||||
<children>
|
||||
<Label layoutX="30.0" layoutY="12.0" prefHeight="40.8" prefWidth="87.2" text="Left 90" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<Label layoutX="44.0" layoutY="12.0" prefHeight="40.8" prefWidth="87.2" text="Left 45" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<Label layoutX="30.0" layoutY="6.0" prefHeight="40.8" prefWidth="87.2" text="Center" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="3">
|
||||
<children>
|
||||
<Label layoutX="24.0" layoutY="6.0" prefHeight="40.0" prefWidth="87.2" text="Right 45" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="4">
|
||||
<children>
|
||||
<Label layoutX="36.0" layoutY="11.0" prefHeight="40.0" prefWidth="87.2" text="Right 90" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1">
|
||||
<children>
|
||||
<ComboBox fx:id="CameraLeft90" layoutX="54.0" layoutY="8.0" prefHeight="40.8" prefWidth="408.0" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<ComboBox fx:id="CameraLeft45" layoutX="26.0" layoutY="14.0" prefHeight="40.8" prefWidth="408.0" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<ComboBox fx:id="CameraCenter" layoutX="88.0" layoutY="8.0" prefHeight="40.8" prefWidth="408.0" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="3">
|
||||
<children>
|
||||
<ComboBox fx:id="CameraRight45" layoutX="54.0" layoutY="8.0" prefHeight="40.0" prefWidth="408.0" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="4">
|
||||
<children>
|
||||
<ComboBox fx:id="CameraRight90" layoutX="75.0" layoutY="1.0" prefHeight="40.0" prefWidth="408.0" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2">
|
||||
<children>
|
||||
<Button layoutY="8.0" mnemonicParsing="false" onAction="#ApplyCameraLeft90" prefHeight="40.8" prefWidth="88.0" text="Apply" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<Button layoutX="22.0" layoutY="2.0" mnemonicParsing="false" onAction="#ApplyCameraLeft45" prefHeight="40.8" prefWidth="88.0" text="Apply" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<Button layoutX="18.0" layoutY="2.0" mnemonicParsing="false" onAction="#ApplyCameraFront" prefHeight="40.8" prefWidth="88.0" text="Apply" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2" GridPane.rowIndex="3">
|
||||
<children>
|
||||
<Button layoutX="22.0" layoutY="8.0" mnemonicParsing="false" onAction="#ApplyCameraRight45" prefHeight="40.0" prefWidth="88.0" text="Apply" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.columnIndex="2" GridPane.rowIndex="4">
|
||||
<children>
|
||||
<Button layoutX="22.0" layoutY="8.0" mnemonicParsing="false" onAction="#ApplyCameraRight90" prefHeight="40.0" prefWidth="88.0" text="Apply" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</children>
|
||||
</GridPane>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="5">
|
||||
<children>
|
||||
<HBox prefHeight="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<children>
|
||||
<GridPane HBox.hgrow="ALWAYS">
|
||||
@@ -308,6 +289,42 @@
|
||||
</HBox>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="4">
|
||||
<children>
|
||||
<Label alignment="CENTER" layoutX="287.0" prefHeight="30.4" prefWidth="1024.0" text="Directory Setting" textAlignment="CENTER" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="5">
|
||||
<children>
|
||||
<GridPane layoutX="75.0" layoutY="-31.0" prefHeight="40.0" prefWidth="1024.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="15.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="10.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<AnchorPane>
|
||||
<children>
|
||||
<Label text="Photo Save" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="0.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane GridPane.columnIndex="1">
|
||||
<children>
|
||||
<TextField fx:id="PhotoDirectoryPath" editable="false" prefHeight="40.0" prefWidth="870.4" promptText="directory to save photo" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane GridPane.columnIndex="2">
|
||||
<children>
|
||||
<Button mnemonicParsing="false" onAction="#ChangePhotoDirectoryPath" prefHeight="40.0" prefWidth="102.4" text="Browse" AnchorPane.bottomAnchor="2.0" AnchorPane.leftAnchor="2.0" AnchorPane.rightAnchor="2.0" AnchorPane.topAnchor="2.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</children>
|
||||
</GridPane>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</children>
|
||||
</GridPane>
|
||||
</children>
|
||||
|
||||
BIN
tahan_posisi.wav
Normal file
BIN
tahan_posisi.wav
Normal file
Binary file not shown.
@@ -1,4 +1,5 @@
|
||||
writer = rolling file
|
||||
#writer = rolling file
|
||||
writer = console
|
||||
writer.file = logs/{date:yyyy-MM-dd}.log
|
||||
writer.format = {date:yyyy-MM-dd HH:mm:ss} {level}: {class}.{method}() {message}
|
||||
//writer.format = {date:yyyy-MM-dd HH:mm:ss} {level}: {message}
|
||||
|
||||
BIN
upload_berhasil.wav
Normal file
BIN
upload_berhasil.wav
Normal file
Binary file not shown.
BIN
upload_gagal.wav
Normal file
BIN
upload_gagal.wav
Normal file
Binary file not shown.
BIN
voices/countdown321.wav
Normal file
BIN
voices/countdown321.wav
Normal file
Binary file not shown.
BIN
voices/data_barcode_tidak_ditemukan.wav
Normal file
BIN
voices/data_barcode_tidak_ditemukan.wav
Normal file
Binary file not shown.
BIN
voices/dua.wav
BIN
voices/dua.wav
Binary file not shown.
BIN
voices/empat.wav
BIN
voices/empat.wav
Binary file not shown.
BIN
voices/kesalahan_server.wav
Normal file
BIN
voices/kesalahan_server.wav
Normal file
Binary file not shown.
BIN
voices/pengambilan_berhasil.wav
Normal file
BIN
voices/pengambilan_berhasil.wav
Normal file
Binary file not shown.
BIN
voices/pengambilan_gagal.wav
Normal file
BIN
voices/pengambilan_gagal.wav
Normal file
Binary file not shown.
BIN
voices/posisikan_wajah.wav
Normal file
BIN
voices/posisikan_wajah.wav
Normal file
Binary file not shown.
BIN
voices/satu.wav
BIN
voices/satu.wav
Binary file not shown.
BIN
voices/scan_barcode.wav
Normal file
BIN
voices/scan_barcode.wav
Normal file
Binary file not shown.
BIN
voices/tahan_posisi.wav
Normal file
BIN
voices/tahan_posisi.wav
Normal file
Binary file not shown.
BIN
voices/tiga.wav
BIN
voices/tiga.wav
Binary file not shown.
BIN
voices/upload_berhasil.wav
Normal file
BIN
voices/upload_berhasil.wav
Normal file
Binary file not shown.
BIN
voices/upload_gagal.wav
Normal file
BIN
voices/upload_gagal.wav
Normal file
Binary file not shown.
Reference in New Issue
Block a user