This program library uses camera vision to detect objects using an AI that analyzes depth.
This section of code shows dynamic functions that other programs can use to analyze data.
This section of code analyzes and processes the image from the camera.
public class ContourPipeline extends OpenCvPipeline {
private static int largestX;
private static int largestY;
Scalar HOT_PINK = new Scalar(196, 23, 112);
// Scalar to start the code
// Green
public static Scalar scalarLowerYCrCb = new Scalar( 0.0, 0.0, 0.0);
public static Scalar scalarUpperYCrCb = new Scalar(255.0, 120.0, 120.0);
// Volatile because accessed by OpMode without sync
public volatile boolean error = false;
public volatile Exception debug;
private double borderLeftX; //fraction of pixels from the left side of the cam to skip
private double borderRightX; //fraction of pixels from the right of the cam to skip
private double borderTopY; //fraction of pixels from the top of the cam to skip
private double borderBottomY; //fraction of pixels from the bottom of the cam to skip
private int CAMERA_WIDTH;
private int CAMERA_HEIGHT;
private int loopCounter = 0;
private int pLoopCounter = 0;
private double largestArea;
private ArrayList<MatOfPoint> findContoursOutput = new ArrayList<>();
private Mat findContoursOutputMat = new Mat();
private Mat finalContourOutputMat = new Mat();
private final Mat mat = new Mat();
private final Mat processed = new Mat();
private Rect maxRect = new Rect(600, 1, 1, 1);
private double maxArea = 0;
private boolean first = false;
private final Object sync = new Object();
public ContourPipeline(double borderLeftX, double borderRightX, double borderTopY, double borderBottomY) {
this.borderLeftX = borderLeftX;
this.borderRightX = borderRightX;
this.borderTopY = borderTopY;
this.borderBottomY = borderBottomY;
}
public void configureScalarLower(double y, double cr, double cb) {
scalarLowerYCrCb = new Scalar(y, cr, cb);
}
public void configureScalarUpper(double y, double cr, double cb) {
scalarUpperYCrCb = new Scalar(y, cr, cb);
}
public void configureScalarLower(int y, int cr, int cb) {
scalarLowerYCrCb = new Scalar(y, cr, cb);
}
public void configureScalarUpper(int y, int cr, int cb) {
scalarUpperYCrCb = new Scalar(y, cr, cb);
}
public void configureBorders(double borderLeftX, double borderRightX, double borderTopY, double borderBottomY) {
this.borderLeftX = borderLeftX;
this.borderRightX = borderRightX;
this.borderTopY = borderTopY;
this.borderBottomY = borderBottomY;
}
...
public int getRectHeight() {
synchronized (sync) {
return maxRect.height;
}
}
public int getRectWidth() {
synchronized (sync) {
return maxRect.width;
}
}
public int getRectX() {
synchronized (sync) {
return maxRect.x;
}
}
public int getRectY() {
synchronized (sync) {
return maxRect.y;
}
}
public double getRectMidpointX() {
synchronized (sync) {
return getRectX() + (getRectWidth() / 2.0);
}
}
public double getRectMidpointY() {
synchronized (sync) {
return getRectY() + (getRectHeight() / 2.0);
}
}
public Point getRectMidpointXY() {
synchronized (sync) {
return new Point(getRectMidpointX(), getRectMidpointY());
}
}
public double getAspectRatio() {
synchronized (sync) {
return getRectArea() / (CAMERA_HEIGHT * CAMERA_WIDTH);
}
}
public double getRectArea() {
synchronized (sync) {
return maxRect.area();
}
}
// The following is for randomness ig
public static int[] getPosition() {
return new int[]{largestX, largestY};
}
public boolean signalDetect() {
if (findContoursOutput.isEmpty() == false) {
return true;
} else {
return false;
}
}
public boolean findContoursRAW() {
return findContoursOutput.isEmpty();
}
}
@Override
public Mat processFrame(Mat input) {
CAMERA_WIDTH = input.width();
CAMERA_HEIGHT = input.height();
try {
// Process Image
Imgproc.cvtColor(input, mat, Imgproc.COLOR_RGB2YCrCb);
Core.inRange(mat, scalarLowerYCrCb, scalarUpperYCrCb, processed);
// Remove Noise
Imgproc.morphologyEx(processed, processed, Imgproc.MORPH_OPEN, new Mat());
Imgproc.morphologyEx(processed, processed, Imgproc.MORPH_CLOSE, new Mat());
// GaussianBlur
Imgproc.GaussianBlur(processed, processed, new Size(5.0, 15.0), 0.00);
// Find Contours
List<MatOfPoint> contours = new ArrayList<>();
Imgproc.findContours(processed, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
// Draw Contours
Imgproc.drawContours(input, contours, -1, new Scalar(255, 0, 0));
// Lock this up to prevent errors when outside threads access the max rect property.
synchronized (sync) {
// Loop Through Contours
for (MatOfPoint contour : contours) {
Point[] contourArray = contour.toArray();
// Bound Rectangle if Contour is Large Enough
if (contourArray.length >= 15) {
MatOfPoint2f areaPoints = new MatOfPoint2f(contourArray);
Rect rect = Imgproc.boundingRect(areaPoints);
if (rect.area() > maxArea
&& rect.x + (rect.width / 2.0) > (borderLeftX * CAMERA_WIDTH)
&& rect.x + (rect.width / 2.0) < CAMERA_WIDTH - (borderRightX * CAMERA_WIDTH)
&& rect.y + (rect.height / 2.0) > (borderTopY * CAMERA_HEIGHT)
&& rect.y + (rect.height / 2.0) < CAMERA_HEIGHT - (borderBottomY * CAMERA_HEIGHT)
|| loopCounter - pLoopCounter > 6
&& rect.x + (rect.width / 2.0) > (borderLeftX * CAMERA_WIDTH)
&& rect.x + (rect.width / 2.0) < CAMERA_WIDTH - (borderRightX * CAMERA_WIDTH)
&& rect.y + (rect.height / 2.0) > (borderTopY * CAMERA_HEIGHT)
&& rect.y + (rect.height / 2.0) < CAMERA_HEIGHT - (borderBottomY * CAMERA_HEIGHT)
) {
maxArea = rect.area();
maxRect = rect;
pLoopCounter++;
loopCounter = pLoopCounter;
first = true;
} else if (loopCounter - pLoopCounter > 10) {
maxArea = new Rect().area();
maxRect = new Rect();
}
areaPoints.release();
}
contour.release();
}
/*if (contours.isEmpty()) {
maxRect = new Rect(600,1,1,1);
} */
}
// Draw Rectangles If Area Is At Least 500
if (first && maxRect.area() > 500) {
Imgproc.rectangle(input, maxRect, new Scalar(0, 255, 0), 2);
}
// Draw Borders
Imgproc.rectangle(input, new Rect(
(int) (borderLeftX * CAMERA_WIDTH),
(int) (borderTopY * CAMERA_HEIGHT),
(int) (CAMERA_WIDTH - (borderRightX * CAMERA_WIDTH) - (borderLeftX * CAMERA_WIDTH)),
(int) (CAMERA_HEIGHT - (borderBottomY * CAMERA_HEIGHT) - (borderTopY * CAMERA_HEIGHT))
), HOT_PINK, 2);
// Display Data
Imgproc.putText(input, "Area: " + getRectArea() + " Midpoint: " + getRectMidpointXY().x + " , " + getRectMidpointXY().y, new Point(5, CAMERA_HEIGHT - 5), 0, 0.6, new Scalar(255, 255, 255), 2);
loopCounter++;
} catch (Exception e) {
debug = e;
error = true;
}
return input;
}