Begin further work on abstraction layout in separate package

This commit is contained in:
Banks Troutman
2019-11-04 02:23:13 -05:00
parent 42b76dfbf9
commit 1bca800f4f
13 changed files with 232 additions and 26 deletions

View File

@@ -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<Mat, Long> getFrame();
void setExposure(int exposure);
void setBrightness(int brightness);
}

View File

@@ -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<VideoMode.PixelFormat> ALLOWED_PIXEL_FORMATS = Arrays.asList(VideoMode.PixelFormat.kYUYV, VideoMode.PixelFormat.kMJPEG);
private static final Predicate<VideoMode> kMinFPSPredicate = (videoMode -> videoMode.fps >= MINIMUM_FPS);
private static final Predicate<VideoMode> kMinSizePredicate = (videoMode -> videoMode.width >= MINIMUM_FPS && videoMode.height >= MINIMUM_FPS);
private static final Predicate<VideoMode> kPixelFormatPredicate = (videoMode -> ALLOWED_PIXEL_FORMATS.contains(videoMode.pixelFormat));
public CameraStaticProperties staticProperties;
public final double FOV;
public final List<VideoMode> videoModes;
public CameraProperties(UsbCamera baseCamera, double fov) {
FOV = fov;
videoModes = filterVideoModes(baseCamera.enumerateVideoModes());
}
private List<VideoMode> filterVideoModes(VideoMode[] videoModes) {
Predicate<VideoMode> fullPredicate = kMinFPSPredicate.and(kMinSizePredicate).and(kPixelFormatPredicate);
Stream<VideoMode> 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));
}
}

View File

@@ -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));
}
}

View File

@@ -0,0 +1,7 @@
package com.chameleonvision.classabstraction.camera;
import org.opencv.core.Mat;
public interface CameraStreamer {
void streamFrame(Mat frame);
}

View File

@@ -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);
}
}

View File

@@ -0,0 +1,21 @@
package com.chameleonvision.classabstraction.pipeline;
import org.opencv.core.Mat;
/**
*
* @param <R> Pipeline result type
*/
public abstract class CVPipeline<R> {
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();
}

View File

@@ -0,0 +1,4 @@
package com.chameleonvision.classabstraction.pipeline;
public class CVPipeline2dSettings extends CVPipelineSettings {
}

View File

@@ -0,0 +1,4 @@
package com.chameleonvision.classabstraction.pipeline;
public abstract class CVPipeline3dSettings extends CVPipelineSettings {
}

View File

@@ -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<Number> hue = Arrays.asList(50, 180);
List<Number> saturation = Arrays.asList(50, 255);
List<Number> value = Arrays.asList(50, 255);
boolean erode = false;
boolean dilate = false;
List<Number> area = Arrays.asList(0.0, 100.0);
List<Number> ratio = Arrays.asList(0.0, 20.0);
List<Number> 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<Number> point = Arrays.asList(0,0);
CalibrationMode calibrationMode = CalibrationMode.None;
String nickname = "";
}

View File

@@ -0,0 +1,25 @@
package com.chameleonvision.classabstraction.pipeline;
import org.opencv.core.Mat;
public class DriverVisionPipeline extends CVPipeline<Void> {
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;
}
}