diff --git a/README.md b/README.md
index 9dfbaf6..fc3aa0b 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,10 @@ This is a personal/professional project, which makes use of JavaCV, OpenCV, Tess
- [x] modify number of iterations for test suite
- [ ] JavaFX GUI (see `gui` branch)
+## Known Bugs
+
+- As of v4.1.0, cropping images is done by a temporary window created by OpenCV. This window will crash after being used correctly. This can be safely killed when prompted, without affecting the rest of the project. Investigation into how to fix this crashing is ongoing, but it has not yet been resolved.
+
## Dependencies
To install this project, you must have the following:
diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml
index c83f3d1..f91bfaf 100644
--- a/dependency-reduced-pom.xml
+++ b/dependency-reduced-pom.xml
@@ -4,7 +4,7 @@
org.baxter.disco
ocr
Disco OCR Accuracy Over Life Testing
- 4.0.0
+ 4.1.0
Testing Discos for long-term accuracy, using automated optical character recognition.
Baxter International
@@ -108,7 +108,6 @@
5.2.3
true
UTF-8
- 19
5.9.1
1.9.4
diff --git a/pom.xml b/pom.xml
index e687fcb..a0c178a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0
org.baxter.disco
ocr
- 4.0.1
+ 4.1.0
jar
Disco OCR Accuracy Over Life Testing
Testing Discos for long-term accuracy, using automated optical character recognition.
@@ -25,7 +25,7 @@
2.1.0
- 19
+
5.2.3
2.8.0
1.5.6
diff --git a/runScript.sh b/runScript.sh
index b562275..ada5cb0 100644
--- a/runScript.sh
+++ b/runScript.sh
@@ -1,2 +1,2 @@
#! /usr/bin/env sh
-sudo java -jar discoTesting-4.0.0-rc3.jar
+sudo java -jar discoTesting-4.1.0.jar 2>/dev/null
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
index 856007c..fdb76d2 100644
--- a/src/main/java/module-info.java
+++ b/src/main/java/module-info.java
@@ -18,7 +18,7 @@ module org.baxter.disco.ocr {
requires org.apache.commons.lang3;
requires org.bytedeco.javacv.platform;
- requires java.desktop;
+ //requires java.desktop;
uses com.pi4j.extension.Extension;
uses com.pi4j.provider.Provider;
diff --git a/src/main/java/org/baxter/disco/ocr/Cli.java b/src/main/java/org/baxter/disco/ocr/Cli.java
index 63219db..5b387c5 100644
--- a/src/main/java/org/baxter/disco/ocr/Cli.java
+++ b/src/main/java/org/baxter/disco/ocr/Cli.java
@@ -17,7 +17,7 @@ import java.util.concurrent.locks.ReentrantLock;
* classes).
*
* @author Blizzard Finnegan
- * @version 1.4.1, 09 Feb. 2023
+ * @version 1.5.0, 10 Feb. 2023
*/
public class Cli
{
@@ -25,7 +25,7 @@ public class Cli
* Complete build version number
*/
- private static final String version = "4.0.0";
+ private static final String version = "4.1.0";
/**
* Currently saved iteration count.
*/
@@ -239,7 +239,9 @@ public class Cli
"\n\tfor use in OCR. Can modify"+
"\n\tconfig file, if requested." +
"\n\tAvailable variables to change:"+
- "\n\t\tCrop dimensions");
+ "\n\t\tCrop dimensions"+
+ "\n\t\tComposite frame count"+
+ "\n\t\tThreshold value");
println("----------------------------------------");
println("3. Set serial numbers: Set the serial " +
"\n\tnumber for the device under test." +
@@ -373,17 +375,6 @@ public class Cli
println("====================================");
println("Camera Config Menu:");
println("------------------------------------");
- println("Current Crop values: ");
- println("************************************");
- print("X: " + ConfigFacade.getValue(cameraName,
- ConfigProperties.CROP_X));
- print(" | Y: " + ConfigFacade.getValue(cameraName,
- ConfigProperties.CROP_Y));
- print(" | Width: " + ConfigFacade.getValue(cameraName,
- ConfigProperties.CROP_W));
- println(" | Height: " + ConfigFacade.getValue(cameraName,
- ConfigProperties.CROP_H));
- println("************************************");
println("Current composite frame count: " +
ConfigFacade.getValue(cameraName,ConfigProperties.COMPOSITE_FRAMES));
println("Current threshold value: " +
@@ -392,20 +383,14 @@ public class Cli
println("Will the image be cropped? " + cropValue);
String thresholdImage = ((ConfigFacade.getValue(cameraName,ConfigProperties.THRESHOLD) != 0) ? "yes" : "no");
println("Will the image be thresholded? " + thresholdImage);
- String cameraActive = ((ConfigFacade.getValue(cameraName,ConfigProperties.ACTIVE) != 0) ? "yes" : "no");
- println("Will the camera be used when running tests? " + cameraActive);
println("Tesseract parsed value for camera " + cameraName + ": " + tesseractValue);
println("------------------------------------");
- println("1. Change Crop X");
- println("2. Change Crop Y");
- println("3. Change Crop Width");
- println("4. Change Crop Height");
- println("5. Change Composite Frame Count");
- println("6. Change Threshold Value");
- println("7. Toggle crop");
- println("8. Toggle threshold");
- println("9. Toggle camera");
- println("10. Exit");
+ println("1. Change Crop Point");
+ println("2. Change Composite Frame Count");
+ println("3. Change Threshold Value");
+ println("4. Toggle crop");
+ println("5. Toggle threshold");
+ println("6. Exit");
println("====================================");
}
@@ -541,53 +526,48 @@ public class Cli
modifiedProperty = ConfigProperties.CROP_X;
break;
case 2:
- modifiedProperty = ConfigProperties.CROP_Y;
- break;
- case 3:
- modifiedProperty = ConfigProperties.CROP_W;
- break;
- case 4:
- modifiedProperty = ConfigProperties.CROP_H;
- break;
- case 5:
modifiedProperty = ConfigProperties.COMPOSITE_FRAMES;
break;
- case 6:
+ case 3:
modifiedProperty = ConfigProperties.THRESHOLD_VALUE;
break;
- case 7:
+ case 4:
modifiedProperty = ConfigProperties.CROP;
break;
- case 8:
+ case 5:
modifiedProperty = ConfigProperties.THRESHOLD;
break;
- case 9:
- modifiedProperty = ConfigProperties.ACTIVE;
- break;
- case 0:
- case 10:
+ case 6:
modifiedProperty = ConfigProperties.PRIME;
break;
default:
}
} while(modifiedProperty == null);
+ //Toggle threshold/crop
if(modifiedProperty == ConfigProperties.THRESHOLD ||
- modifiedProperty == ConfigProperties.CROP ||
- modifiedProperty == ConfigProperties.ACTIVE)
+ modifiedProperty == ConfigProperties.CROP)
{
double newValue = ConfigFacade.getValue(cameraName,modifiedProperty);
newValue = Math.abs(newValue - 1);
ConfigFacade.setValue(cameraName,modifiedProperty,newValue);
}
+
+ //Redefine crop points
+ else if(modifiedProperty == ConfigProperties.CROP_X)
+ { OpenCVFacade.setCrop(cameraName); }
+
+ //Modify config values
else if(modifiedProperty != ConfigProperties.PRIME)
{
prompt("Enter new value for this property (" + modifiedProperty.toString() + ", currently : " +
- ConfigFacade.getValue(cameraName,modifiedProperty) + "): ");
+ (int)ConfigFacade.getValue(cameraName,modifiedProperty) + "): ");
userInput = inputFiltering(inputScanner.nextLine());
ConfigFacade.setValue(cameraName,modifiedProperty,userInput);
//if(canvas != null) canvas.dispose();
}
+
+ //Exit loop
else break;
} while(true);
diff --git a/src/main/java/org/baxter/disco/ocr/OpenCVFacade.java b/src/main/java/org/baxter/disco/ocr/OpenCVFacade.java
index 5cd8270..69be583 100644
--- a/src/main/java/org/baxter/disco/ocr/OpenCVFacade.java
+++ b/src/main/java/org/baxter/disco/ocr/OpenCVFacade.java
@@ -5,6 +5,7 @@ import java.util.Set;
import static org.bytedeco.opencv.global.opencv_imgproc.*;
import static org.bytedeco.opencv.global.opencv_imgcodecs.*;
+import static org.bytedeco.opencv.global.opencv_highgui.*;
import static org.bytedeco.opencv.global.opencv_core.*;
import org.bytedeco.javacv.*;
@@ -22,7 +23,7 @@ import java.util.List;
* Performs image capture, as well as image manipulation.
*
* @author Blizzard Finnegan
- * @version 1.4.1, 09 Feb. 2023
+ * @version 1.5.0, 10 Feb. 2023
*/
public class OpenCVFacade
{
@@ -36,7 +37,7 @@ public class OpenCVFacade
/**
* Object used to convert between Mats and Frames
*/
- private static final OpenCVFrameConverter.ToMat MAT_CONVERTER = new OpenCVFrameConverter.ToMat();
+ public static final OpenCVFrameConverter.ToMat MAT_CONVERTER = new OpenCVFrameConverter.ToMat();
/**
* Width of the image created by the camera.
@@ -228,15 +229,68 @@ public class OpenCVFacade
return output;
}
- /**
- * Crop the given image to the dimensions in the configuration.
+ /**
+ * Set crop size and location by GUI means.
*
+ * @param cameraName The name of the camera being configured
+ */
+ public static void setCrop(String cameraName)
+ {
+ Mat uncroppedImage = takePicture(cameraName);
+ Rect roi = selectROI("Pick Crop Location", uncroppedImage);
+ ConfigFacade.setValue(cameraName,ConfigProperties.CROP_X, roi.x());
+ ConfigFacade.setValue(cameraName,ConfigProperties.CROP_Y, roi.y());
+ ConfigFacade.setValue(cameraName,ConfigProperties.CROP_W, roi.width());
+ ConfigFacade.setValue(cameraName,ConfigProperties.CROP_H, roi.height());
+ }
+
+ /**
+ * Crop a given image, based on dimensions in the configuration.
+ *
+ * @param image Frame taken from the camera
+ * @param cameraName Name of the camera the frame is from
+ */
+ public static Mat crop(Mat image, String cameraName)
+ {
+ int x = (int)ConfigFacade.getValue(cameraName,ConfigProperties.CROP_X);
+ int y = (int)ConfigFacade.getValue(cameraName,ConfigProperties.CROP_Y);
+ int width = (int)ConfigFacade.getValue(cameraName,ConfigProperties.CROP_W);
+ int height = (int)ConfigFacade.getValue(cameraName,ConfigProperties.CROP_H);
+ Rect roi = new Rect(x,y,width,height);
+ return crop(image, roi,cameraName);
+ }
+
+ /**
+ * Crop the given image, based on dimensions defined in a {@link Rect}
+ *
+ * @param image Frame taken from the camera
+ * @param roi The region of interest to crop the image to
+ *
+ * @return Frame of the cropped image
+ */
+ public static Mat crop(Mat image, Rect roi, String cameraName)
+ {
+ Mat output = null;
+ output = image.apply(roi);
+ String fileLocation = ConfigFacade.getImgSaveLocation() + "/debug/"
+ + ErrorLogging.fileDatetime.format(LocalDateTime.now()) +
+ "." + cameraName + "-preProcess.jpg";
+ cvSaveImage(fileLocation,MAT_CONVERTER.convertToIplImage(
+ MAT_CONVERTER.convert(output)));
+ return output;
+ }
+
+ /**
+ * Crop the given image to the dimensions in the configuration;
+ * deprecated in favour of {@link #crop(Mat, Rect)}
+ *
+ * @deprecated
* @param image Frame taken from the camera.
* @param cameraName Name of the camera taking the picture
*
* @return Frame of the cropped image
*/
- public static Mat crop(Mat image, String cameraName)
+ private static Mat cropImage(Mat image, String cameraName)
{
Mat output = null;
int x = (int)ConfigFacade.getValue(cameraName,ConfigProperties.CROP_X);
diff --git a/toDoList.md b/toDoList.md
index 0e00336..9e06829 100644
--- a/toDoList.md
+++ b/toDoList.md
@@ -4,31 +4,21 @@
## Cli(?)
-- [ ] enable camera toggling
- - may require more classes to be modified
-
-### MovementFacade
-
-- [x] Implement multithreading for physical Run switch\*
- - Currently questionably implemented, consider looking into more
+- [x] enable camera toggling
### OpenCVFacade
-- [x] Overload takeBurst with a default framecount from config
-- [x] Overload crop with default values from config
- [ ] completeProcess should have more robust file output checking
### Gui
-- [x] rebuild menus with current feature set
-- [x] Complete implementation
- - currently questionably implemented; debugging...
+- [ ] Debug and ensure GUI is written properly
## Low-priority improvements
### All
-- [ ] denote overrided functions in first sentence of function
+- [x] denote overrided functions in first sentence of function
- [ ] reduce Javadoc linking to one link per reference per class
- [ ] Use generated Javadocs to improve Javadocs (perpetual)