Rename StreamDivisor enum and work on CameraStreamer

This commit is contained in:
Matt
2019-11-07 16:53:31 -08:00
parent cc2c065dc8
commit 1e7f380f07
10 changed files with 101 additions and 34 deletions

View File

@@ -6,8 +6,22 @@ import org.opencv.core.Mat;
public interface CameraProcess {
CameraProperties getProperties();
/**
* Get the next camera frame
* @param frame the frame to copy the image into
* @return a Pair of the captured image and how long it took to grab the frame (in uS)
*/
Pair<Mat, Long> getFrame(Mat frame);
/**
* Set the exposure of the camera
* @param exposure the new exposure to set the camera to
*/
void setExposure(int exposure);
/**
* Set the exposure of the camera
* @param brightness the new brightness to set the camera to
*/
void setBrightness(int brightness);
}

View File

@@ -21,7 +21,7 @@ public class CameraProperties {
private static final List<VideoMode.PixelFormat> ALLOWED_PIXEL_FORMATS = Arrays.asList(VideoMode.PixelFormat.kYUYV, VideoMode.PixelFormat.kMJPEG);
private static final Predicate<VideoMode> kMinFPSPredicate = (videoMode -> videoMode.fps >= MINIMUM_FPS);
private static final Predicate<VideoMode> kMinSizePredicate = (videoMode -> videoMode.width >= MINIMUM_FPS && videoMode.height >= MINIMUM_FPS);
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;
@@ -46,11 +46,11 @@ public class CameraProperties {
}
public double CalculatePitch(double PixelY, double centerY) {
double pitch = FastMath.toDegrees(FastMath.atan((PixelY - centerY) / staticProperties.VerticalFocalLength));
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));
return FastMath.toDegrees(FastMath.atan((PixelX - centerX) / staticProperties.horizontalFocalLength));
}
}

View File

@@ -5,32 +5,32 @@ import org.apache.commons.math3.util.FastMath;
public class CameraStaticProperties {
public final int ImageWidth;
public final int ImageHeight;
public final double FOV;
public final double ImageArea;
public final int imageWidth;
public final int imageHeight;
public final double fov;
public final double imageArea;
public final double centerX;
public final double centerY;
public final double HorizontalFocalLength;
public final double VerticalFocalLength;
public final double horizontalFocalLength;
public final double verticalFocalLength;
public CameraStaticProperties(int imageWidth, int imageHeight, double fov) {
ImageWidth = imageWidth;
ImageHeight = imageHeight;
FOV = fov;
ImageArea = ImageWidth * ImageHeight;
centerX = ((double) ImageWidth / 2) - 0.5;
centerY = ((double) ImageHeight / 2) - 0.5;
this.imageWidth = imageWidth;
this.imageHeight = imageHeight;
this.fov = fov;
imageArea = this.imageWidth * this.imageHeight;
centerX = ((double) this.imageWidth / 2) - 0.5;
centerY = ((double) this.imageHeight / 2) - 0.5;
// pinhole model calculations
double diagonalView = FastMath.toRadians(FOV);
Fraction aspectFraction = new Fraction(ImageWidth, ImageHeight);
double diagonalView = FastMath.toRadians(this.fov);
Fraction aspectFraction = new Fraction(this.imageWidth, this.imageHeight);
int horizontalRatio = aspectFraction.getNumerator();
int verticalRatio = aspectFraction.getDenominator();
double diagonalAspect = FastMath.hypot(horizontalRatio, verticalRatio);
double horizontalView = FastMath.atan(FastMath.tan(diagonalView / 2) * (horizontalRatio / diagonalAspect)) * 2;
double verticalView = FastMath.atan(FastMath.tan(diagonalView / 2) * (verticalRatio / diagonalAspect)) * 2;
HorizontalFocalLength = ImageWidth / (2 * FastMath.tan(horizontalView /2));
VerticalFocalLength = ImageHeight / (2 * FastMath.tan(verticalView /2));
horizontalFocalLength = this.imageWidth / (2 * FastMath.tan(horizontalView /2));
verticalFocalLength = this.imageHeight / (2 * FastMath.tan(verticalView /2));
}
}

View File

@@ -1,7 +1,58 @@
package com.chameleonvision.classabstraction.camera;
import com.chameleonvision.vision.camera.CameraManager;
import com.chameleonvision.vision.camera.StreamDivisor;
import com.chameleonvision.web.ServerHandler;
import edu.wpi.cscore.CvSource;
import edu.wpi.first.cameraserver.CameraServer;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
public class CameraStreamer {
private final CameraProcess cameraProcess;
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;
this.name = name;
this.cvSource = CameraServer.getInstance().putVideo(name,
cameraProcess.getProperties().staticProperties.imageWidth / divisor.value,
cameraProcess.getProperties().staticProperties.imageHeight / divisor.value);
}
public void setDivisor(StreamDivisor newDivisor) {
this.divisor = newDivisor;
var camValues = cameraProcess.getProperties();
var newWidth = camValues.staticProperties.imageWidth / newDivisor.value;
var newHeight = camValues.staticProperties.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);
}
ServerHandler.sendFullSettings();
}
public void runStream() {
var newFrame = cameraProcess.getFrame(streamBuffer);
var image = newFrame.getLeft();
if (divisor.value != 1) {
var camVal = cameraProcess.getProperties().staticProperties;
var newWidth = camVal.imageWidth / divisor.value;
var newHeight = camVal.imageHeight / divisor.value;
Size newSize = new Size(newWidth, newHeight);
Imgproc.resize(image, image, newSize);
}
cvSource.putFrame(image);
}
public interface CameraStreamer {
void streamFrame(Mat frame);
}

View File

@@ -28,10 +28,12 @@ public class USBCameraProcess implements CameraProcess {
@Override
public Pair<Mat, Long> getFrame(Mat frame) {
var timestamp = System.nanoTime();
cvSink.grabFrame(imageBuffer);
imageBuffer.copyTo(frame);
return Pair.of(frame, timestamp - System.nanoTime());
Long deltaTime;
synchronized (cvSink) {
deltaTime = cvSink.grabFrame(imageBuffer) * 1000L;
imageBuffer.copyTo(frame);
}
return Pair.of(frame, deltaTime);
}
@Override

View File

@@ -61,11 +61,11 @@ public class Collect2dTargetsPipe implements Pipe<List<RotatedRect>, List<CVPipe
}
private double calculatePitch(double pixelY, double centerY) {
double pitch = FastMath.toDegrees(FastMath.atan((pixelY - centerY) / camProps.VerticalFocalLength));
double pitch = FastMath.toDegrees(FastMath.atan((pixelY - centerY) / camProps.verticalFocalLength));
return (pitch * -1);
}
private double calculateYaw(double pixelX, double centerX) {
return FastMath.toDegrees(FastMath.atan((pixelX - centerX) / camProps.HorizontalFocalLength));
return FastMath.toDegrees(FastMath.atan((pixelX - centerX) / camProps.horizontalFocalLength));
}
}

View File

@@ -32,7 +32,7 @@ public class FilterContoursPipe implements Pipe<List<MatOfPoint>, List<MatOfPoin
for (MatOfPoint Contour : input) {
try {
double contourArea = Imgproc.contourArea(Contour);
double AreaRatio = (contourArea / camProps.ImageArea) * 100;
double AreaRatio = (contourArea / camProps.imageArea) * 100;
double minArea = (MathHandler.sigmoid(area.get(0)));
double maxArea = (MathHandler.sigmoid(area.get(1)));
if (AreaRatio < minArea || AreaRatio > maxArea) {