Further abstract image capture, fix some UI bugs

This commit is contained in:
Banks Troutman
2019-11-25 05:34:04 -05:00
parent 26e0bb733b
commit ddba967793
23 changed files with 165 additions and 130 deletions

View File

@@ -1,18 +1,11 @@
package com.chameleonvision.vision.camera;
import com.chameleonvision.vision.image.ImageCapture;
import edu.wpi.cscore.VideoMode;
import org.apache.commons.lang3.tuple.Pair;
import org.opencv.core.Mat;
public interface CameraProcess {
public interface CameraCapture extends ImageCapture {
USBCameraProperties getProperties();
/**
* Get the next camera frame
* @return a Pair of the captured image and how long it took to grab the frame (in uS)
*/
Pair<Mat, Long> getFrame();
/**
* Set the exposure of the camera
* @param exposure the new exposure to set the camera to

View File

@@ -10,32 +10,32 @@ import org.opencv.core.CvType;
import org.opencv.core.Mat;
public class CameraStreamer {
private final CameraProcess cameraProcess;
private final CameraCapture cameraCapture;
private final String name;
private StreamDivisor divisor = StreamDivisor.NONE;
private CvSource cvSource;
private final Object streamBufferLock = new Object();
private Mat streamBuffer = new Mat();
public CameraStreamer(CameraProcess cameraProcess, String name) {
this.cameraProcess = cameraProcess;
public CameraStreamer(CameraCapture cameraCapture, String name) {
this.cameraCapture = cameraCapture;
this.name = name;
this.cvSource = CameraServer.getInstance().putVideo(name,
cameraProcess.getProperties().staticProperties.imageWidth / divisor.value,
cameraProcess.getProperties().staticProperties.imageHeight / divisor.value);
cameraCapture.getProperties().getStaticProperties().imageWidth / divisor.value,
cameraCapture.getProperties().getStaticProperties().imageHeight / divisor.value);
setDivisor(divisor, false);
}
public void setDivisor(StreamDivisor newDivisor, boolean updateUI) {
this.divisor = newDivisor;
var camValues = cameraProcess.getProperties();
var newWidth = camValues.staticProperties.imageWidth / newDivisor.value;
var newHeight = camValues.staticProperties.imageHeight / newDivisor.value;
var camValues = cameraCapture.getProperties();
var newWidth = camValues.getStaticProperties().imageWidth / newDivisor.value;
var newHeight = camValues.getStaticProperties().imageHeight / newDivisor.value;
synchronized (streamBufferLock) {
this.streamBuffer = new Mat(newWidth, newHeight, CvType.CV_8UC3);
this.cvSource = CameraServer.getInstance().putVideo(this.name,
cameraProcess.getProperties().staticProperties.imageWidth / divisor.value,
cameraProcess.getProperties().staticProperties.imageHeight / divisor.value);
cameraCapture.getProperties().getStaticProperties().imageWidth / divisor.value,
cameraCapture.getProperties().getStaticProperties().imageHeight / divisor.value);
}
if (updateUI) {
ServerHandler.sendFullSettings();

View File

@@ -3,7 +3,7 @@ package com.chameleonvision.vision.camera;
import org.apache.commons.math3.fraction.Fraction;
import org.apache.commons.math3.util.FastMath;
public class CameraStaticProperties {
public class CaptureStaticProperties {
public final int imageWidth;
public final int imageHeight;
@@ -14,7 +14,7 @@ public class CameraStaticProperties {
public final double horizontalFocalLength;
public final double verticalFocalLength;
public CameraStaticProperties(int imageWidth, int imageHeight, double fov) {
public CaptureStaticProperties(int imageWidth, int imageHeight, double fov) {
this.imageWidth = imageWidth;
this.imageHeight = imageHeight;
this.fov = fov;

View File

@@ -9,13 +9,13 @@ import edu.wpi.first.cameraserver.CameraServer;
import org.apache.commons.lang3.tuple.Pair;
import org.opencv.core.Mat;
public class USBCameraProcess implements CameraProcess {
public class USBCameraCapture implements CameraCapture {
private final UsbCamera baseCamera;
private final CvSink cvSink;
private Mat imageBuffer = new Mat();
private USBCameraProperties properties;
public USBCameraProcess(CameraConfig config) {
public USBCameraCapture(CameraConfig config) {
baseCamera = new UsbCamera(config.name, config.path);
cvSink = CameraServer.getInstance().getVideo(baseCamera);
properties = new USBCameraProperties(baseCamera, config);

View File

@@ -2,9 +2,9 @@ package com.chameleonvision.vision.camera;
import com.chameleonvision.config.CameraConfig;
import com.chameleonvision.util.Platform;
import com.chameleonvision.vision.image.CaptureProperties;
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;
@@ -12,7 +12,7 @@ import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class USBCameraProperties {
public class USBCameraProperties extends CaptureProperties {
public static final double DEFAULT_FOV = 70;
private static final int DEFAULT_EXPOSURE = 50;
private static final int DEFAULT_BRIGHTNESS = 50;
@@ -26,19 +26,18 @@ public class USBCameraProperties {
private static final Predicate<VideoMode> kMinSizePredicate = (videoMode -> videoMode.width >= MINIMUM_WIDTH && videoMode.height >= MINIMUM_HEIGHT);
private static final Predicate<VideoMode> kPixelFormatPredicate = (videoMode -> ALLOWED_PIXEL_FORMATS.contains(videoMode.pixelFormat));
public CameraStaticProperties staticProperties;
public final String name;
public final String path;
public final List<VideoMode> videoModes;
private final UsbCamera baseCamera;
private final boolean hasGain;
private String nickname;
public double FOV;
public final boolean hasGain;
public USBCameraProperties(UsbCamera baseCamera, CameraConfig config) {
USBCameraProperties(UsbCamera baseCamera, CameraConfig config) {
FOV = config.fov;
name = config.name;
path = config.path;
@@ -86,17 +85,8 @@ public class USBCameraProperties {
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));
void updateVideoMode(VideoMode videoMode) {
staticProperties = new CaptureStaticProperties(videoMode.width, videoMode.height, FOV);
}
public List<VideoMode> getVideoModes() {