mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-21 01:01:41 +00:00
Attempt further memory fixes, begin unit tests, fix DriverMode rotation
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
package com.chameleonvision.config;
|
||||
|
||||
import com.chameleonvision.vision.VisionProcess;
|
||||
import com.chameleonvision.vision.camera.USBCameraProperties;
|
||||
import com.chameleonvision.vision.camera.USBCaptureProperties;
|
||||
import com.chameleonvision.vision.enums.StreamDivisor;
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
@@ -31,7 +31,7 @@ public class CameraJsonConfig {
|
||||
}
|
||||
|
||||
public CameraJsonConfig(String path, String name) {
|
||||
this.fov = USBCameraProperties.DEFAULT_FOV;
|
||||
this.fov = USBCaptureProperties.DEFAULT_FOV;
|
||||
this.path = path;
|
||||
this.name = name;
|
||||
this.nickname = name;
|
||||
@@ -40,7 +40,7 @@ public class CameraJsonConfig {
|
||||
}
|
||||
|
||||
public static CameraJsonConfig fromVisionProcess(VisionProcess process) {
|
||||
USBCameraProperties camProps = process.getCamera().getProperties();
|
||||
USBCaptureProperties camProps = process.getCamera().getProperties();
|
||||
int videomode = camProps.getCurrentVideoModeIndex();
|
||||
StreamDivisor streamDivisor = process.cameraStreamer.getDivisor();
|
||||
return new CameraJsonConfig(camProps.getFOV(), camProps.path, camProps.name, camProps.getNickname(), videomode, streamDivisor);
|
||||
|
||||
@@ -84,7 +84,7 @@ public class VisionManager {
|
||||
|
||||
CameraJsonConfig cameraJsonConfig = config.cameraConfig;
|
||||
|
||||
CameraCapture camera = new USBCameraCapture(cameraJsonConfig);
|
||||
USBCameraCapture camera = new USBCameraCapture(cameraJsonConfig);
|
||||
VisionProcess process = new VisionProcess(camera, cameraJsonConfig.name, config.pipelines);
|
||||
process.pipelineManager.driverModePipeline.settings = config.drivermode;
|
||||
visionProcesses.add(new VisionProcessManageable(i, cameraJsonConfig.name, process));
|
||||
@@ -165,7 +165,7 @@ public class VisionManager {
|
||||
currentUIVisionProcess.pipelineManager.saveDriverModeConfig();
|
||||
}
|
||||
|
||||
private static List<HashMap> getCameraResolutionList(CameraCapture capture) {
|
||||
private static List<HashMap> getCameraResolutionList(USBCameraCapture capture) {
|
||||
return capture.getProperties().getVideoModes().stream().map(Helpers::VideoModeToHashMap).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.chameleonvision.config.ConfigManager;
|
||||
import com.chameleonvision.util.LoopingRunnable;
|
||||
import com.chameleonvision.vision.camera.CameraCapture;
|
||||
import com.chameleonvision.vision.camera.CameraStreamer;
|
||||
import com.chameleonvision.vision.camera.USBCameraCapture;
|
||||
import com.chameleonvision.vision.pipeline.*;
|
||||
import com.chameleonvision.web.SocketHandler;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
@@ -24,7 +25,7 @@ import java.util.concurrent.LinkedBlockingDeque;
|
||||
|
||||
public class VisionProcess {
|
||||
|
||||
private final CameraCapture cameraCapture;
|
||||
private final USBCameraCapture cameraCapture;
|
||||
private final CameraStreamerRunnable streamRunnable;
|
||||
private final VisionProcessRunnable visionRunnable;
|
||||
public final CameraStreamer cameraStreamer;
|
||||
@@ -48,7 +49,7 @@ public class VisionProcess {
|
||||
private NetworkTableEntry ntValidEntry;
|
||||
private ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
VisionProcess(CameraCapture cameraCapture, String name, List<CVPipelineSettings> loadedPipelineSettings) {
|
||||
VisionProcess(USBCameraCapture cameraCapture, String name, List<CVPipelineSettings> loadedPipelineSettings) {
|
||||
this.cameraCapture = cameraCapture;
|
||||
|
||||
pipelineManager = new PipelineManager(this, loadedPipelineSettings);
|
||||
@@ -218,7 +219,7 @@ public class VisionProcess {
|
||||
return cameraCapture.getProperties().videoModes;
|
||||
}
|
||||
|
||||
public CameraCapture getCamera() {
|
||||
public USBCameraCapture getCamera() {
|
||||
return cameraCapture;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package com.chameleonvision.vision.camera;
|
||||
|
||||
import com.chameleonvision.vision.image.CaptureProperties;
|
||||
import com.chameleonvision.vision.image.ImageCapture;
|
||||
import edu.wpi.cscore.VideoMode;
|
||||
|
||||
public interface CameraCapture extends ImageCapture {
|
||||
USBCameraProperties getProperties();
|
||||
CaptureProperties getProperties();
|
||||
|
||||
VideoMode getCurrentVideoMode();
|
||||
|
||||
|
||||
@@ -16,10 +16,10 @@ public class CaptureStaticProperties {
|
||||
public final double verticalFocalLength;
|
||||
public final VideoMode mode;
|
||||
|
||||
public CaptureStaticProperties(VideoMode mode, int imageWidth, int imageHeight, double fov) {
|
||||
public CaptureStaticProperties(VideoMode mode, double fov) {
|
||||
this.mode = mode;
|
||||
this.imageWidth = imageWidth;
|
||||
this.imageHeight = imageHeight;
|
||||
this.imageWidth = mode.width;
|
||||
this.imageHeight = mode.height;
|
||||
this.fov = fov;
|
||||
imageArea = this.imageWidth * this.imageHeight;
|
||||
centerX = ((double) this.imageWidth / 2) - 0.5;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.chameleonvision.vision.camera;
|
||||
|
||||
import com.chameleonvision.config.CameraJsonConfig;
|
||||
import com.chameleonvision.vision.image.CaptureProperties;
|
||||
import edu.wpi.cscore.CvSink;
|
||||
import edu.wpi.cscore.UsbCamera;
|
||||
import edu.wpi.cscore.VideoException;
|
||||
@@ -13,19 +14,20 @@ public class USBCameraCapture implements CameraCapture {
|
||||
private final UsbCamera baseCamera;
|
||||
private final CvSink cvSink;
|
||||
private Mat imageBuffer = new Mat();
|
||||
private USBCameraProperties properties;
|
||||
private USBCaptureProperties properties;
|
||||
|
||||
public USBCameraCapture(CameraJsonConfig config) {
|
||||
baseCamera = new UsbCamera(config.name, config.path);
|
||||
cvSink = CameraServer.getInstance().getVideo(baseCamera);
|
||||
properties = new USBCameraProperties(baseCamera, config);
|
||||
properties = new USBCaptureProperties(baseCamera, config);
|
||||
|
||||
int videoMode = properties.videoModes.size() - 1 <= config.videomode ? config.videomode : 0;
|
||||
setVideoMode(videoMode);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public USBCameraProperties getProperties() {
|
||||
public USBCaptureProperties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class USBCameraProperties extends CaptureProperties {
|
||||
public class USBCaptureProperties extends com.chameleonvision.vision.image.CaptureProperties {
|
||||
public static final double DEFAULT_FOV = 70;
|
||||
private static final int DEFAULT_EXPOSURE = 50;
|
||||
private static final int DEFAULT_BRIGHTNESS = 50;
|
||||
@@ -40,7 +40,7 @@ public class USBCameraProperties extends CaptureProperties {
|
||||
private String nickname;
|
||||
private double FOV;
|
||||
|
||||
USBCameraProperties(UsbCamera baseCamera, CameraJsonConfig config) {
|
||||
USBCaptureProperties(UsbCamera baseCamera, CameraJsonConfig config) {
|
||||
FOV = config.fov;
|
||||
name = config.name;
|
||||
path = config.path;
|
||||
@@ -70,7 +70,7 @@ public class USBCameraProperties extends CaptureProperties {
|
||||
public void setFOV(double FOV) {
|
||||
if (this.FOV != FOV) {
|
||||
this.FOV = FOV;
|
||||
staticProperties = new CaptureStaticProperties(staticProperties.mode, staticProperties.imageWidth, staticProperties.imageHeight, FOV);
|
||||
staticProperties = new CaptureStaticProperties(staticProperties.mode, FOV);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ public class USBCameraProperties extends CaptureProperties {
|
||||
}
|
||||
|
||||
void updateVideoMode(VideoMode videoMode) {
|
||||
staticProperties = new CaptureStaticProperties(videoMode, videoMode.width, videoMode.height, FOV);
|
||||
staticProperties = new CaptureStaticProperties(videoMode, FOV);
|
||||
}
|
||||
|
||||
public List<VideoMode> getVideoModes() {
|
||||
@@ -11,8 +11,8 @@ public class CaptureProperties {
|
||||
protected CaptureProperties() {
|
||||
}
|
||||
|
||||
public CaptureProperties(Mat staticImage, double fov) {
|
||||
staticProperties = new CaptureStaticProperties(new VideoMode(0, staticImage.cols(), staticImage.rows(), 99999), staticImage.cols(), staticImage.rows(), fov);
|
||||
public CaptureProperties(VideoMode videoMode, double fov) {
|
||||
staticProperties = new CaptureStaticProperties(videoMode, fov);
|
||||
}
|
||||
|
||||
public CaptureStaticProperties getStaticProperties() {
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package com.chameleonvision.vision.image;
|
||||
|
||||
import com.chameleonvision.vision.camera.CameraCapture;
|
||||
import com.chameleonvision.vision.camera.USBCaptureProperties;
|
||||
import edu.wpi.cscore.VideoMode;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.imgcodecs.Imgcodecs;
|
||||
@@ -7,26 +10,67 @@ import org.opencv.imgcodecs.Imgcodecs;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class StaticImageCapture implements ImageCapture {
|
||||
public class StaticImageCapture implements CameraCapture {
|
||||
|
||||
private final Mat image = new Mat();
|
||||
private Mat image = new Mat();
|
||||
private final VideoMode fakeVideoMode;
|
||||
private final com.chameleonvision.vision.image.CaptureProperties properties;
|
||||
|
||||
public StaticImageCapture(Path imagePath) {
|
||||
this(imagePath, 70);
|
||||
}
|
||||
|
||||
public StaticImageCapture(Path imagePath, double FOV) {
|
||||
if (!Files.exists(imagePath)) throw new RuntimeException("Invalid path for image!");
|
||||
|
||||
Mat tempMat = new Mat();
|
||||
|
||||
try {
|
||||
tempMat = Imgcodecs.imread(imagePath.toString());
|
||||
} catch (Exception e) {
|
||||
System.err.println("Failed to read image!");
|
||||
} finally {
|
||||
tempMat.copyTo(image);
|
||||
Mat loadedImage = Imgcodecs.imread(imagePath.toString());
|
||||
loadedImage.copyTo(image);
|
||||
if (image.cols() > 0 && image.rows() > 0) {
|
||||
fakeVideoMode = new VideoMode(VideoMode.PixelFormat.kBGR, image.cols(), image.rows(), 60);
|
||||
} else {
|
||||
throw new RuntimeException("Failed to load image!");
|
||||
}
|
||||
|
||||
properties = new com.chameleonvision.vision.image.CaptureProperties(fakeVideoMode, FOV);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<Mat, Long> getFrame() {
|
||||
return Pair.of(image, System.nanoTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CaptureProperties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VideoMode getCurrentVideoMode() {
|
||||
return fakeVideoMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExposure(int exposure) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBrightness(int brightness) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVideoMode(VideoMode mode) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVideoMode(int index) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGain(int gain) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.chameleonvision.vision.pipeline;
|
||||
|
||||
import com.chameleonvision.Main;
|
||||
import com.chameleonvision.util.MemoryManager;
|
||||
import com.chameleonvision.vision.camera.CameraCapture;
|
||||
import com.chameleonvision.vision.camera.CaptureStaticProperties;
|
||||
import com.chameleonvision.vision.pipeline.pipes.*;
|
||||
@@ -78,6 +79,8 @@ public class CVPipeline2d extends CVPipeline<CVPipeline2dResult, CVPipeline2dSet
|
||||
outputMatPipe = new OutputMatPipe(settings.isBinary);
|
||||
}
|
||||
|
||||
private final MemoryManager memManager = new MemoryManager(120);
|
||||
|
||||
@Override
|
||||
public CVPipeline2dResult runPipeline(Mat inputMat) {
|
||||
long totalPipelineTimeNanos = 0;
|
||||
@@ -181,6 +184,8 @@ public class CVPipeline2d extends CVPipeline<CVPipeline2dResult, CVPipeline2dSet
|
||||
System.out.printf("full pipeline run time was %.3fms (%.2fFPS)\n", truePipelineTimeMillis, truePipelineFPS);
|
||||
}
|
||||
|
||||
memManager.run(Main.testMode);
|
||||
|
||||
return new CVPipeline2dResult(collect2dTargetsResult.getLeft(), draw2dContoursResult.getLeft(), totalPipelineTimeNanos);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,14 +7,16 @@ import java.util.List;
|
||||
public abstract class CVPipelineResult<T> {
|
||||
public final List<T> targets;
|
||||
public final boolean hasTarget;
|
||||
public final Mat outputMat = new Mat();
|
||||
public final Mat outputMat;
|
||||
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();
|
||||
outputMat.copyTo(this.outputMat);
|
||||
this.outputMat = outputMat;
|
||||
// outputMat.copyTo(this.outputMat);
|
||||
// outputMat.release();
|
||||
this.processTime = processTime;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package com.chameleonvision.vision.pipeline;
|
||||
|
||||
import com.chameleonvision.Main;
|
||||
import com.chameleonvision.util.MemoryManager;
|
||||
import com.chameleonvision.vision.camera.CameraCapture;
|
||||
import com.chameleonvision.vision.pipeline.pipes.Draw2dContoursPipe;
|
||||
import com.chameleonvision.vision.pipeline.pipes.RotateFlipPipe;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.RotatedRect;
|
||||
@@ -12,10 +15,13 @@ import static com.chameleonvision.vision.pipeline.DriverVisionPipeline.DriverPip
|
||||
|
||||
public class DriverVisionPipeline extends CVPipeline<DriverPipelineResult, CVPipelineSettings> {
|
||||
|
||||
private RotateFlipPipe rotateFlipPipe;
|
||||
private Draw2dContoursPipe draw2dContoursPipe;
|
||||
private Draw2dContoursPipe.Draw2dContoursSettings draw2dContoursSettings = new Draw2dContoursPipe.Draw2dContoursSettings();
|
||||
private final List<RotatedRect> blankList = List.of();
|
||||
|
||||
private final MemoryManager memoryManager = new MemoryManager(50);
|
||||
|
||||
public DriverVisionPipeline(CVPipelineSettings settings) {
|
||||
super(settings);
|
||||
settings.index = -1;
|
||||
@@ -24,6 +30,7 @@ public class DriverVisionPipeline extends CVPipeline<DriverPipelineResult, CVPip
|
||||
@Override
|
||||
public void initPipeline(CameraCapture capture) {
|
||||
super.initPipeline(capture);
|
||||
rotateFlipPipe = new RotateFlipPipe(settings.rotationMode, settings.flipMode);
|
||||
draw2dContoursSettings.showCrosshair = true;
|
||||
draw2dContoursPipe = new Draw2dContoursPipe(draw2dContoursSettings, cameraCapture.getProperties().getStaticProperties());
|
||||
}
|
||||
@@ -31,12 +38,17 @@ public class DriverVisionPipeline extends CVPipeline<DriverPipelineResult, CVPip
|
||||
@Override
|
||||
public DriverPipelineResult runPipeline(Mat inputMat) {
|
||||
|
||||
inputMat.copyTo(outputMat);
|
||||
// inputMat.copyTo(outputMat);
|
||||
|
||||
rotateFlipPipe.setConfig(settings.rotationMode, settings.flipMode);
|
||||
draw2dContoursPipe.setConfig(false, cameraCapture.getProperties().getStaticProperties());
|
||||
draw2dContoursPipe.run(Pair.of(outputMat, blankList)).getLeft().copyTo(outputMat);
|
||||
|
||||
return new DriverPipelineResult(null, outputMat, 0);
|
||||
Pair<Mat, Long> rotateFlipResult = rotateFlipPipe.run(inputMat);
|
||||
Pair<Mat, Long> draw2dContoursResult = draw2dContoursPipe.run(Pair.of(rotateFlipResult.getLeft(), blankList));
|
||||
|
||||
memoryManager.run(Main.testMode);
|
||||
|
||||
return new DriverPipelineResult(null, draw2dContoursResult.getLeft(), 0);
|
||||
}
|
||||
|
||||
public static class DriverPipelineResult extends CVPipelineResult<Void> {
|
||||
|
||||
@@ -40,7 +40,8 @@ public class Draw2dContoursPipe implements Pipe<Pair<Mat, List<RotatedRect>>, Ma
|
||||
long processStartNanos = System.nanoTime();
|
||||
|
||||
if (settings.showCrosshair || settings.showCentroid || settings.showMaximumBox || settings.showRotatedBox) {
|
||||
input.getLeft().copyTo(processBuffer);
|
||||
// input.getLeft().copyTo(processBuffer);
|
||||
processBuffer = input.getLeft();
|
||||
|
||||
if (input.getRight().size() > 0) {
|
||||
for (int i = 0; i < input.getRight().size(); i++) {
|
||||
@@ -81,14 +82,14 @@ public class Draw2dContoursPipe implements Pipe<Pair<Mat, List<RotatedRect>>, Ma
|
||||
Imgproc.line(processBuffer, yMax, yMin, Helpers.colorToScalar(settings.crosshairColor), 2);
|
||||
}
|
||||
|
||||
processBuffer.copyTo(outputMat);
|
||||
processBuffer.release();
|
||||
// processBuffer.copyTo(outputMat);
|
||||
// processBuffer.release();
|
||||
} else {
|
||||
input.getLeft().copyTo(outputMat);
|
||||
// input.getLeft().copyTo(outputMat);
|
||||
}
|
||||
|
||||
long processTime = System.nanoTime() - processStartNanos;
|
||||
return Pair.of(outputMat, processTime);
|
||||
return Pair.of(processBuffer, processTime);
|
||||
}
|
||||
|
||||
public static class Draw2dContoursSettings {
|
||||
|
||||
@@ -32,23 +32,23 @@ public class RotateFlipPipe implements Pipe<Mat, Mat> {
|
||||
boolean shouldRotate = !rotation.equals(ImageRotationMode.DEG_0);
|
||||
|
||||
if (shouldFlip || shouldRotate) {
|
||||
input.copyTo(processBuffer);
|
||||
// input.copyTo(processBuffer);
|
||||
|
||||
if (shouldFlip) {
|
||||
Core.flip(processBuffer, processBuffer, flip.value);
|
||||
Core.flip(input, input, flip.value);
|
||||
}
|
||||
|
||||
if (shouldRotate) {
|
||||
Core.rotate(processBuffer, processBuffer, rotation.value);
|
||||
Core.rotate(input, input, rotation.value);
|
||||
}
|
||||
|
||||
processBuffer.copyTo(outputMat);
|
||||
processBuffer.release();
|
||||
// processBuffer.copyTo(outputMat);
|
||||
// processBuffer.release();
|
||||
} else {
|
||||
input.copyTo(outputMat);
|
||||
// input.copyTo(outputMat);
|
||||
}
|
||||
|
||||
long processTime = System.nanoTime() - processStartNanos;
|
||||
return Pair.of(outputMat, processTime);
|
||||
return Pair.of(input, processTime);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.chameleonvision.network.NetworkIPMode;
|
||||
import com.chameleonvision.vision.VisionManager;
|
||||
import com.chameleonvision.vision.VisionProcess;
|
||||
import com.chameleonvision.vision.camera.CameraCapture;
|
||||
import com.chameleonvision.vision.camera.USBCameraCapture;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.javalin.http.Context;
|
||||
@@ -40,7 +41,7 @@ public class RequestHandler {
|
||||
Map camSettings = objectMapper.readValue(ctx.body(), Map.class);
|
||||
|
||||
VisionProcess currentVisionProcess = VisionManager.getCurrentUIVisionProcess();
|
||||
CameraCapture currentCamera = currentVisionProcess.getCamera();
|
||||
USBCameraCapture currentCamera = currentVisionProcess.getCamera();
|
||||
|
||||
double newFOV;
|
||||
try {
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.chameleonvision.config.ConfigManager;
|
||||
import com.chameleonvision.vision.VisionManager;
|
||||
import com.chameleonvision.vision.VisionProcess;
|
||||
import com.chameleonvision.vision.camera.CameraCapture;
|
||||
import com.chameleonvision.vision.camera.USBCameraCapture;
|
||||
import com.chameleonvision.vision.enums.StreamDivisor;
|
||||
import com.chameleonvision.vision.pipeline.CVPipeline;
|
||||
import com.chameleonvision.vision.pipeline.CVPipelineSettings;
|
||||
@@ -234,7 +235,7 @@ public class SocketHandler {
|
||||
private static HashMap<String, Object> getOrdinalCameraSettings() {
|
||||
HashMap<String, Object> tmp = new HashMap<>();
|
||||
VisionProcess currentVisionProcess = VisionManager.getCurrentUIVisionProcess();
|
||||
CameraCapture currentCamera = VisionManager.getCurrentUIVisionProcess().getCamera();
|
||||
USBCameraCapture currentCamera = VisionManager.getCurrentUIVisionProcess().getCamera();
|
||||
tmp.put("fov", currentCamera.getProperties().getFOV());
|
||||
tmp.put("streamDivisor", currentVisionProcess.cameraStreamer.getDivisor().ordinal());
|
||||
tmp.put("resolution", currentVisionProcess.getCamera().getProperties().getCurrentVideoModeIndex());
|
||||
|
||||
Reference in New Issue
Block a user