mirror of
https://github.com/PhotonVision/photonvision
synced 2026-07-01 02:41:42 +00:00
add FrameProviders, meddle with 2.x code
This commit is contained in:
@@ -7,6 +7,7 @@ import com.chameleonvision._2.vision.pipeline.CVPipeline;
|
||||
import com.chameleonvision._2.vision.pipeline.CVPipelineResult;
|
||||
import com.chameleonvision._2.vision.pipeline.pipes.*;
|
||||
import com.chameleonvision.common.util.MemoryManager;
|
||||
import com.chameleonvision.common.vision.opencv.Contour;
|
||||
import edu.wpi.first.wpilibj.geometry.Pose2d;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.opencv.core.Point;
|
||||
@@ -124,7 +125,7 @@ public class StandardCVPipeline extends CVPipeline<StandardCVPipeline.StandardCV
|
||||
speckleRejectPipe.setConfig(settings.speckle.doubleValue());
|
||||
groupContoursPipe.setConfig(settings.targetGroup, settings.targetIntersection);
|
||||
sortContoursPipe.setConfig(settings.sortMode, camProps, 5);
|
||||
collect2dTargetsPipe = new Collect2dTargetsPipe(settings.calibrationMode, settings.targetRegion, settings.targetOrientation, settings.point, settings.dualTargetCalibrationM, settings.dualTargetCalibrationB, camProps);
|
||||
collect2dTargetsPipe.setConfig(settings.calibrationMode, settings.targetRegion, settings.targetOrientation, settings.point, settings.dualTargetCalibrationM, settings.dualTargetCalibrationB, camProps);
|
||||
draw2dContoursPipe.setConfig(settings.multiple, camProps);
|
||||
draw2dCrosshairPipe.setConfig(draw2dCrosshairPipeSettings, settings.calibrationMode, settings.point, settings.dualTargetCalibrationM, settings.dualTargetCalibrationB);
|
||||
outputMatPipe.setConfig(settings.isBinary);
|
||||
@@ -161,9 +162,10 @@ public class StandardCVPipeline extends CVPipeline<StandardCVPipeline.StandardCV
|
||||
Pair<List<MatOfPoint>, Long> findContoursResult = findContoursPipe.run(hsvResult.getLeft());
|
||||
totalPipelineTimeNanos += findContoursResult.getRight();
|
||||
|
||||
Pair<List<MatOfPoint>, Long> filterContoursResult = filterContoursPipe.run(findContoursResult.getLeft());
|
||||
Pair<List<Contour>, Long> filterContoursResult = filterContoursPipe.run(findContoursResult.getLeft());
|
||||
totalPipelineTimeNanos += filterContoursResult.getRight();
|
||||
|
||||
// ignore !
|
||||
Pair<List<MatOfPoint>, Long> speckleRejectResult = speckleRejectPipe.run(filterContoursResult.getLeft());
|
||||
totalPipelineTimeNanos += speckleRejectResult.getRight();
|
||||
|
||||
|
||||
@@ -4,23 +4,25 @@ import com.chameleonvision._2.vision.camera.CaptureStaticProperties;
|
||||
import com.chameleonvision._2.vision.pipeline.Pipe;
|
||||
import com.chameleonvision.common.util.math.MathUtils;
|
||||
import com.chameleonvision.common.util.numbers.DoubleCouple;
|
||||
import com.chameleonvision.common.vision.opencv.Contour;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.opencv.core.MatOfPoint;
|
||||
import org.opencv.core.MatOfPoint2f;
|
||||
import org.opencv.core.Rect;
|
||||
import org.opencv.core.RotatedRect;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class FilterContoursPipe implements Pipe<List<MatOfPoint>, List<MatOfPoint>> {
|
||||
public class FilterContoursPipe implements Pipe<List<MatOfPoint>, List<Contour>> {
|
||||
|
||||
private DoubleCouple area;
|
||||
private DoubleCouple ratio;
|
||||
private DoubleCouple extent;
|
||||
private CaptureStaticProperties camProps;
|
||||
|
||||
private List<MatOfPoint> filteredContours = new ArrayList<>();
|
||||
private List<Contour> filteredContours = new ArrayList<>();
|
||||
|
||||
public FilterContoursPipe(DoubleCouple area, DoubleCouple ratio, DoubleCouple extent, CaptureStaticProperties camProps) {
|
||||
this.area = area;
|
||||
@@ -36,34 +38,47 @@ public class FilterContoursPipe implements Pipe<List<MatOfPoint>, List<MatOfPoin
|
||||
this.camProps = camProps;
|
||||
}
|
||||
|
||||
private void filterContour(MatOfPoint contourPoints) {
|
||||
|
||||
Contour realContour = new Contour(contourPoints);
|
||||
|
||||
// Area Filtering
|
||||
double contourArea = realContour.getArea();
|
||||
double areaRatio = (contourArea / camProps.imageArea) * 100;
|
||||
double minArea = (MathUtils.sigmoid(area.getFirst()));
|
||||
double maxArea = (MathUtils.sigmoid(area.getSecond()));
|
||||
if (areaRatio < minArea || areaRatio > maxArea) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TargetFillPercentage filtering
|
||||
RotatedRect minAreaRect = realContour.getMinAreaRect();
|
||||
double minExtent = (extent.getFirst() * minAreaRect.size.area()) / 100;
|
||||
double maxExtent = (extent.getSecond() * minAreaRect.size.area()) / 100;
|
||||
if (contourArea <= minExtent || contourArea >= maxExtent) {
|
||||
return;
|
||||
}
|
||||
|
||||
// AspectRatio filtering
|
||||
Rect boundingRect = realContour.getBoundingRect();
|
||||
double aspectRatio = ((double)boundingRect.width / boundingRect.height);
|
||||
if (aspectRatio < ratio.getFirst() || aspectRatio > ratio.getSecond()) {
|
||||
return;
|
||||
}
|
||||
|
||||
filteredContours.add(realContour);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<List<MatOfPoint>, Long> run(List<MatOfPoint> input) {
|
||||
public Pair<List<Contour>, Long> run(List<MatOfPoint> input) {
|
||||
long processStartNanos = System.nanoTime();
|
||||
|
||||
filteredContours.clear();
|
||||
|
||||
if (input.size() > 0) {
|
||||
for (MatOfPoint Contour : input) {
|
||||
for (MatOfPoint contour : input) {
|
||||
try {
|
||||
double contourArea = Imgproc.contourArea(Contour);
|
||||
double AreaRatio = (contourArea / camProps.imageArea) * 100;
|
||||
double minArea = (MathUtils.sigmoid(area.getFirst()));
|
||||
double maxArea = (MathUtils.sigmoid(area.getFirst()));
|
||||
if (AreaRatio < minArea || AreaRatio > maxArea) {
|
||||
continue;
|
||||
}
|
||||
var rect = Imgproc.minAreaRect(new MatOfPoint2f(Contour.toArray()));
|
||||
double minExtent = (extent.getFirst() * rect.size.area()) / 100;
|
||||
double maxExtent = (extent.getSecond() * rect.size.area()) / 100;
|
||||
if (contourArea <= minExtent || contourArea >= maxExtent) {
|
||||
continue;
|
||||
}
|
||||
Rect bb = Imgproc.boundingRect(Contour);
|
||||
double aspectRatio = ((double)bb.width / bb.height);
|
||||
if (aspectRatio < ratio.getFirst() || aspectRatio > ratio.getSecond()) {
|
||||
continue;
|
||||
}
|
||||
filteredContours.add(Contour);
|
||||
filterContour(contour);
|
||||
} catch (Exception e) {
|
||||
System.err.println("Error while filtering contours");
|
||||
e.printStackTrace();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.chameleonvision.common.util.numbers;
|
||||
|
||||
public class NumberCouple<T extends Number> {
|
||||
public abstract class NumberCouple<T extends Number> {
|
||||
|
||||
private T first;
|
||||
private T second;
|
||||
@@ -30,4 +30,26 @@ public class NumberCouple<T extends Number> {
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof NumberCouple)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var couple = (NumberCouple) obj;
|
||||
if (!couple.first.equals(first)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!couple.second.equals(second)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return first.intValue() == 0 && second.intValue() == 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
package com.chameleonvision.common.vision.base.camera;
|
||||
|
||||
import com.chameleonvision.common.vision.base.frame.provider.USBFrameProvider;
|
||||
|
||||
public class USBCamera extends USBFrameProvider {
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package com.chameleonvision.common.vision.base.frame;
|
||||
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.Size;
|
||||
|
||||
public class Frame {
|
||||
public long timestamp;
|
||||
public Mat image;
|
||||
public Size imageSize;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package com.chameleonvision.common.vision.base.pipeline.pipe;
|
||||
|
||||
import com.chameleonvision.common.vision.base.pipeline.CVPipe;
|
||||
import com.chameleonvision.common.vision.base.pipeline.pipe.params.ResizeImageParams;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
|
||||
/**
|
||||
* Pipe that resizes an image to a given resolution
|
||||
*/
|
||||
public class ResizeImagePipe extends CVPipe<Mat, Mat, ResizeImageParams> {
|
||||
|
||||
public ResizeImagePipe() {
|
||||
setParams(ResizeImageParams.DEFAULT);
|
||||
}
|
||||
|
||||
public ResizeImagePipe(ResizeImageParams params) {
|
||||
setParams(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process this pipe
|
||||
* @param in {@link Mat} to be resized
|
||||
* @return Resized {@link Mat}
|
||||
*/
|
||||
@Override
|
||||
protected Mat process(Mat in) {
|
||||
Imgproc.resize(in, in, params.getSize());
|
||||
return in;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package com.chameleonvision.common.vision.base.pipeline.pipe;
|
||||
|
||||
import com.chameleonvision.common.vision.base.pipeline.CVPipe;
|
||||
import com.chameleonvision.common.vision.base.pipeline.pipe.params.RotateImageParams;
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.core.Mat;
|
||||
|
||||
/**
|
||||
* Pipe that rotates an image to a given orientation
|
||||
*/
|
||||
public class RotateImagePipe extends CVPipe<Mat, Mat, RotateImageParams> {
|
||||
|
||||
public RotateImagePipe() {
|
||||
setParams(RotateImageParams.DEFAULT);
|
||||
}
|
||||
|
||||
public RotateImagePipe(RotateImageParams params) {
|
||||
setParams(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process this pipe
|
||||
* @param in {@link Mat} to be rotated
|
||||
* @return Rotated {@link Mat}
|
||||
*/
|
||||
@Override
|
||||
protected Mat process(Mat in) {
|
||||
Core.rotate(in, in, params.rotation.value);
|
||||
return in;
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package com.chameleonvision.common.vision.base.pipeline.pipe.params;
|
||||
|
||||
import org.opencv.core.Size;
|
||||
|
||||
public class ResizeImageParams {
|
||||
|
||||
public static ResizeImageParams DEFAULT = new ResizeImageParams(320, 240);
|
||||
|
||||
private Size size;
|
||||
public int width;
|
||||
public int height;
|
||||
|
||||
public ResizeImageParams() {
|
||||
this(DEFAULT.width, DEFAULT.height);
|
||||
}
|
||||
|
||||
public ResizeImageParams(int width, int height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
size = new Size(new double[]{width, height});
|
||||
}
|
||||
|
||||
public Size getSize() {
|
||||
return size;
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package com.chameleonvision.common.vision.base.pipeline.pipe.params;
|
||||
|
||||
public class RotateImageParams {
|
||||
|
||||
public static RotateImageParams DEFAULT = new RotateImageParams(ImageRotation.DEG_0);
|
||||
|
||||
public ImageRotation rotation;
|
||||
|
||||
public RotateImageParams() {
|
||||
rotation = DEFAULT.rotation;
|
||||
}
|
||||
|
||||
public RotateImageParams(ImageRotation rotation) {
|
||||
this.rotation = rotation;
|
||||
}
|
||||
|
||||
public enum ImageRotation {
|
||||
DEG_0(-1),
|
||||
DEG_90(0),
|
||||
DEG_180(1),
|
||||
DEG_270(2);
|
||||
|
||||
public final int value;
|
||||
|
||||
ImageRotation(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public boolean isRotated() {
|
||||
return this.value==DEG_90.value || this.value==DEG_270.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.chameleonvision.common.vision.camera;
|
||||
|
||||
import com.chameleonvision.common.vision.frame.provider.USBFrameProvider;
|
||||
|
||||
public class USBCamera extends USBFrameProvider {
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.chameleonvision.common.vision.frame;
|
||||
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.Size;
|
||||
|
||||
public class Frame {
|
||||
public long timestampNanos;
|
||||
public Mat image;
|
||||
|
||||
public Frame(Mat image) {
|
||||
this.image = image;
|
||||
timestampNanos = System.nanoTime();
|
||||
}
|
||||
|
||||
public Frame(Mat image, long timestampNanos) {
|
||||
this.image = image;
|
||||
this.timestampNanos = timestampNanos;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.chameleonvision.common.vision.base.frame;
|
||||
package com.chameleonvision.common.vision.frame;
|
||||
|
||||
public interface FrameConsumer {
|
||||
void consume(Frame frame);
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.chameleonvision.common.vision.base.frame;
|
||||
package com.chameleonvision.common.vision.frame;
|
||||
|
||||
public interface FrameProvider {
|
||||
Frame getFrame();
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.chameleonvision.common.vision.base.frame.consumer;
|
||||
package com.chameleonvision.common.vision.frame.consumer;
|
||||
|
||||
import com.chameleonvision.common.vision.base.frame.Frame;
|
||||
import com.chameleonvision.common.vision.base.frame.FrameConsumer;
|
||||
import com.chameleonvision.common.vision.frame.Frame;
|
||||
import com.chameleonvision.common.vision.frame.FrameConsumer;
|
||||
import org.apache.commons.lang3.NotImplementedException;
|
||||
|
||||
public class MJPGFrameConsumer implements FrameConsumer {
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.chameleonvision.common.vision.base.frame.provider;
|
||||
package com.chameleonvision.common.vision.frame.provider;
|
||||
|
||||
import com.chameleonvision.common.vision.base.frame.Frame;
|
||||
import com.chameleonvision.common.vision.base.frame.FrameProvider;
|
||||
import com.chameleonvision.common.vision.frame.Frame;
|
||||
import com.chameleonvision.common.vision.frame.FrameProvider;
|
||||
import org.apache.commons.lang3.NotImplementedException;
|
||||
|
||||
public class FileFrameProvider implements FrameProvider {
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.chameleonvision.common.vision.base.frame.provider;
|
||||
package com.chameleonvision.common.vision.frame.provider;
|
||||
|
||||
import com.chameleonvision.common.vision.base.frame.Frame;
|
||||
import com.chameleonvision.common.vision.base.frame.FrameProvider;
|
||||
import com.chameleonvision.common.vision.frame.Frame;
|
||||
import com.chameleonvision.common.vision.frame.FrameProvider;
|
||||
import org.apache.commons.lang3.NotImplementedException;
|
||||
|
||||
public class NetworkFrameProvider implements FrameProvider {
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.chameleonvision.common.vision.base.frame.provider;
|
||||
package com.chameleonvision.common.vision.frame.provider;
|
||||
|
||||
import com.chameleonvision.common.vision.base.frame.Frame;
|
||||
import com.chameleonvision.common.vision.base.frame.FrameProvider;
|
||||
import com.chameleonvision.common.vision.frame.Frame;
|
||||
import com.chameleonvision.common.vision.frame.FrameProvider;
|
||||
import org.apache.commons.lang3.NotImplementedException;
|
||||
|
||||
public class USBFrameProvider implements FrameProvider {
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.chameleonvision.common.vision.opencv;
|
||||
|
||||
import org.opencv.core.*;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
|
||||
public class Contour {
|
||||
|
||||
private final MatOfPoint points;
|
||||
|
||||
private Double area = Double.NaN;
|
||||
private RotatedRect minAreaRect = null;
|
||||
private Rect boundingRect = null;
|
||||
|
||||
public Contour(MatOfPoint points) {
|
||||
this.points = points;
|
||||
}
|
||||
|
||||
public double getArea() {
|
||||
if (Double.isNaN(area)) {
|
||||
area = Imgproc.contourArea(points);
|
||||
}
|
||||
return area;
|
||||
}
|
||||
|
||||
public RotatedRect getMinAreaRect() {
|
||||
if (minAreaRect == null) {
|
||||
MatOfPoint2f temp = new MatOfPoint2f(points.toArray());
|
||||
minAreaRect = Imgproc.minAreaRect(temp);
|
||||
temp.release();
|
||||
}
|
||||
return minAreaRect;
|
||||
}
|
||||
|
||||
public Rect getBoundingRect() {
|
||||
if (boundingRect == null) {
|
||||
boundingRect = Imgproc.boundingRect(points);
|
||||
}
|
||||
return boundingRect;
|
||||
}
|
||||
|
||||
public Point getCenterPoint() {
|
||||
return getMinAreaRect().center;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.chameleonvision.common.vision.base.pipeline;
|
||||
package com.chameleonvision.common.vision.pipeline;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
@@ -8,6 +8,7 @@ import java.util.function.Function;
|
||||
*
|
||||
* @param <I> Input type for the pipe
|
||||
* @param <O> Output type for the pipe
|
||||
* @param <P> Parameters type for the pipe
|
||||
*/
|
||||
public abstract class CVPipe<I, O, P> implements Function<I, PipeResult<O>> {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.chameleonvision.common.vision.base.pipeline;
|
||||
package com.chameleonvision.common.vision.pipeline;
|
||||
|
||||
import com.chameleonvision.common.vision.base.pipeline.pipe.ResizeImagePipe;
|
||||
import com.chameleonvision.common.vision.base.pipeline.pipe.RotateImagePipe;
|
||||
import com.chameleonvision.common.vision.pipeline.pipe.ResizeImagePipe;
|
||||
import com.chameleonvision.common.vision.pipeline.pipe.RotateImagePipe;
|
||||
import edu.wpi.cscore.CameraServerCvJNI;
|
||||
import org.opencv.core.CvType;
|
||||
import org.opencv.core.Mat;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.chameleonvision.common.vision.base.pipeline;
|
||||
package com.chameleonvision.common.vision.pipeline;
|
||||
|
||||
public class PipeResult<O> {
|
||||
O result;
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.chameleonvision.common.vision.pipeline.pipe;
|
||||
|
||||
import com.chameleonvision.common.vision.pipeline.CVPipe;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.Size;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
|
||||
/**
|
||||
* Pipe that resizes an image to a given resolution
|
||||
*/
|
||||
public class ResizeImagePipe extends CVPipe<Mat, Mat, ResizeImagePipe.ResizeImageParams> {
|
||||
|
||||
public ResizeImagePipe() {
|
||||
setParams(ResizeImageParams.DEFAULT);
|
||||
}
|
||||
|
||||
public ResizeImagePipe(ResizeImageParams params) {
|
||||
setParams(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process this pipe
|
||||
* @param in {@link Mat} to be resized
|
||||
* @return Resized {@link Mat}
|
||||
*/
|
||||
@Override
|
||||
protected Mat process(Mat in) {
|
||||
Imgproc.resize(in, in, params.getSize());
|
||||
return in;
|
||||
}
|
||||
|
||||
public static class ResizeImageParams {
|
||||
public static ResizeImageParams DEFAULT = new ResizeImageParams(320, 240);
|
||||
|
||||
private Size size;
|
||||
public int width;
|
||||
public int height;
|
||||
|
||||
public ResizeImageParams() {
|
||||
this(DEFAULT.width, DEFAULT.height);
|
||||
}
|
||||
|
||||
public ResizeImageParams(int width, int height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
size = new Size(new double[]{width, height});
|
||||
}
|
||||
|
||||
public Size getSize() {
|
||||
return size;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.chameleonvision.common.vision.pipeline.pipe;
|
||||
|
||||
import com.chameleonvision.common.vision.pipeline.CVPipe;
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.core.Mat;
|
||||
|
||||
/**
|
||||
* Pipe that rotates an image to a given orientation
|
||||
*/
|
||||
public class RotateImagePipe extends CVPipe<Mat, Mat, RotateImagePipe.RotateImageParams> {
|
||||
|
||||
public RotateImagePipe() {
|
||||
setParams(RotateImageParams.DEFAULT);
|
||||
}
|
||||
|
||||
public RotateImagePipe(RotateImageParams params) {
|
||||
setParams(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process this pipe
|
||||
* @param in {@link Mat} to be rotated
|
||||
* @return Rotated {@link Mat}
|
||||
*/
|
||||
@Override
|
||||
protected Mat process(Mat in) {
|
||||
Core.rotate(in, in, params.rotation.value);
|
||||
return in;
|
||||
}
|
||||
|
||||
public static class RotateImageParams {
|
||||
public static RotateImageParams DEFAULT = new RotateImageParams(ImageRotation.DEG_0);
|
||||
|
||||
public ImageRotation rotation;
|
||||
|
||||
public RotateImageParams() {
|
||||
rotation = DEFAULT.rotation;
|
||||
}
|
||||
|
||||
public RotateImageParams(ImageRotation rotation) {
|
||||
this.rotation = rotation;
|
||||
}
|
||||
|
||||
public enum ImageRotation {
|
||||
DEG_0(-1),
|
||||
DEG_90(0),
|
||||
DEG_180(1),
|
||||
DEG_270(2);
|
||||
|
||||
public final int value;
|
||||
|
||||
ImageRotation(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public boolean isRotated() {
|
||||
return this.value==DEG_90.value || this.value==DEG_270.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,116 @@
|
||||
package com.chameleonvision.common.vision.target;
|
||||
|
||||
import com.chameleonvision.common.util.numbers.DoubleCouple;
|
||||
import com.chameleonvision.common.vision.opencv.Contour;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.opencv.core.Point;
|
||||
import org.opencv.core.RotatedRect;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
// TODO: banks fix
|
||||
public class TrackedTarget {
|
||||
// final Contour externalContour;
|
||||
//
|
||||
// private Point targetOffsetPoint = null;
|
||||
// private Point robotOffsetPoint = null;
|
||||
//
|
||||
// // Single Grouped
|
||||
// public TrackedTarget(Contour inputContour) {
|
||||
// this.externalContour = inputContour;
|
||||
//
|
||||
// }
|
||||
//
|
||||
// public TrackedTarget(List<Contour> subContours) {
|
||||
//
|
||||
// }
|
||||
//
|
||||
//
|
||||
// private Point calculateOffsetPoint(boolean isLandscape, TargetOffsetPointRegion offsetRegion) {
|
||||
// Point[] vertices = new Point[4];
|
||||
//
|
||||
// RotatedRect minRect = externalContour.getMinAreaRect();
|
||||
// minRect.points(vertices);
|
||||
//
|
||||
// Point bl = getMiddle(vertices[0], vertices[1]);
|
||||
// Point tl = getMiddle(vertices[1], vertices[2]);
|
||||
// Point tr = getMiddle(vertices[2], vertices[3]);
|
||||
// Point br = getMiddle(vertices[3], vertices[0]);
|
||||
// boolean orientation;
|
||||
// if (isLandscape) {
|
||||
// orientation = minRect.size.width > minRect.size.height;
|
||||
// } else {
|
||||
// orientation = minRect.size.width < minRect.size.height;
|
||||
// }
|
||||
//
|
||||
// Point result = minRect.center;
|
||||
// switch (offsetRegion) {
|
||||
// case Top: {
|
||||
// result = orientation ? tl : tr;
|
||||
// break;
|
||||
// }
|
||||
// case Bottom: {
|
||||
// result = orientation ? br : bl;
|
||||
// break;
|
||||
// }
|
||||
// case Left: {
|
||||
// result = orientation ? bl : tl;
|
||||
// break;
|
||||
// }
|
||||
// case Right: {
|
||||
// result = orientation ? tr : br;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
//
|
||||
// public Point getTargetOffsetPoint(boolean isLandscape, TargetOffsetPointRegion offsetRegion) {
|
||||
// if (targetOffsetPoint == null) {
|
||||
// targetOffsetPoint = calculateOffsetPoint(isLandscape, offsetRegion);
|
||||
// }
|
||||
// return targetOffsetPoint;
|
||||
// }
|
||||
//
|
||||
// private Point calculateRobotOffsetPoint(DoubleCouple offsetPoint, DoubleCouple offsetEquationValues, RobotOffsetPointMode offsetMode) {
|
||||
// switch (offsetMode) {
|
||||
// case Single:
|
||||
// if (offsetPoint.isEmpty()) {
|
||||
// offsetPoint.set(camProps.centerX, camProps.centerY);
|
||||
// }
|
||||
//
|
||||
// t.calibratedX = offsetPoint.getFirst();
|
||||
// t.calibratedY = offsetPoint.getSecond();
|
||||
// break;
|
||||
// case None:
|
||||
// t.calibratedX = camProps.centerX;
|
||||
// t.calibratedY = camProps.centerY;
|
||||
// break;
|
||||
// case Dual:
|
||||
// t.calibratedX = (t.point.x - this.calibrationB) / this.calibrationM;
|
||||
// t.calibratedY = (t.point.y * this.calibrationM) + this.calibrationB;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private double calculatePitch(double pixelY, double centerY, double verticalFocalLength) {
|
||||
// double pitch = FastMath.toDegrees(FastMath.atan((pixelY - centerY) / verticalFocalLength));
|
||||
// return (pitch * -1);
|
||||
// }
|
||||
//
|
||||
// private double calculateYaw(double pixelX, double centerX, double horizontalFocalLength) {
|
||||
// return FastMath.toDegrees(FastMath.atan((pixelX - centerX) / horizontalFocalLength));
|
||||
// }
|
||||
//
|
||||
// private Point getMiddle(Point p1, Point p2) {
|
||||
// return new Point(((p1.x + p2.x) / 2), ((p1.y + p2.y) / 2));
|
||||
// }
|
||||
//
|
||||
// public enum TargetOffsetPointRegion {
|
||||
// Center, Top, Bottom, Left, Right
|
||||
// }
|
||||
//
|
||||
// public enum RobotOffsetPointMode {
|
||||
// None, Single, Dual
|
||||
// }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user