File Frame Provider (#91)

* Add FileFrameProvider.

* Adding camera properties to the frame providers.

* Fix updating properties.

* Remove updating fov.

* Fix formatting error.
This commit is contained in:
Claudius Tewari
2020-03-31 14:28:36 -07:00
committed by GitHub
parent d527f44d50
commit 64d7cda98c
5 changed files with 157 additions and 2 deletions

View File

@@ -2,4 +2,6 @@ package com.chameleonvision.common.vision.frame;
public interface FrameProvider {
Frame getFrame();
FrameStaticProperties getFrameProperties();
}

View File

@@ -0,0 +1,61 @@
package com.chameleonvision.common.vision.frame;
import edu.wpi.cscore.VideoMode;
import org.apache.commons.math3.fraction.Fraction;
import org.apache.commons.math3.util.FastMath;
/** Represents the properties of a frame. */
public class FrameStaticProperties {
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;
/**
* Instantiates a new Frame static properties.
*
* @param mode The Video Mode of the camera.
* @param fov The fov of the image.
*/
public FrameStaticProperties(VideoMode mode, double fov) {
this(mode.width, mode.height, fov);
}
/**
* Instantiates a new Frame static properties.
*
* @param imageWidth The width of the image.
* @param imageHeight The width of the image.
* @param fov The fov of the image.
*/
public FrameStaticProperties(int imageWidth, int imageHeight, double fov) {
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(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 = this.imageWidth / (2 * FastMath.tan(horizontalView / 2));
verticalFocalLength = this.imageHeight / (2 * FastMath.tan(verticalView / 2));
}
}

View File

@@ -2,11 +2,91 @@ package com.chameleonvision.common.vision.frame.provider;
import com.chameleonvision.common.vision.frame.Frame;
import com.chameleonvision.common.vision.frame.FrameProvider;
import org.apache.commons.lang3.NotImplementedException;
import com.chameleonvision.common.vision.frame.FrameStaticProperties;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
/**
* A {@link FrameProvider} that will read and provide an image from a {@link java.nio.file.Path
* path}.
*/
public class FileFrameProvider implements FrameProvider {
private Frame m_frame;
private Path m_path;
private double m_fov;
private FrameStaticProperties m_properties;
private boolean m_reloadImage;
/**
* Instantiates a new FileFrameProvider.
*
* @param path The path of the image to read from.
* @param fov The fov of the image.
*/
public FileFrameProvider(Path path, double fov) {
if (!Files.exists(path)) throw new RuntimeException("Invalid path for image!");
m_path = path;
m_fov = fov;
loadImage();
}
/**
* Instantiates a new File frame provider.
*
* @param pathAsString The path of the image to read from as a string.
* @param fov The fov of the image.
*/
public FileFrameProvider(String pathAsString, double fov) {
this(Paths.get(pathAsString), fov);
}
private void loadImage() {
Mat image = Imgcodecs.imread(m_path.toString());
if (image.cols() > 0 && image.rows() > 0) {
m_properties = new FrameStaticProperties(image.width(), image.height(), m_fov);
m_frame = new Frame(image);
} else {
throw new RuntimeException("Image loading failed!");
}
}
/**
* Set image reloading. If true this will reload the image from the path set in the constructor
* every time {@link FileFrameProvider#getFrame()} is called.
*
* @param reloadImage True to enable image reloading.
*/
public void setImageReloading(boolean reloadImage) {
m_reloadImage = reloadImage;
}
/**
* Returns if image reloading is enabled.
*
* @return True if image reloading is enabled.
*/
public boolean isImageReloading() {
return m_reloadImage;
}
@Override
public FrameStaticProperties getFrameProperties() {
return m_properties;
}
@Override
public Frame getFrame() {
throw new NotImplementedException("");
if (m_reloadImage) {
loadImage();
}
return m_frame;
}
}

View File

@@ -2,6 +2,7 @@ package com.chameleonvision.common.vision.frame.provider;
import com.chameleonvision.common.vision.frame.Frame;
import com.chameleonvision.common.vision.frame.FrameProvider;
import com.chameleonvision.common.vision.frame.FrameStaticProperties;
import org.apache.commons.lang3.NotImplementedException;
public class NetworkFrameProvider implements FrameProvider {
@@ -9,4 +10,9 @@ public class NetworkFrameProvider implements FrameProvider {
public Frame getFrame() {
throw new NotImplementedException("");
}
@Override
public FrameStaticProperties getFrameProperties() {
throw new NotImplementedException("");
}
}

View File

@@ -2,6 +2,7 @@ package com.chameleonvision.common.vision.frame.provider;
import com.chameleonvision.common.vision.frame.Frame;
import com.chameleonvision.common.vision.frame.FrameProvider;
import com.chameleonvision.common.vision.frame.FrameStaticProperties;
import org.apache.commons.lang3.NotImplementedException;
public class USBFrameProvider implements FrameProvider {
@@ -9,4 +10,9 @@ public class USBFrameProvider implements FrameProvider {
public Frame getFrame() {
throw new NotImplementedException("");
}
@Override
public FrameStaticProperties getFrameProperties() {
throw new NotImplementedException("");
}
}