So, we are trying to program a robot for the FTC competition. We are using OpenCV to detect an object. What we need to detect is the position of the object. We have that part all running very well.
Our problem is, we can't take any variable out of the pipeline that actually detects the object position. So, this is pretty much a Java problem, not an OpenCV problem. We're not that well experienced with Java, so, yeah.
Our code is this.
Do you have any advice?
EDIT: Here's a code snippet, I tried making it as short as I could and commenting it as much as possible, basically we need the 'max' variable that I also specified in the comments inside the code
public void runOpMode()
{
//region camera stuff ignore it
int cameraMonitorViewId = hardwareMap.appContext.getResources().getIdentifier("cameraMonitorViewId", "id", hardwareMap.appContext.getPackageName());
WebcamName webcam = hardwareMap.get(WebcamName.class, "milcamerezi");
OpenCvCamera camera = OpenCvCameraFactory.getInstance().createWebcam(webcam, cameraMonitorViewId);
//endregion
camera.openCameraDevice(); //turns camera on
pipeline Pipe = new pipeline() { //the pipeline I was talking about
public int max;
@Override
public Mat processFrame(Mat input) {
//region more camera stuff
Mat mat = new Mat();
mat = input;
Point region1_a = new Point(0,480);
Point region1_b = new Point(100,580);
Imgproc.cvtColor(mat, mat, Imgproc.COLOR_RGB2HSV);
//lower and higher bounds for the color of our object that we need to detect
Scalar lowHSV1 = new Scalar(170,50,10);
Scalar highHSV1 = new Scalar(180,200,100);
Core.inRange(mat, lowHSV1, highHSV1, mat);
Point r1p1 = new Point(0,0);
Point r1p2 = new Point(mat.width()/3f,mat.height());
Point r2p1 = new Point(mat.width()/3f,0);
Point r2p2 = new Point((2*mat.width())/3f,mat.height());
Point r3p1 = new Point((2*mat.width())/3f,0);
Point r3p2 = new Point(mat.width(),mat.height());
//the imaginary rectangles created to detect the possible zones for the object
Rect rect1 = new Rect(r1p1,r1p2);
Rect rect2 = new Rect(r2p1,r2p2);
Rect rect3 = new Rect(r3p1,r3p2);
Mat matLeft = mat.submat(rect1);
Mat matCenter = mat.submat(rect2);
Mat matRight = mat.submat(rect3);
//the regions used to create the value for the 'max' variable
//these region variables contain how many pixels there are in the three zones the object can be in
int region1 = Core.countNonZero(matLeft);
int region2 = Core.countNonZero(matCenter);
int region3 = Core.countNonZero(matRight);
//endregion
//
//
// this is the actual important part, I guess
//
//
//where our 'max' variable gets the value it needs, the variable we need
if(region1 > region2)
if(region1 > region3)
max = 1;
else
max = 3;
else
if(region2 > region3)
max = 2;
else
max = 3;
telemetry.addData("It's in place number: ", max); //should report 1, 2, or 3; in here it works because it is inside the pipeline
telemetry.update();
sleep(300);
return super.processFrame(input);
}
};
camera.setPipeline(Pipe);
camera.startStreaming(640, 480, OpenCvCameraRotation.UPRIGHT);
waitForStart(); //waits for button to get pressed
while (opModeIsActive()) //this runs when that button gets pressed
{
camera.closeCameraDevice();
//we need our 'max' variable here, but we can't use it here
if(max == 1) do_something
else if(max == 2) do_something2
else if(max == 3) do_something3
break; //stop robot; please ignore we have a while loop that runs only once
}
}
}
EDIT2:
pipeline Pipe = new pipeline() { //the pipeline I was talking about
public Mat processFrame(Mat input) {
int max;
//the regions used to create the value for the 'max' variable
//these region variables contain how many pixels there are in the three zones the object can be in
int region1 = 1; //placeholder values
int region2 = 2;
int region3 = 3;
//where our 'max' variable gets the value it needs, the variable we need
if(region1 > region2)
if(region1 > region3)
max = 1;
else
max = 3;
else
if(region2 > region3)
max = 2;
else
max = 3;
System.out.println("It's in place number: ", max); //should report 1, 2, or 3; in here it works because it is inside the pipeline
sleep(300);
return super.processFrame(input);
}
};
camera.setPipeline(Pipe);
camera.startStreaming(640, 480, OpenCvCameraRotation.UPRIGHT);
while(codeIsRunning) //this runs when a button gets pressed
{
//we need our 'max' variable here, but we can't use it here. Making it public won't work either
if(max == 1) do_something
else if(max == 2) do_something2
else if(max == 3) do_something3
break; //stop robot; please ignore we have a while loop that runs only once
}