diff --git a/Main/chameleon-vision.iml b/Main/chameleon-vision.iml
index 13d0e774e..bb72d8934 100644
--- a/Main/chameleon-vision.iml
+++ b/Main/chameleon-vision.iml
@@ -10,9 +10,6 @@
-
-
-
diff --git a/Main/src/main/java/com/chameleonvision/classabstraction/camera/CameraProcess.java b/Main/src/main/java/com/chameleonvision/classabstraction/camera/CameraProcess.java
new file mode 100644
index 000000000..fe5777c0c
--- /dev/null
+++ b/Main/src/main/java/com/chameleonvision/classabstraction/camera/CameraProcess.java
@@ -0,0 +1,11 @@
+package com.chameleonvision.classabstraction.camera;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.opencv.core.Mat;
+
+public interface CameraProcess {
+ Pair getFrame();
+
+ void setExposure(int exposure);
+ void setBrightness(int brightness);
+}
diff --git a/Main/src/main/java/com/chameleonvision/classabstraction/camera/CameraProperties.java b/Main/src/main/java/com/chameleonvision/classabstraction/camera/CameraProperties.java
new file mode 100644
index 000000000..57a78d2fb
--- /dev/null
+++ b/Main/src/main/java/com/chameleonvision/classabstraction/camera/CameraProperties.java
@@ -0,0 +1,57 @@
+package com.chameleonvision.classabstraction.camera;
+
+import edu.wpi.cscore.UsbCamera;
+import edu.wpi.cscore.VideoMode;
+import org.apache.commons.math3.util.FastMath;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class CameraProperties {
+ private static final double DEFAULT_FOV = 70;
+ private static final int DEFAULT_EXPOSURE = 50;
+ private static final int DEFAULT_BRIGHTNESS = 50;
+ private static final int MINIMUM_FPS = 30;
+ private static final int MINIMUM_WIDTH = 320;
+ private static final int MINIMUM_HEIGHT = 200;
+ private static final int MAX_INIT_MS = 1500;
+ private static final List ALLOWED_PIXEL_FORMATS = Arrays.asList(VideoMode.PixelFormat.kYUYV, VideoMode.PixelFormat.kMJPEG);
+
+ private static final Predicate kMinFPSPredicate = (videoMode -> videoMode.fps >= MINIMUM_FPS);
+ private static final Predicate kMinSizePredicate = (videoMode -> videoMode.width >= MINIMUM_FPS && videoMode.height >= MINIMUM_FPS);
+ private static final Predicate kPixelFormatPredicate = (videoMode -> ALLOWED_PIXEL_FORMATS.contains(videoMode.pixelFormat));
+
+ public CameraStaticProperties staticProperties;
+ public final double FOV;
+ public final List videoModes;
+
+ public CameraProperties(UsbCamera baseCamera, double fov) {
+ FOV = fov;
+
+ videoModes = filterVideoModes(baseCamera.enumerateVideoModes());
+
+
+ }
+
+ private List filterVideoModes(VideoMode[] videoModes) {
+ Predicate fullPredicate = kMinFPSPredicate.and(kMinSizePredicate).and(kPixelFormatPredicate);
+ Stream validModes = Arrays.stream(videoModes).filter(fullPredicate);
+ return validModes.collect(Collectors.toList());
+ }
+
+ public void updateVideoMode(VideoMode videoMode) {
+ staticProperties = new CameraStaticProperties(videoMode.width, videoMode.height, FOV);
+ }
+
+ public double CalculatePitch(double PixelY, double centerY) {
+ double pitch = FastMath.toDegrees(FastMath.atan((PixelY - centerY) / staticProperties.VerticalFocalLength));
+ return (pitch * -1);
+ }
+
+ public double CalculateYaw(double PixelX, double centerX) {
+ return FastMath.toDegrees(FastMath.atan((PixelX - centerX) / staticProperties.HorizontalFocalLength));
+ }
+}
diff --git a/Main/src/main/java/com/chameleonvision/classabstraction/camera/CameraStaticProperties.java b/Main/src/main/java/com/chameleonvision/classabstraction/camera/CameraStaticProperties.java
new file mode 100644
index 000000000..7242fb3c4
--- /dev/null
+++ b/Main/src/main/java/com/chameleonvision/classabstraction/camera/CameraStaticProperties.java
@@ -0,0 +1,36 @@
+package com.chameleonvision.classabstraction.camera;
+
+import org.apache.commons.math3.fraction.Fraction;
+import org.apache.commons.math3.util.FastMath;
+
+public class CameraStaticProperties {
+
+ public final int ImageWidth;
+ public final int ImageHeight;
+ public final double FOV;
+ public final double ImageArea;
+ public final double CenterX;
+ public final double CenterY;
+ public final double HorizontalFocalLength;
+ public final double VerticalFocalLength;
+
+ public CameraStaticProperties(int imageWidth, int imageHeight, double fov) {
+ ImageWidth = imageWidth;
+ ImageHeight = imageHeight;
+ FOV = fov;
+ ImageArea = ImageWidth * ImageHeight;
+ CenterX = ((double) ImageWidth / 2) - 0.5;
+ CenterY = ((double) ImageHeight / 2) - 0.5;
+
+ // pinhole model calculations
+ double diagonalView = FastMath.toRadians(FOV);
+ Fraction aspectFraction = new Fraction(ImageWidth, ImageHeight);
+ int horizontalRatio = aspectFraction.getNumerator();
+ int verticalRatio = aspectFraction.getDenominator();
+ double diagonalAspect = FastMath.hypot(horizontalRatio, verticalRatio);
+ double horizontalView = FastMath.atan(FastMath.tan(diagonalView / 2) * (horizontalRatio / diagonalAspect)) * 2;
+ double verticalView = FastMath.atan(FastMath.tan(diagonalView / 2) * (verticalRatio / diagonalAspect)) * 2;
+ HorizontalFocalLength = ImageWidth / (2 * FastMath.tan(horizontalView /2));
+ VerticalFocalLength = ImageHeight / (2 * FastMath.tan(verticalView /2));
+ }
+}
diff --git a/Main/src/main/java/com/chameleonvision/classabstraction/camera/CameraStreamer.java b/Main/src/main/java/com/chameleonvision/classabstraction/camera/CameraStreamer.java
new file mode 100644
index 000000000..fc3dc2a16
--- /dev/null
+++ b/Main/src/main/java/com/chameleonvision/classabstraction/camera/CameraStreamer.java
@@ -0,0 +1,7 @@
+package com.chameleonvision.classabstraction.camera;
+
+import org.opencv.core.Mat;
+
+public interface CameraStreamer {
+ void streamFrame(Mat frame);
+}
diff --git a/Main/src/main/java/com/chameleonvision/classabstraction/camera/USBCamera.java b/Main/src/main/java/com/chameleonvision/classabstraction/camera/USBCamera.java
new file mode 100644
index 000000000..e2212f8f2
--- /dev/null
+++ b/Main/src/main/java/com/chameleonvision/classabstraction/camera/USBCamera.java
@@ -0,0 +1,15 @@
+package com.chameleonvision.classabstraction.camera;
+
+import edu.wpi.cscore.UsbCamera;
+import edu.wpi.cscore.VideoMode;
+
+public class USBCamera {
+ private final UsbCamera baseCamera;
+ private final CameraProperties properties;
+
+ public USBCamera(UsbCamera camera) {
+ baseCamera = camera;
+ VideoMode vidMode = new VideoMode(VideoMode.PixelFormat.kYUYV, 640, 480, 60);
+ properties = new CameraProperties(baseCamera, 75);
+ }
+}
diff --git a/Main/src/main/java/com/chameleonvision/classabstraction/pipeline/CVPipeline.java b/Main/src/main/java/com/chameleonvision/classabstraction/pipeline/CVPipeline.java
new file mode 100644
index 000000000..fc057b790
--- /dev/null
+++ b/Main/src/main/java/com/chameleonvision/classabstraction/pipeline/CVPipeline.java
@@ -0,0 +1,21 @@
+package com.chameleonvision.classabstraction.pipeline;
+
+import org.opencv.core.Mat;
+
+/**
+ *
+ * @param Pipeline result type
+ */
+public abstract class CVPipeline {
+ private CVPipelineSettings settings;
+ private Mat inputMat;
+ protected Mat outputMat;
+
+ public CVPipeline(CVPipelineSettings settings) {
+ this.settings = settings;
+ }
+
+ abstract void initPipeline();
+ abstract R runPipeline(Mat inputMat);
+ abstract Mat getOutputMat();
+}
diff --git a/Main/src/main/java/com/chameleonvision/classabstraction/pipeline/CVPipeline2dSettings.java b/Main/src/main/java/com/chameleonvision/classabstraction/pipeline/CVPipeline2dSettings.java
new file mode 100644
index 000000000..20dd868ba
--- /dev/null
+++ b/Main/src/main/java/com/chameleonvision/classabstraction/pipeline/CVPipeline2dSettings.java
@@ -0,0 +1,4 @@
+package com.chameleonvision.classabstraction.pipeline;
+
+public class CVPipeline2dSettings extends CVPipelineSettings {
+}
diff --git a/Main/src/main/java/com/chameleonvision/classabstraction/pipeline/CVPipeline3dSettings.java b/Main/src/main/java/com/chameleonvision/classabstraction/pipeline/CVPipeline3dSettings.java
new file mode 100644
index 000000000..b18a2e048
--- /dev/null
+++ b/Main/src/main/java/com/chameleonvision/classabstraction/pipeline/CVPipeline3dSettings.java
@@ -0,0 +1,4 @@
+package com.chameleonvision.classabstraction.pipeline;
+
+public abstract class CVPipeline3dSettings extends CVPipelineSettings {
+}
diff --git a/Main/src/main/java/com/chameleonvision/classabstraction/pipeline/CVPipelineSettings.java b/Main/src/main/java/com/chameleonvision/classabstraction/pipeline/CVPipelineSettings.java
new file mode 100644
index 000000000..c5f3281ae
--- /dev/null
+++ b/Main/src/main/java/com/chameleonvision/classabstraction/pipeline/CVPipelineSettings.java
@@ -0,0 +1,30 @@
+package com.chameleonvision.classabstraction.pipeline;
+
+import com.chameleonvision.vision.CalibrationMode;
+import com.chameleonvision.vision.SortMode;
+import com.chameleonvision.vision.TargetGroup;
+import com.chameleonvision.vision.TargetIntersection;
+
+import java.util.Arrays;
+import java.util.List;
+
+public abstract class CVPipelineSettings {
+ List hue = Arrays.asList(50, 180);
+ List saturation = Arrays.asList(50, 255);
+ List value = Arrays.asList(50, 255);
+ boolean erode = false;
+ boolean dilate = false;
+ List area = Arrays.asList(0.0, 100.0);
+ List ratio = Arrays.asList(0.0, 20.0);
+ List extent = Arrays.asList(0, 100);
+ Number speckle = 5;
+ boolean isBinary = false;
+ SortMode sortMode = SortMode.Largest;
+ TargetGroup targetGroup = TargetGroup.Single;
+ TargetIntersection targetIntersection = TargetIntersection.Up;
+ double m = 1;
+ double b = 0;
+ List point = Arrays.asList(0,0);
+ CalibrationMode calibrationMode = CalibrationMode.None;
+ String nickname = "";
+}
diff --git a/Main/src/main/java/com/chameleonvision/classabstraction/pipeline/DriverVisionPipeline.java b/Main/src/main/java/com/chameleonvision/classabstraction/pipeline/DriverVisionPipeline.java
new file mode 100644
index 000000000..200c38eb9
--- /dev/null
+++ b/Main/src/main/java/com/chameleonvision/classabstraction/pipeline/DriverVisionPipeline.java
@@ -0,0 +1,25 @@
+package com.chameleonvision.classabstraction.pipeline;
+
+import org.opencv.core.Mat;
+
+public class DriverVisionPipeline extends CVPipeline {
+ public DriverVisionPipeline(CVPipelineSettings settings) {
+ super(settings);
+ }
+
+ @Override
+ void initPipeline() {
+ // set exposure/brightness of camera?
+ }
+
+ @Override
+ Void runPipeline(Mat inputMat) {
+ this.outputMat = inputMat;
+ return null;
+ }
+
+ @Override
+ Mat getOutputMat() {
+ return this.outputMat;
+ }
+}
diff --git a/Main/src/main/java/com/chameleonvision/vision/camera/CameraManager.java b/Main/src/main/java/com/chameleonvision/vision/camera/CameraManager.java
index a4855feec..d43f82ee4 100644
--- a/Main/src/main/java/com/chameleonvision/vision/camera/CameraManager.java
+++ b/Main/src/main/java/com/chameleonvision/vision/camera/CameraManager.java
@@ -43,7 +43,7 @@ public class CameraManager {
public static HashMap getAllCamerasByName() {
return allCamerasByName;
}
- public static List getAllCameraByNickname(){
+ public static List getAllCameraByNickname() {
var cameras = getAllCamerasByName();
return cameras.values().stream().map(USBCamera::getNickname).collect(Collectors.toList());
}
@@ -101,6 +101,7 @@ public class CameraManager {
if (curCam == null) throw new CameraException(CameraException.CameraExceptionType.BAD_CAMERA);
return curCam;
}
+
public static Integer getCurrentCameraIndex() throws CameraException {
if (allCamerasByName.size() == 0) throw new CameraException(CameraException.CameraExceptionType.NO_CAMERA);
List arr = new ArrayList<>(allCamerasByName.keySet());
@@ -118,6 +119,7 @@ public class CameraManager {
SettingsManager.generalSettings.currentCamera = cameraName;
SettingsManager.updateCameraSetting(cameraName, getCurrentCamera().getCurrentPipelineIndex());
}
+
public static void setCurrentCamera(int cameraIndex) throws CameraException {
List s = new ArrayList(allCamerasByName.keySet());
setCurrentCamera(s.get(cameraIndex));
diff --git a/Main/src/main/java/com/chameleonvision/vision/camera/CameraValues.java b/Main/src/main/java/com/chameleonvision/vision/camera/CameraValues.java
index 50dcde294..8335f3bd6 100644
--- a/Main/src/main/java/com/chameleonvision/vision/camera/CameraValues.java
+++ b/Main/src/main/java/com/chameleonvision/vision/camera/CameraValues.java
@@ -3,7 +3,6 @@ package com.chameleonvision.vision.camera;
import org.apache.commons.math3.fraction.Fraction;
import org.apache.commons.math3.util.FastMath;
-@SuppressWarnings("WeakerAccess")
public class CameraValues {
public final int ImageWidth;
public final int ImageHeight;
@@ -11,20 +10,14 @@ public class CameraValues {
public final double ImageArea;
public final double CenterX;
public final double CenterY;
- public final double DiagonalView;
- public final double DiagonalAspect;
- public final Fraction AspectFraction;
- public final int HorizontalRatio;
- public final int VerticalRatio;
- public final double HorizontalView;
- public final double VerticalView;
- public final double HorizontalFocalLength;
- public final double VerticalFocalLength;
+ private final double HorizontalFocalLength;
+ private final double VerticalFocalLength;
public CameraValues(USBCamera USBCamera) {
this(USBCamera.getVideoMode().width, USBCamera.getVideoMode().height, USBCamera.getFOV());
}
+
public CameraValues(int imageWidth, int imageHeight, double fov) {
ImageWidth = imageWidth;
ImageHeight = imageHeight;
@@ -32,21 +25,25 @@ public class CameraValues {
ImageArea = ImageWidth * ImageHeight;
CenterX = ((double) ImageWidth / 2) - 0.5;
CenterY = ((double) ImageHeight / 2) - 0.5;
- DiagonalView = FastMath.toRadians(FOV);
- AspectFraction = new Fraction(ImageWidth, ImageHeight);
- HorizontalRatio = AspectFraction.getNumerator();
- VerticalRatio = AspectFraction.getDenominator();
- DiagonalAspect = FastMath.hypot(HorizontalRatio, VerticalRatio);
- HorizontalView = FastMath.atan(FastMath.tan(DiagonalView / 2) * (HorizontalRatio / DiagonalAspect)) * 2;
- VerticalView = FastMath.atan(FastMath.tan(DiagonalView / 2) * (VerticalRatio / DiagonalAspect)) * 2;
- HorizontalFocalLength = ImageWidth / (2 * FastMath.tan(HorizontalView /2));
- VerticalFocalLength = ImageHeight / (2 * FastMath.tan(VerticalView /2));
+
+ // pinhole model calculations
+ double diagonalView = FastMath.toRadians(FOV);
+ Fraction aspectFraction = new Fraction(ImageWidth, ImageHeight);
+ int horizontalRatio = aspectFraction.getNumerator();
+ int verticalRatio = aspectFraction.getDenominator();
+ double diagonalAspect = FastMath.hypot(horizontalRatio, verticalRatio);
+ double horizontalView = FastMath.atan(FastMath.tan(diagonalView / 2) * (horizontalRatio / diagonalAspect)) * 2;
+ double verticalView = FastMath.atan(FastMath.tan(diagonalView / 2) * (verticalRatio / diagonalAspect)) * 2;
+ HorizontalFocalLength = ImageWidth / (2 * FastMath.tan(horizontalView /2));
+ VerticalFocalLength = ImageHeight / (2 * FastMath.tan(verticalView /2));
}
- public double CalculatePitch(double PixelY, double centerY){
- double pitch = FastMath.toDegrees(FastMath.atan((PixelY - centerY) / VerticalFocalLength));
+
+ public double CalculatePitch(double PixelY, double centerY) {
+ double pitch = FastMath.toDegrees(FastMath.atan((PixelY - centerY) / VerticalFocalLength));
return (pitch * -1);
}
- public double CalculateYaw(double PixelX, double centerX){
+
+ public double CalculateYaw(double PixelX, double centerX) {
return FastMath.toDegrees(FastMath.atan((PixelX - centerX) / HorizontalFocalLength));
}
}