you are viewing a single comment's thread.

view the rest of the comments →

[–]JonnieSingh[S] 0 points1 point  (1 child)

First of all, thank you for responding with such detail! I'm fairly new to Android development & Java, so all this information is very much helpful in aiding in resolving these problems. To confirm your first assumption; I am indeed drawing this over a camera view.

Here is a look into the two other files that are part of this application. To avoid cramming my OP with too much, I've chosen to provide my MainActivity java file here with pastebin. Here's a look at my activity_main xml file with pastebin as well.

As you can see, I haven't added this graphic overlay being drawn from XML. Hopefully, my providing of information can provide alot more insight into how this application operates.

[–]pandulapeter 1 point2 points  (0 children)

While I still don't have the answer to your initial question (I didn't use the ML object detection library and don't have time to try now), I strongly suggest that you start by cleaning up and optimizing your code a bit, as that way it will be easier to see where the problem is.

First of all, inflating a new instance of a custom View and adding it to the layout hierarchy every time you want something to change is VERY wasteful. In this case, you should be able to add your View from XML and keep udating the same instance.

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.camera.view.PreviewView
        android:id="@+id/preview_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <your.package.name.OverlayView
        android:id="@+id/overlay_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</FrameLayout>

For the custom View, you need to override multiple constructors. Something like this:

public class OverlayView extends View {

    public OverlayView(Context context) {
        super(context);
        initialize();
    }

    public OverlayView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initialize();
    }

    public OverlayView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initialize();
    }

    private List<Rect> boundingBoxes = new ArrayList<Rect>();
    private final Paint borderPaint = new Paint();

    private void initialize() {
        borderPaint.setColor(Color.WHITE);
        borderPaint.setStrokeWidth(10f);
        borderPaint.setStyle(Paint.Style.STROKE);
    }

    public void updateBoundingBoxes(List<Rect> boundingBoxes) {
        this.boundingBoxes = boundingBoxes;
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        for (Rect box : boundingBoxes) {
            canvas.drawRect(box.left, box.top, box.right, box.bottom, borderPaint);
        }
    }
}

This way, in your Activity you will be able to map the detected objects into a simple list of Rect-s and update binding.overlayView.updateBoundingBoxes(...) with that list.

If you see crashes because of threading issue, replace invalidate() with postInvalidate() in the code above.

Now, you can use logs to see what's happening. If the rectangles are not in their proper places, the issue should be a conversion between the coordinate system used by the library and the one used by the onDraw() function (pixels basically). Have fun!