-1

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
        }
Andy3153
  • 33
  • 4
  • what variable are you trying to get? – dcolazin Feb 17 '22 at 11:59
  • 1
    Welcome to the site. Please include a [mre] of your problem in your question. A question dependent on a link to a github project is not useful for the site. – khelwood Feb 17 '22 at 11:59
  • @dcolazin I was trying to get the 'max' variable – Andy3153 Feb 17 '22 at 12:18
  • @khelwood I just made an edit right now, I hope it is better now – Andy3153 Feb 17 '22 at 12:19
  • @Andy3153 Yes, it is better, but still not a [mre]. – khelwood Feb 17 '22 at 12:21
  • @khelwood Here comes another, smaller example; I really don't know if I could give a more minimal example due to our limited Java knowledge – Andy3153 Feb 17 '22 at 12:38
  • You want to learn what **scope** is in programming. You define a local variable in an anonymous inner class, so you can't get "into" that from the outside. You also want to learn about java naming conventions. Class names start UpperCase, always. So it should be `Pipeline üipe = new Pipeline() ` to begin with! – GhostCat Feb 17 '22 at 12:47

1 Answers1

0

Create your own pipeline class by extending the existing one and provide a getMax() method to retrieve the values of the max variable.

public class MyPipeline extends pipeline {
  private int max; // member variables are generally made private and accesses via methods

  @Override
  public Mat processFrame(Mat input) {
    ... that stuff you wrote ....
  }

  public int getMax() { return max; }
}

Note that the Java naming standard is to define classes with leading uppercase and variables with leading lowercase. I recommend that you adhere to it to avoid confusion when working with other Java developers.

vsfDawg
  • 1,425
  • 1
  • 9
  • 12