Search code examples
javaandroidopencvblending

Overlay transparent colour on preview


I am writting a motion detector. I am able to detect motion in specific areas of the frame. Now, i want to highlight that area with a transparent colour.

I am using OpenCV for Android.

I found other tutorials using other languages, like this.

They use addWeighted() to blend two images.

At the moment, i just try to overlay the preview frame. I tried the following code:

public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame {
mRgba = inputframe.rgba();
//defined a Mat that overlays the frame:
Mat greenOverlay = mRgba.submat(0, mRgba.height(), 0, mRgba.width()/5)
mGreenOverlay.setTo(GREEN);

Core.addWeighted(mGreenOverlay,0.5,mRgba,0.5, 0.0, mRgba);
return mRgba;
}

The problem (logcat shows this) is that greenOverlay and inputFrame do not have the same size. Logcat message:

OpenCV Error: Sizes of input arguments do not match 
(The operation is neither 'array op array' 
(where arrays have the same size and the same number of channels), 
nor 'array op scalar', nor 'scalar op array')

How can i solve this problem?

Solution

Toris answer works. Code looks like this:

Mat greenOverlay = mRgba.clone();
Imgproc.rectangle(greenOverlay, new Point(0, 0), new 
                  Point(mRgba.width()/5, mRgba.height()), GREEN, -1);
Core.addWeighted(greenOverlay,0.25,mRgba,0.75, 0.0, mRgba);

Solution

  • From tutorial (written in python) shown in question:

    overlay = image.copy()
    output = image.copy()
    
    cv2.rectangle(overlay, ...)
    

    And from reference of OpenCV:
    https://docs.opencv.org/2.4/modules/core/doc/operations_on_arrays.html#addweighted

    addWeighted()
    src2 – second input array of the same size and channel number as src1.

    So, clone mRgba to make greenOverlay and draw rect on it.


    Sample code (not tested):

    Replace

    Mat greenOverlay = mRgba.submat(0, mRgba.height(), 0, mRgba.width()/5);
    mGreenOverlay.setTo(GREEN);
    

    With

    Mat greenOverlay = mRgba.clone();
    Core.rectangle(greenOverlay, new Point(0, 0), new Point(mRgba.width()/5, mRgba.height()), GREEN, -1);