Config tweaks, fixed CameraStreamer

This commit is contained in:
Banks Troutman
2019-11-26 23:03:07 -05:00
parent d588b1a69e
commit 8b8138eb50
9 changed files with 82 additions and 49 deletions

View File

@@ -67,7 +67,7 @@ public class ConfigManager {
}
}
public static void saveSettings() {
public static void saveGeneralSettings() {
checkSettingsFolder();
saveSettingsFile();
}

View File

@@ -7,6 +7,7 @@ import com.chameleonvision.util.Helpers;
import com.chameleonvision.util.Platform;
import com.chameleonvision.vision.camera.CameraCapture;
import com.chameleonvision.vision.camera.USBCameraCapture;
import com.chameleonvision.vision.pipeline.CVPipeline;
import com.chameleonvision.vision.pipeline.CVPipelineSettings;
import edu.wpi.cscore.UsbCamera;
import edu.wpi.cscore.UsbCameraInfo;
@@ -136,6 +137,7 @@ public class VisionManager {
return currentUIVisionProcess.getPipelines().stream().map(cvPipeline -> cvPipeline.settings.nickname).collect(Collectors.toList());
}
public static void saveCameras() {
visionProcesses.forEach((vpm) -> {
VisionProcess process = vpm.visionProcess;
@@ -149,6 +151,25 @@ public class VisionManager {
});
}
private static String getCurrentCameraName() {
return currentUIVisionProcess.getCamera().getProperties().name;
}
public static void saveCurrentCameraSettings() {
CameraJsonConfig config = CameraJsonConfig.fromUSBCameraProcess((USBCameraCapture) currentUIVisionProcess.getCamera());
ConfigManager.saveCameraConfig(getCurrentCameraName(), config);
}
public static void saveCurrentCameraPipelines() {
List<CVPipelineSettings> pipelineSettings = currentUIVisionProcess.getPipelines().stream().map(pipeline -> pipeline.settings).collect(Collectors.toList());
ConfigManager.saveCameraPipelines(getCurrentCameraName(), pipelineSettings);
}
public static void saveCurrentCameraDriverMode() {
CVPipelineSettings driverModeSettings = currentUIVisionProcess.getDriverModeSettings();
ConfigManager.saveCameraDriverMode(getCurrentCameraName(), driverModeSettings);
}
public static List<String> getCurrentCameraResolutionList() {
return currentUIVisionProcess.getCamera().getProperties().getVideoModes().stream().map(Helpers::VideoModeToString).collect(Collectors.toList());
}

View File

@@ -35,7 +35,7 @@ public class VisionProcess {
private volatile CVPipelineResult lastPipelineResult;
BlockingQueue<Mat> streamFrameQueue = new LinkedBlockingDeque<>(1);
private BlockingQueue<Mat> streamFrameQueue = new LinkedBlockingDeque<>(1);
// network table stuff
private final NetworkTable defaultTable;
@@ -323,10 +323,9 @@ public class VisionProcess {
}
private static class CameraStreamerRunnable extends LoopingRunnable {
private class CameraStreamerRunnable extends LoopingRunnable {
final CameraStreamer streamer;
private Mat streamBuffer = new Mat();
private CameraStreamerRunnable(int cameraFPS, CameraStreamer streamer) {
// add 2 FPS to allow for a bit of overhead
@@ -336,7 +335,18 @@ public class VisionProcess {
@Override
protected void process() {
try {
if (!streamFrameQueue.isEmpty()) {
Mat latestMat = streamFrameQueue.take();
if (!latestMat.empty()) {
streamer.runStream(latestMat);
} else {
System.out.println("stream mat empty");
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

View File

@@ -16,7 +16,6 @@ import static com.chameleonvision.vision.pipeline.CVPipeline2d.*;
public class CVPipeline2d extends CVPipeline<CVPipeline2dResult, CVPipeline2dSettings> {
private Mat rawCameraMat = new Mat();
private Mat hsvOutputMat = new Mat();
private RotateFlipPipe rotateFlipPipe;
private BlurPipe blurPipe;
@@ -32,13 +31,10 @@ public class CVPipeline2d extends CVPipeline<CVPipeline2dResult, CVPipeline2dSet
private Draw2dContoursPipe draw2dContoursPipe;
private OutputMatPipe outputMatPipe;
private StringBuilder pipelineTimeStringBuilder = new StringBuilder();
private CaptureStaticProperties camProps;
private Scalar hsvLower, hsvUpper;
public CVPipeline2d() {
super(new CVPipeline2dSettings());
}
@@ -128,13 +124,6 @@ public class CVPipeline2d extends CVPipeline<CVPipeline2dResult, CVPipeline2dSet
Pair<Mat, Long> hsvResult = hsvPipe.run(erodeDilateResult.getLeft());
totalPipelineTimeNanos += hsvResult.getRight();
// Todo: move to a pipe
try {
Imgproc.cvtColor(hsvResult.getLeft(), hsvOutputMat, Imgproc.COLOR_GRAY2BGR, 3);
} catch (CvException e) {
System.err.println("(CVPipeline2d) Exception thrown by OpenCV: \n" + e.getMessage());
}
Pair<List<MatOfPoint>, Long> findContoursResult = findContoursPipe.run(hsvResult.getLeft());
totalPipelineTimeNanos += findContoursResult.getRight();
@@ -153,8 +142,8 @@ public class CVPipeline2d extends CVPipeline<CVPipeline2dResult, CVPipeline2dSet
Pair<List<Target2d>, Long> collect2dTargetsResult = collect2dTargetsPipe.run(sortContoursResult.getLeft());
totalPipelineTimeNanos += collect2dTargetsResult.getRight();
// takes pair of (Mat of original camera image, Mat of HSV thresholded image)
Pair<Mat, Long> outputMatResult = outputMatPipe.run(Pair.of(rawCameraMat, hsvOutputMat));
// takes pair of (Mat of original camera image (8UC3), Mat of HSV thresholded image(8UC1))
Pair<Mat, Long> outputMatResult = outputMatPipe.run(Pair.of(rawCameraMat, hsvResult.getLeft()));
totalPipelineTimeNanos += outputMatResult.getRight();
// takes pair of (Mat to draw on, List<RotatedRect> of sorted contours)
@@ -175,13 +164,15 @@ public class CVPipeline2d extends CVPipeline<CVPipeline2dResult, CVPipeline2dSet
pipelineTimeStringBuilder.append(String.format("OutputMat: %.2fms, ", outputMatResult.getRight() / 1000000.0));
pipelineTimeStringBuilder.append(String.format("Draw2dContours: %.2fms, ", draw2dContoursResult.getRight() / 1000000.0));
System.out.println(pipelineTimeStringBuilder.toString());
double totalPipelineTimeMillis = totalPipelineTimeNanos / 1000000.0;
double totalPipelineTimeFPS = 1.0 / (totalPipelineTimeMillis / 1000.0);
double truePipelineTimeMillis = (System.nanoTime() - pipelineStartTimeNanos) / 1000000.0;
double truePipelineFPS = 1.0 / (truePipelineTimeMillis / 1000.0);
System.out.printf("Pipeline processed in %.3fms (%.2fFPS), ", totalPipelineTimeMillis, totalPipelineTimeFPS);
System.out.printf("full pipeline run time was %.3fms (%.2fFPS)\n", truePipelineTimeMillis, truePipelineFPS);
if (true) {
System.out.println(pipelineTimeStringBuilder.toString());
double totalPipelineTimeMillis = totalPipelineTimeNanos / 1000000.0;
double totalPipelineTimeFPS = 1.0 / (totalPipelineTimeMillis / 1000.0);
double truePipelineTimeMillis = (System.nanoTime() - pipelineStartTimeNanos) / 1000000.0;
double truePipelineFPS = 1.0 / (truePipelineTimeMillis / 1000.0);
System.out.printf("Pipeline processed in %.3fms (%.2fFPS), ", totalPipelineTimeMillis, totalPipelineTimeFPS);
System.out.printf("full pipeline run time was %.3fms (%.2fFPS)\n", truePipelineTimeMillis, truePipelineFPS);
}
return new CVPipeline2dResult(collect2dTargetsResult.getLeft(), draw2dContoursResult.getLeft(), totalPipelineTimeNanos);
}

View File

@@ -7,14 +7,14 @@ import java.util.List;
public abstract class CVPipelineResult<T> {
public final List<T> targets;
public final boolean hasTarget;
public final Mat outputMat;
public final Mat outputMat = new Mat();
public final long processTime;
public long imageTimestamp = 0;
public CVPipelineResult(List<T> targets, Mat outputMat, long processTime) {
this.targets = targets;
hasTarget = targets != null && !targets.isEmpty();
this.outputMat = outputMat;
outputMat.copyTo(this.outputMat);
this.processTime = processTime;
}

View File

@@ -38,7 +38,7 @@ public class ErodeDilatePipe implements Pipe<Mat, Mat> {
}
if (dilate) {
Imgproc.erode(processBuffer, processBuffer, kernel);
Imgproc.dilate(processBuffer, processBuffer, kernel);
}
processBuffer.copyTo(outputMat);

View File

@@ -1,12 +1,15 @@
package com.chameleonvision.vision.pipeline.pipes;
import org.apache.commons.lang3.tuple.Pair;
import org.opencv.core.CvException;
import org.opencv.core.Mat;
import org.opencv.imgproc.Imgproc;
public class OutputMatPipe implements Pipe<Pair<Mat, Mat>, Mat> {
private boolean showThresholded;
private Mat processBuffer = new Mat();
private Mat outputMat = new Mat();
public OutputMatPipe(boolean showThresholded) {
@@ -17,15 +20,30 @@ public class OutputMatPipe implements Pipe<Pair<Mat, Mat>, Mat> {
this.showThresholded = showThresholded;
}
/**
*
* @param input Input object for pipe
* Left is raw camera mat (8UC3), Right is HSV threshold mat (8UC1)
* @return Returns desired output Mat, and processing time in nanoseconds
*/
@Override
public Pair<Mat, Long> run(Pair<Mat, Mat> input) {
long processStartNanos = System.nanoTime();
outputMat = showThresholded ? input.getRight() : input.getLeft();
if (showThresholded) {
try {
input.getRight().copyTo(processBuffer);
Imgproc.cvtColor(processBuffer, processBuffer, Imgproc.COLOR_GRAY2BGR, 3);
processBuffer.copyTo(outputMat);
processBuffer.release();
} catch (CvException e) {
System.err.println("(OutputMat) Exception thrown by OpenCV: \n" + e.getMessage());
}
} else {
input.getLeft().copyTo(outputMat);
}
long processTime = System.nanoTime() - processStartNanos;
Pair<Mat, Long> output = Pair.of(outputMat, processTime);
outputMat.release();
return output;
return Pair.of(outputMat, processTime);
}
}

View File

@@ -20,7 +20,7 @@ public class Server {
ws.onClose(ctx -> {
handler.onClose(ctx);
System.out.println("Socket Disconnected");
ConfigManager.saveSettings();
ConfigManager.saveGeneralSettings();
});
ws.onBinaryMessage(ctx -> {
handler.onBinaryMessage(ctx);

View File

@@ -58,7 +58,7 @@ public class ServerHandler {
for (HashMap.Entry<String, Object> e : data.entrySet()) {
setField(ConfigManager.settings, e.getKey(), e.getValue());
}
ConfigManager.saveSettings();
ConfigManager.saveGeneralSettings();
sendFullSettings();
break;
}
@@ -68,7 +68,7 @@ public class ServerHandler {
currentProcess.getDriverModeSettings().brightness = (Integer) data.get("brightness");
currentProcess.setDriverMode((Boolean) data.get("isDriver"));
VisionManager.saveCameras();
VisionManager.saveCurrentCameraDriverMode();
break;
}
case "cameraSettings": {
@@ -90,20 +90,20 @@ public class ServerHandler {
// currentCamera.getProperties().setCamVideoMode(newResolution, true);
// }
VisionManager.saveCameras();
VisionManager.saveCurrentCameraSettings();
sendFullSettings();
break;
}
case "changeCameraName": {
currentCamera.getProperties().setNickname((String) entry.getValue());
sendFullSettings();
ConfigManager.saveSettings();
VisionManager.saveCurrentCameraSettings();
break;
}
case "changePipelineName": {
currentPipeline.settings.nickname = ((String) entry.getValue());
sendFullSettings();
ConfigManager.saveSettings();
VisionManager.saveCurrentCameraPipelines();
break;
}
case "duplicatePipeline": {
@@ -121,7 +121,7 @@ public class ServerHandler {
} else {
currentProcess.addPipeline(origPipeline);
}
ConfigManager.saveSettings();
VisionManager.saveCurrentCameraPipelines();
break;
}
case "command": {
@@ -129,7 +129,7 @@ public class ServerHandler {
case "addNewPipeline":
currentProcess.addPipeline();
sendFullSettings();
ConfigManager.saveSettings();
VisionManager.saveCurrentCameraPipelines();
break;
// TODO: (HIGH) this never worked before, re-visit now that VisionProcess is written sanely
case "deleteCurrentPipeline":
@@ -143,10 +143,10 @@ public class ServerHandler {
// cam.deletePipeline();
// cam.setCurrentPipelineIndex(nextIndex);
// sendFullSettings();
// ConfigManager.saveSettings();
// VisionManager.saveCurrentCameraPipelines();
break;
case "save":
ConfigManager.saveSettings();
ConfigManager.saveGeneralSettings();
System.out.println("saved Settings");
break;
}
@@ -161,17 +161,10 @@ public class ServerHandler {
case "currentPipeline": {
currentProcess.setPipeline((Integer) entry.getValue(), true);
sendFullSettings();
try {
currentCamera.setBrightness((int) currentPipeline.settings.brightness);
currentCamera.setExposure((int) currentPipeline.settings.exposure);
} catch (Exception e) {
continue;
}
break;
}
default: {
setField(currentPipeline.settings, entry.getKey(), entry.getValue());
switch (entry.getKey()) {
case "exposure": {
currentCamera.setExposure((Integer) entry.getValue());