Add some documentation

This commit is contained in:
Scott Barnes 2024-02-29 12:37:16 -06:00
parent fb5c3174f1
commit f8fcafbea2
7 changed files with 128 additions and 27 deletions

View File

@ -1,4 +1,7 @@
package com.tearabite.ftctearabits.common;
/**
* Enum for the two alliances in FTC
*/
public enum Alliance { Blue, Red }

View File

@ -3,6 +3,9 @@ package com.tearabite.ftctearabits.graphics;
import android.graphics.Color;
import android.graphics.Paint;
/**
* A class to represent a paint object for drawing lines
*/
public class LinePaint extends Paint
{
public LinePaint(int color)

View File

@ -22,21 +22,38 @@ import java.util.ArrayList;
import lombok.Getter;
import lombok.Setter;
/**
* A basic color detection vision processor that detects the largest contour of a specified color
*/
public class BasicColorDetectionVisionProcessor implements VisionProcessor {
public static final Size BLUR_SIZE = new Size(7, 7);
public static final int ERODE_DILATE_ITERATIONS = 2;
public static final Mat STRUCTURING_ELEMENT = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(5, 5));
public static final Point ANCHOR = new Point((STRUCTURING_ELEMENT.cols() / 2f), STRUCTURING_ELEMENT.rows() / 2f);
private static final Mat STRUCTURING_ELEMENT = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(5, 5));
private static final Point ANCHOR = new Point((STRUCTURING_ELEMENT.cols() / 2f), STRUCTURING_ELEMENT.rows() / 2f);
/**
* The size of the blur kernel
*/
@Getter @Setter private Size blurSize = new Size(7, 7);
/**
* The color ranges to detect
*/
@Getter @Setter private ScalarRange[] colorRanges;
/**
* The detection object
*/
@Getter private Detection detection;
/**
* The number of iterations to erode and dilate the mask
*/
@Getter @Setter private int erodeDilateIterations = 2;
private final Mat blurred = new Mat();
private final Mat hsv = new Mat();
private final Mat mask = new Mat();
private final Mat tmpMask = new Mat();
@Getter @Setter private ScalarRange[] colorRanges;
@Getter private Detection detection;
public BasicColorDetectionVisionProcessor(ScalarRange... colorRanges) {
this.colorRanges = colorRanges;
}
@ -62,7 +79,7 @@ public class BasicColorDetectionVisionProcessor implements VisionProcessor {
@Override
public Object processFrame(Mat input, long captureTimeNanos) {
Imgproc.GaussianBlur(input, blurred, BLUR_SIZE, 0);
Imgproc.GaussianBlur(input, blurred, blurSize, 0);
Imgproc.cvtColor(blurred, hsv, Imgproc.COLOR_RGB2HSV);
mask.release();
@ -74,8 +91,8 @@ public class BasicColorDetectionVisionProcessor implements VisionProcessor {
Core.add(mask, tmpMask, mask);
}
Imgproc.erode(mask, mask, STRUCTURING_ELEMENT, ANCHOR, ERODE_DILATE_ITERATIONS);
Imgproc.dilate(mask, mask, STRUCTURING_ELEMENT, ANCHOR, ERODE_DILATE_ITERATIONS);
Imgproc.erode(mask, mask, STRUCTURING_ELEMENT, ANCHOR, erodeDilateIterations);
Imgproc.dilate(mask, mask, STRUCTURING_ELEMENT, ANCHOR, erodeDilateIterations);
ArrayList<MatOfPoint> contours = new ArrayList<>();
Imgproc.findContours(mask, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
@ -100,10 +117,10 @@ public class BasicColorDetectionVisionProcessor implements VisionProcessor {
}
/**
* @param ignoreSmallerThan the minimum area threshold in pixels
* @param minimumAreaThreshold the minimum area threshold in pixels
*/
public void setMinimumAreaThreshold(double ignoreSmallerThan) {
this.detection.setMinimumAreaThreshold(ignoreSmallerThan);
public void setMinimumAreaThreshold(double minimumAreaThreshold) {
this.detection.setMinimumAreaThreshold(minimumAreaThreshold);
}
/**
@ -114,9 +131,9 @@ public class BasicColorDetectionVisionProcessor implements VisionProcessor {
}
/**
* @param ignoreLargerThan the maximum area threshold in pixels
* @param maximumAreaThreshold the maximum area threshold in pixels
*/
public void setMaximumAreaThreshold(double ignoreLargerThan) {
this.detection.setMaximumAreaThreshold(ignoreLargerThan);
public void setMaximumAreaThreshold(double maximumAreaThreshold) {
this.detection.setMaximumAreaThreshold(maximumAreaThreshold);
}
}

View File

@ -13,6 +13,10 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
/**
* This class is used to represent a detection from the a VisionProcessor pipeline.
* It contains various useful abstraction methods for interacting with the detection.
*/
@NoArgsConstructor()
@AllArgsConstructor
@Builder
@ -25,6 +29,11 @@ public class Detection {
@Getter @Setter private double maxAreaThreshold;
@Getter @Setter private double minAreaThreshold;
/**
* Returns whether the detection is valid or not.
* A detection is considered valid if it has a contour and its area is within
* the min and max area thresholds.
*/
public boolean isValid() {
double area = getArea();
return contour != null
@ -32,6 +41,11 @@ public class Detection {
&& area < maxAreaThreshold;
}
/**
* Returns the area of the detection in the specified scale.
* @param scale The scale to return the area in
* @return The area of the detection
*/
public double getArea(PropertyScale scale) {
if (!isValid()) {
return INVALID_AREA;
@ -45,10 +59,19 @@ public class Detection {
return (areaPx / (frameSize.width * frameSize.height)) * 100;
}
/**
* Returns the area of the detection in pixels.
* @return The pixel area of the detection
*/
public double getArea() {
return getArea(PropertyScale.Pixels);
}
/**
* Returns the center of the detection in the specified scale.
* @param scale The scale to return the center in
* @return The center of the detection
*/
public Point getCenter(PropertyScale scale) {
if (!isValid()) {
return INVALID_POINT;
@ -62,40 +85,67 @@ public class Detection {
return pixelPointToPercentageOfFrame(centerPx);
}
/**
* Returns the pixel center of the detection.
* @return The pixel center of the detection
*/
public Point getCenter() {
return getCenter(PropertyScale.Pixels);
}
public void setMaximumAreaThreshold(double ignoreLargerThan, PropertyScale scale) {
/**
* Sets the maximum area threshold for the detection.
* @param maximumAreaThreshold The maximum area threshold
* @param scale The scale that maximumAreaThreshold is specified in
*/
public void setMaximumAreaThreshold(double maximumAreaThreshold, PropertyScale scale) {
switch (scale) {
case Pixels:
this.maxAreaThreshold = ignoreLargerThan;
this.maxAreaThreshold = maximumAreaThreshold;
break;
case Percent:
this.maxAreaThreshold = frameSize.area() * ignoreLargerThan;
this.maxAreaThreshold = frameSize.area() * maximumAreaThreshold;
break;
}
}
public void setMaximumAreaThreshold(double threshold) {
setMaximumAreaThreshold(threshold, PropertyScale.Pixels);
/**
* Sets the maximum area threshold for the detection in pixels.
* @param maximumAreaThreshold The maximum area threshold
*/
public void setMaximumAreaThreshold(double maximumAreaThreshold) {
setMaximumAreaThreshold(maximumAreaThreshold, PropertyScale.Pixels);
}
public void setMinimumAreaThreshold(double threshold, PropertyScale scale) {
/**
* Sets the minimum area threshold for the detection.
* @param minimumAreaThreshold The minimum area threshold
* @param scale The scale that minimumAreaThreshold is specified in
*/
public void setMinimumAreaThreshold(double minimumAreaThreshold, PropertyScale scale) {
switch (scale) {
case Pixels:
this.minAreaThreshold = threshold;
this.minAreaThreshold = minimumAreaThreshold;
break;
case Percent:
this.minAreaThreshold = frameSize.area() * threshold;
this.minAreaThreshold = frameSize.area() * minimumAreaThreshold;
break;
}
}
public void setMinimumAreaThreshold(double threshold) {
setMinimumAreaThreshold(threshold, PropertyScale.Pixels);
/**
* Sets the minimum area threshold for the detection in pixels.
* @param minimumAreaThreshold The minimum area threshold
*/
public void setMinimumAreaThreshold(double minimumAreaThreshold) {
setMinimumAreaThreshold(minimumAreaThreshold, PropertyScale.Pixels);
}
/**
* Returns the maximum area threshold for the detection in the specified scale.
* @param scale The scale to return the maximum area threshold in
* @return The maximum area threshold
*/
public double getMaximumAreaThreshold(PropertyScale scale) {
switch (scale) {
default:
@ -106,10 +156,19 @@ public class Detection {
}
}
/**
* Returns the maximum area threshold for the detection in pixels.
* @return The maximum area threshold
*/
public double getMaximumAreaThreshold() {
return getMaximumAreaThreshold(PropertyScale.Pixels);
}
/**
* Returns the minimum area threshold for the detection in the specified scale.
* @param scale The scale to return the minimum area threshold in
* @return The minimum area threshold
*/
public double getMinimumAreaThreshold(PropertyScale scale) {
switch (scale) {
default:
@ -120,12 +179,21 @@ public class Detection {
}
}
/**
* Returns the minimum area threshold for the detection in pixels.
* @return The minimum area threshold
*/
public double getMinimumAreaThreshold() {
return getMinimumAreaThreshold(PropertyScale.Pixels);
}
public enum PropertyScale { Pixels, Percent }
/**
* Converts a pixel point to a percentage of the frame.
* @param pixelPoint The pixel point to convert
* @return The percentage of the frame that the pixel point is at
*/
private Point pixelPointToPercentageOfFrame(Point pixelPoint) {
double normalizedX = ((pixelPoint.x / frameSize.width) * 100) - 50;
double normalizedY = ((pixelPoint.y / frameSize.height) * -100) + 50;

View File

@ -1,6 +1,10 @@
package com.tearabite.ftctearabits.vision;
import org.opencv.core.Scalar;
/**
* A class containing common HSV color ranges for the FIRST Tech Challenge
*/
public class FTCColors {
public static Scalar FTC_RED_LOWER = new Scalar(165, 80, 80);
public static Scalar FTC_RED_UPPER = new Scalar(15, 255, 255);

View File

@ -12,6 +12,9 @@ import org.opencv.imgproc.Moments;
import java.util.Collections;
import java.util.List;
/**
* A utility class for common vision operations
*/
public class OpenCVUtil {
public static void drawPoint(Mat img, Point point, Scalar color) {

View File

@ -5,6 +5,9 @@ import org.opencv.core.Scalar;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
* A class for specifying an upper and lower bound for a color range.
*/
@Data
@AllArgsConstructor
public class ScalarRange {