unfinished

This commit is contained in:
gallant 2023-09-29 08:06:43 -05:00
parent f3a5a54f67
commit 822a502a2e
6 changed files with 208 additions and 2 deletions

View file

@ -6,7 +6,9 @@ import java.text.SimpleDateFormat
apply plugin: 'com.android.library'
android {
buildFeatures{
buildConfig = true;
}
defaultConfig {
minSdkVersion 24
//noinspection ExpiredTargetSdkVersion

View file

@ -0,0 +1,46 @@
package org.firstinspires.ftc.teamcode.freesight.opmodes;
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import org.firstinspires.ftc.robotcore.external.Telemetry;
import org.firstinspires.ftc.robotcore.external.hardware.camera.WebcamName;
import org.firstinspires.ftc.teamcode.freesight.vision.FreeSightPipeline;
import org.openftc.easyopencv.*;
public class FreeSight {
private FreeSightPipeline pipe;
private final OpenCvWebcam web;
private final Telemetry telemetry;
public FreeSight(LinearOpMode op)
{
web = OpenCvCameraFactory.getInstance().createWebcam(
op.hardwareMap.get(WebcamName.class,"webcam")
);
telemetry = op.telemetry;
}
public void findStuff()
{
pipe = new FreeSightPipeline();
web.openCameraDeviceAsync(new OpenCvCamera.AsyncCameraOpenListener() {
@Override
public void onOpened() {
web.setPipeline(pipe);
web.startStreaming(800, 448, OpenCvCameraRotation.UPRIGHT);
}
@Override
public void onError(int errorCode) {
telemetry.addData("Error:", "Camera produced error code: " + errorCode);
stop();
}
});
}
public void stop()
{
web.stopStreaming();
}
}

View file

@ -0,0 +1,148 @@
package org.firstinspires.ftc.teamcode.freesight.vision;
//import com.acmerobotics.dashboard.config.Config;
import org.firstinspires.ftc.robotcore.external.Telemetry;
import org.firstinspires.ftc.robotcore.internal.opmode.TelemetryImpl;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.MatOfRect;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.imgproc.Imgproc;
import org.openftc.easyopencv.OpenCvPipeline;
import java.util.ArrayList;
//@Config
public class FreeSightPipeline extends OpenCvPipeline {
public enum Prop
{
BLUE,ORANGE,NONE
}
public enum Side
{
LEFT,RIGHT,MIDDLE
}
ArrayList<double[]> frameList = new ArrayList<>();
public Side positionState;
public Scalar lowHSV = new Scalar(0,0,0);
public Scalar highHSV = new Scalar(0,0,0);
public Scalar outline = new Scalar(0,0,0);
public Prop colorState = Prop.NONE;
/**
* @param input the frame to be manipulated
* @return The altered matrix
*/
@Override
public Mat processFrame(Mat input) {
int width = input.width();
int height = input.height();
Mat mat = new Mat();
Imgproc.cvtColor(input, mat, Imgproc.COLOR_RGB2HSV);
if(mat.empty()) return input;
/*
* BLUE
* Scalar lowHSV = new Scalar(55.3, 62.3, 53.8);
* Scalar highHSV = new Scalar(213.9, 240.8, 255);
*/
if(colorState == Prop.BLUE)
{
lowHSV = new Scalar(55.3, 62.3, 53.8);
highHSV = new Scalar(213.9, 240.8, 255);
}
else if(colorState == Prop.ORANGE)
{
lowHSV = new Scalar(0,106.3,198.3);
highHSV = new Scalar(14.2, 255, 255);
}
Mat threshold = new Mat();
Core.inRange(mat, lowHSV, highHSV, threshold);
Mat masked = new Mat();
Core.bitwise_and(mat, mat, masked, threshold);
Scalar avg = Core.mean(masked, threshold);
Mat scaledMask = new Mat();
masked.convertTo(scaledMask, -1, 150/avg.val[1],0);
Mat scaledThresh = new Mat();
double strictLowS;
//you probably want to tune this
if(colorState == Prop.BLUE)
strictLowS = 62.3;
else
strictLowS = 86.4; // orange
Scalar strictLowHSV = new Scalar(0, strictLowS, 0); //strict lower bound HSV for yellow
Scalar strictHighHSV = new Scalar(255, 255, 255); //strict higher bound HSV for yellow
//apply strict HSV filter onto scaledMask to get rid of any yellow other than pole
Core.inRange(scaledMask, strictLowHSV, strictHighHSV, scaledThresh);
//contours, apply post processing to information
ArrayList<MatOfPoint> contours = new ArrayList<>();
Mat hierarchy = new Mat();
//find contours, input scaledThresh because it has hard edges
Imgproc.findContours(scaledThresh, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_NONE);
int index = 0;
int area = 0;
for (int i = 0; i < contours.size(); i++)
{
MatOfPoint bar = contours.get(i);
int foo = bar.width() * bar.height();
if(foo > area)
{
index = i;
area = foo;
}
}
MatOfPoint contour = contours.get(index);
Rect boundingRect = Imgproc.boundingRect(contour);
int min_x = boundingRect.x;
int max_x = boundingRect.x - boundingRect.width;
int min_y = boundingRect.y;
int max_y = boundingRect.y - boundingRect.height;
// center is ( x + w ) / 2
Imgproc.rectangle(
threshold,
new Rect(
min_x,
min_y,
(max_x + min_x),
(max_y + min_y)),
outline
);
//list of frames to reduce inconsistency, not too many so that it is still real-time, change the number from 5 if you want
if (frameList.size() > 5) {
frameList.remove(0);
}
//releasing for ram related reasons
input.release();
scaledThresh.release();
scaledMask.release();
mat.release();
masked.release();
return threshold;
}
}

View file

@ -0,0 +1,7 @@
{
"sourcesPath": ".",
"resourcesPath": ".",
"excludedPaths": [],
"excludedFileExtensions": [],
"eocvSimVersion": "3.5.2"
}

View file

@ -1,6 +1,7 @@
repositories {
mavenCentral()
google() // Needed for androidx
maven { url = 'https://maven.brott.dev/' }
}
dependencies {
@ -17,5 +18,7 @@ dependencies {
implementation 'org.tensorflow:tensorflow-lite-task-vision:0.4.3'
runtimeOnly 'org.tensorflow:tensorflow-lite:2.12.0'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.acmerobotics.dashboard:dashboard:0.4.12'
implementation 'org.openftc:easyopencv:1.7.0'
}

View file

@ -11,7 +11,7 @@ buildscript {
}
dependencies {
// Note for FTC Teams: Do not modify this yourself.
classpath 'com.android.tools.build:gradle:7.2.0'
classpath 'com.android.tools.build:gradle:8.1.1'
}
}