alan412 / LearnJavaForFTC

This is for learning Java for FTC
126 stars 10 forks source link

Issues with chapters 15 and 16 #52

Closed Windwoes closed 2 years ago

Windwoes commented 2 years ago

Date on version you are commenting on

May 1 2022

Section you are commenting on

15 and 16

Comments

alan412 commented 2 years ago

Also, if you'll give me your name and any associated FTC team then I'll be happy to add you to the Credits. I really appreciate your taking the time to give feedback!!

Windwoes commented 2 years ago

we actually use stopStreaming because it doesn't close the connection to your camera which allows you to start it again later if needed with less lag. Is there a non-blocking call that stops the streaming but doesn't close the device?

Hmm, EOCV does not currently have a non-blocking call to stop streaming, no. I suppose you could make a new thread and call it from that. Not exactly best practice though.... probably something I could support in the next release of EOCV though.

I modified the text. Please let me know what you think

Looks better :')

For the input mat, my understanding (which may not be correct) is that if you return a different mat than the one that was passed to you then you need to release the one that was passed to you and the one you return will continue in the processing.

Well, first things first, your example code actually crashes on EOCV on real hardware because releasing input() breaks some internal logic that checks to make sure a sane Mat size was returned for display on the viewport. (It will throw an exception complaining that "User pipeline returned frame of unexpected size"). The input Mat that is delivered to your Pipeline is always the same object - the framebuffer is static and is re-used. There is no memory leak from not releasing it.

For the HSV mat, you need to release it since it is being filled by the cvtColor call.

Because it's an instance variable and not a local variable, the same chunk of memory is being filled each time so there is no leak. Also, after removing the input.release() call to allow the code to run on real hardware, I'm actually getting a memory leak even with the call to release the HSV mat.

memleak

I think it's leaking due to Core.split replacing the old Mats in the arraylist without releasing them.

Here's a modified version of your pipeline which runs on real hardware and does not leak memory and does not need to call .release(). If this causes a memory leak in EOCV-Sim then that's a bug in the simulator that you should report :)

public class FirstPipelineRevised extends OpenCvPipeline
{
    public Scalar nonSelectedColor = new Scalar(0,255,0);
    public Scalar selectedColor = new Scalar(0,0,255);

    public Rect rect1 = new Rect(110, 42, 40, 40);
    public Rect rect2 = new Rect(160, 42, 40, 40);
    public Rect rect3 = new Rect(210, 42, 40, 40);
    public int selectedRect = 0;

    Mat hsvMat = new Mat();
    Mat destMat = new Mat();
    Mat detectionMat = new Mat();

    @Override
    public Mat processFrame(Mat input)
    {
        Imgproc.cvtColor(input, hsvMat, Imgproc.COLOR_RGB2HSV);
        Core.extractChannel(hsvMat, detectionMat, 1);
        Imgproc.cvtColor(detectionMat, destMat, Imgproc.COLOR_GRAY2RGB);

        drawRectangles(destMat);

        return destMat;
    }

    public void drawRectangles(Mat input)
    {
        Imgproc.rectangle(input, rect1, nonSelectedColor);
        Imgproc.rectangle(input, rect2, nonSelectedColor);
        Imgproc.rectangle(input, rect3, nonSelectedColor);

        switch (selectedRect) {
            case 1:
                Imgproc.rectangle(input, rect1, selectedColor);
                break;
            case 2:
                Imgproc.rectangle(input, rect2, selectedColor);
                break;
            case 3:
                Imgproc.rectangle(input, rect3, selectedColor);
                break;
        }
    }
}

noleak


The thing with memory leaking is that you want to avoid allocating new Mats in processFrame(). If must do it, then you have to release them. But if you allocate Mats outside processFrame and simply reference them inside, the chunk of memory is being re-used and there is no leak.

alan412 commented 2 years ago

Thank you very much!! I didn't know about extractChannel - that is a MUCH cleaner way of doing it. What is your name so I can put you in the Credits?

Windwoes commented 2 years ago

Michael - 4634 alum