mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-21 01:01:41 +00:00
Config tweaks, fixed CameraStreamer
This commit is contained in:
@@ -67,7 +67,7 @@ public class ConfigManager {
|
||||
}
|
||||
}
|
||||
|
||||
public static void saveSettings() {
|
||||
public static void saveGeneralSettings() {
|
||||
checkSettingsFolder();
|
||||
saveSettingsFile();
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user