Begin work on VisionProcess, refinement of CVPipeline interactions

This commit is contained in:
Banks Troutman
2019-11-10 11:47:56 -05:00
parent 1e7f380f07
commit 80f711c37c
13 changed files with 300 additions and 110 deletions

View File

@@ -0,0 +1,61 @@
package com.chameleonvision.classabstraction;
import com.chameleonvision.classabstraction.camera.USBCameraProcess;
import com.chameleonvision.settings.SettingsManager;
import com.chameleonvision.util.FileHelper;
import com.chameleonvision.vision.camera.CameraDeserializer;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import edu.wpi.cscore.UsbCamera;
import edu.wpi.cscore.UsbCameraInfo;
import org.opencv.videoio.VideoCapture;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.LinkedHashMap;
public class VisionManager {
private static final Path CamConfigPath = Paths.get(SettingsManager.SettingsPath.toString(), "cameras");
public static final LinkedHashMap<String, UsbCameraInfo> UsbCameraInfosByCameraName = new LinkedHashMap<>();
public static final LinkedHashMap<String, VisionProcess> VisionProcessesByCameraName = new LinkedHashMap<>();
public static boolean initializeSources() {
int suffix = 0;
for (UsbCameraInfo info : UsbCamera.enumerateUsbCameras()) {
VideoCapture cap = new VideoCapture(info.dev);
if (cap.isOpened()) {
cap.release();
String name = info.name;
while (UsbCameraInfosByCameraName.containsKey(name)) {
suffix++;
name = String.format("%s (%d)", name, suffix);
}
UsbCameraInfosByCameraName.put(name, info);
}
}
if (UsbCameraInfosByCameraName.isEmpty()) {
return false;
}
FileHelper.CheckPath(CamConfigPath);
UsbCameraInfosByCameraName.forEach((cameraName, cameraInfo) -> {
Path cameraConfigPath = Paths.get(CamConfigPath.toString(), String.format("%s.json", cameraName));
File cameraConfigFile = new File(cameraConfigPath.toString());
if (cameraConfigFile.exists() && cameraConfigFile.length() != 0) {
try {
Gson gson = new GsonBuilder()().registerTypeAdapter(USBCameraProcess.class, new CameraDeserializer())
}
}
})
}
public static void initializeProcesses() {
}
}

View File

@@ -0,0 +1,41 @@
package com.chameleonvision.classabstraction;
import com.chameleonvision.classabstraction.camera.CameraProcess;
import com.chameleonvision.classabstraction.pipeline.CVPipeline;
import com.chameleonvision.classabstraction.pipeline.CVPipelineSettings;
import com.chameleonvision.classabstraction.pipeline.DriverVisionPipeline;
import java.util.ArrayList;
import java.util.List;
public class VisionProcess {
private final CameraProcess cameraProcess;
private final List<CVPipeline> pipelines = new ArrayList<>();
private CVPipeline currentPipeline;
private final CVPipelineSettings driverVisionSettings = new CVPipelineSettings();
public VisionProcess(CameraProcess cameraProcess) {
this.cameraProcess = cameraProcess;
pipelines.add(new DriverVisionPipeline(() -> driverVisionSettings));
setPipeline(pipelines.get(0));
}
public void setPipeline(int pipelineIndex) {
CVPipeline newPipeline = pipelines.get(pipelineIndex);
if (newPipeline != null) {
setPipeline(newPipeline);
}
}
public void setPipeline(CVPipeline pipeline) {
currentPipeline = pipeline;
currentPipeline.initPipeline(cameraProcess);
}
public CVPipeline getCurrentPipeline() {
return currentPipeline;
}
}

View File

@@ -0,0 +1,10 @@
package com.chameleonvision.classabstraction.camera;
public class CameraConfig {
public double FOV;
public String Path;
public String Name;
public String Nickname;
public com.chameleonvision.vision.camera.StreamDivisor StreamDivisor;
// public
}

View File

@@ -14,11 +14,11 @@ public class USBCameraProcess implements CameraProcess {
private Mat imageBuffer = new Mat();
public final CameraProperties properties;
public USBCameraProcess(UsbCamera camera, double fov) {
public USBCameraProcess(UsbCamera camera, CameraConfig config) {
baseCamera = camera;
cvSink = CameraServer.getInstance().getVideo(baseCamera);
VideoMode vidMode = new VideoMode(VideoMode.PixelFormat.kYUYV, 640, 480, 60);
properties = new CameraProperties(baseCamera, fov);
properties = new CameraProperties(baseCamera, config.FOV);
}
@Override
@@ -41,7 +41,7 @@ public class USBCameraProcess implements CameraProcess {
try {
baseCamera.setExposureManual(exposure);
} catch (VideoException e) {
System.err.println("USBCameraProcess Does not support exposure change");
System.err.println("Current camera does not support exposure change");
}
}
@@ -50,7 +50,7 @@ public class USBCameraProcess implements CameraProcess {
try {
baseCamera.setBrightness(brightness);
} catch (VideoException e) {
System.err.println("USBCameraProcess Does not support brightness change");
System.err.println("Current camera does not support brightness change");
}
}
}

View File

@@ -3,19 +3,29 @@ package com.chameleonvision.classabstraction.pipeline;
import com.chameleonvision.classabstraction.camera.CameraProcess;
import org.opencv.core.Mat;
import java.util.function.Supplier;
/**
*
* @param <R> Pipeline result type
*/
public abstract class CVPipeline<R extends CVPipelineResult, S extends CVPipelineSettings> {
protected S settings;
private Mat inputMat;
protected Mat outputMat;
CameraProcess cameraProcess;
final Supplier<S> settingsSupplier;
public CVPipeline(S settings) {
this.settings = settings;
public CVPipeline(Supplier<S> settingsSupplier) {
this.settingsSupplier = settingsSupplier;
}
abstract void initPipeline(CameraProcess camera);
abstract R runPipeline(Mat inputMat);
public S getSettings() {
return settingsSupplier.get();
}
public void initPipeline(CameraProcess camera) {
cameraProcess = camera;
cameraProcess.setExposure((int) getSettings().exposure);
cameraProcess.setBrightness((int) getSettings().brightness);
}
abstract public R runPipeline(Mat inputMat);
}

View File

@@ -1,6 +1,5 @@
package com.chameleonvision.classabstraction.pipeline;
import com.chameleonvision.classabstraction.camera.CameraProcess;
import com.chameleonvision.classabstraction.camera.CameraStaticProperties;
import com.chameleonvision.classabstraction.pipeline.pipes.*;
import com.chameleonvision.vision.ImageRotation;
@@ -9,29 +8,26 @@ import org.opencv.core.*;
import org.opencv.imgproc.Imgproc;
import java.util.List;
import java.util.function.Supplier;
import static com.chameleonvision.classabstraction.pipeline.CVPipeline2d.*;
@SuppressWarnings("WeakerAccess")
public class CVPipeline2d extends CVPipeline<CVPipeline2d.CVPipeline2dResult, CVPipeline2d.CVPipeline2dSettings> {
private CameraProcess cameraProcess;
public class CVPipeline2d extends CVPipeline<CVPipeline2dResult, CVPipeline2dSettings> {
private Mat rawCameraMat = new Mat();
private Mat hsvOutputMat = new Mat();
public CVPipeline2d(CVPipeline2dSettings settings) {
super(settings);
public CVPipeline2d(Supplier<CVPipeline2dSettings> settingsSupplier) {
super(settingsSupplier);
}
@Override
void initPipeline(CameraProcess cam) {
cameraProcess = cam;
}
@Override
CVPipeline2d.CVPipeline2dResult runPipeline(Mat inputMat) {
public CVPipeline2dResult runPipeline(Mat inputMat) {
long totalProcessTimeNanos = 0;
StringBuilder procTimeStringBuilder = new StringBuilder();
var settings = settingsSupplier.get();
CameraStaticProperties camProps = cameraProcess.getProperties().staticProperties;
inputMat.copyTo(rawCameraMat);
@@ -123,16 +119,9 @@ public class CVPipeline2d extends CVPipeline<CVPipeline2d.CVPipeline2dResult, CV
return new CVPipeline2dResult(collect2dTargetsResult.getLeft(), draw2dContoursResult.getLeft());
}
public static class CVPipeline2dSettings extends CVPipelineSettings {
double dualTargetCalibrationM = 1;
double dualTargetCalibrationB = 0;
}
public static class CVPipeline2dResult extends CVPipelineResult<Target> {
public CVPipeline2dResult(List<Target> targets, Mat outputMat) {
this.targets = targets;
this.hasTarget = !targets.isEmpty();
this.outputMat = outputMat;
super(targets, outputMat);
}
}

View File

@@ -0,0 +1,29 @@
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 class CVPipeline2dSettings extends CVPipelineSettings {
public List<Number> hue = Arrays.asList(50, 180);
public List<Number> saturation = Arrays.asList(50, 255);
public List<Number> value = Arrays.asList(50, 255);
public boolean erode = false;
public boolean dilate = false;
public List<Number> area = Arrays.asList(0.0, 100.0);
public List<Number> ratio = Arrays.asList(0.0, 20.0);
public List<Number> extent = Arrays.asList(0, 100);
public Number speckle = 5;
public boolean isBinary = false;
public SortMode sortMode = SortMode.Largest;
public TargetGroup targetGroup = TargetGroup.Single;
public TargetIntersection targetIntersection = TargetIntersection.Up;
public List<Number> point = Arrays.asList(0, 0);
public CalibrationMode calibrationMode = CalibrationMode.None;
public double dualTargetCalibrationM = 1;
public double dualTargetCalibrationB = 0;
}

View File

@@ -1,33 +1,33 @@
//package com.chameleonvision.classabstraction.pipeline;
//
//import org.opencv.core.Mat;
//
//public class CVPipeline3d extends CVPipeline<CVPipeline3d.CVPipeline3dResult> {
//
// public CVPipeline3d(CVPipelineSettings settings) {
// super(settings);
// }
//
// @Override
// void initPipeline() {
//
// }
//
// @Override
// CVPipeline3d.CVPipeline3dResult runPipeline(Mat inputMat) {
// return null;
// }
//
// @Override
// Mat getOutputMat() {
// return null;
// }
//
// public static class CVPipeline3dSettings extends CVPipelineSettings {
// }
//
// public static class CVPipeline3dResult {
//
// }
//
//}
package com.chameleonvision.classabstraction.pipeline;
import com.chameleonvision.classabstraction.camera.CameraProcess;
import org.opencv.core.Mat;
import java.util.List;
import java.util.function.Supplier;
import static com.chameleonvision.classabstraction.pipeline.CVPipeline3d.*;
public class CVPipeline3d extends CVPipeline<CVPipeline3dResult, CVPipeline3dSettings> {
public CVPipeline3d(Supplier<CVPipeline3dSettings> settingsSupplier) {
super(settingsSupplier);
}
@Override
public CVPipeline3dResult runPipeline(Mat inputMat) {
return null;
}
public static class CVPipeline3dResult extends CVPipelineResult<Target3d> {
public CVPipeline3dResult(List<Target3d> targets, Mat outputMat) {
super(targets, outputMat);
}
}
public static class Target3d {
// TODO: Define 3d-specific target data
}
}

View File

@@ -0,0 +1,5 @@
package com.chameleonvision.classabstraction.pipeline;
public class CVPipeline3dSettings extends CVPipeline2dSettings {
// TODO:
}

View File

@@ -5,7 +5,13 @@ import org.opencv.core.Mat;
import java.util.List;
public abstract class CVPipelineResult<T> {
List<T> targets;
boolean hasTarget;
Mat outputMat;
public final List<T> targets;
public final boolean hasTarget;
public final Mat outputMat = new Mat();
public CVPipelineResult(List<T> targets, Mat outputMat) {
this.targets = targets;
hasTarget = targets != null && !targets.isEmpty();
outputMat.copyTo(this.outputMat);
}
}

View File

@@ -2,29 +2,10 @@ package com.chameleonvision.classabstraction.pipeline;
import com.chameleonvision.vision.*;
import java.util.Arrays;
import java.util.List;
@SuppressWarnings("ALL")
public abstract class CVPipelineSettings {
ImageFlipMode flipMode = ImageFlipMode.NONE;
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;
List<Number> point = Arrays.asList(0,0);
CalibrationMode calibrationMode = CalibrationMode.None;
String nickname = "";
double exposure = 50.0;
double brightness = 50.0;
public class CVPipelineSettings {
public ImageFlipMode flipMode = ImageFlipMode.NONE;
public String nickname = "";
public double exposure = 50.0;
public double brightness = 50.0;
}

View File

@@ -3,26 +3,34 @@ package com.chameleonvision.classabstraction.pipeline;
import com.chameleonvision.classabstraction.camera.CameraProcess;
import org.opencv.core.Mat;
public class DriverVisionPipeline extends CVPipeline<DriverVisionPipeline.DriverPipelineResult, CVPipelineSettings> {
public DriverVisionPipeline(CVPipelineSettings settings) {
super(settings);
import java.util.List;
import java.util.function.Supplier;
import static com.chameleonvision.classabstraction.pipeline.DriverVisionPipeline.*;
public class DriverVisionPipeline extends CVPipeline<DriverPipelineResult, CVPipelineSettings> {
public DriverVisionPipeline(Supplier<CVPipelineSettings> settingsSupplier) {
super(settingsSupplier);
}
@Override
void initPipeline(CameraProcess camera) {
// TODO: set camera to driver mode
public void initPipeline(CameraProcess camera) {
camera.setBrightness((int) getSettings().brightness);
camera.setExposure((int) getSettings().exposure);
}
@Override
DriverPipelineResult runPipeline(Mat inputMat) {
return new DriverPipelineResult(inputMat);
public DriverPipelineResult runPipeline(Mat inputMat) {
inputMat.copyTo(outputMat);
return new DriverPipelineResult(null, inputMat);
}
public static class DriverPipelineResult extends CVPipelineResult<Void> {
public DriverPipelineResult(Mat outputMat) {
this.hasTarget = false;
this.targets = null;
outputMat.copyTo(this.outputMat);
public DriverPipelineResult(List<Void> targets, Mat outputMat) {
super(targets, outputMat);
}
}
}