unfinished
This commit is contained in:
parent
f3a5a54f67
commit
822a502a2e
|
@ -6,7 +6,9 @@ import java.text.SimpleDateFormat
|
|||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
|
||||
buildFeatures{
|
||||
buildConfig = true;
|
||||
}
|
||||
defaultConfig {
|
||||
minSdkVersion 24
|
||||
//noinspection ExpiredTargetSdkVersion
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"sourcesPath": ".",
|
||||
"resourcesPath": ".",
|
||||
"excludedPaths": [],
|
||||
"excludedFileExtensions": [],
|
||||
"eocvSimVersion": "3.5.2"
|
||||
}
|
|
@ -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'
|
||||
}
|
||||
|
||||
|
|
|
@ -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'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue