Changing the color of an object in an Android application

Basically my goal is change the color of object in real time for paint application. To achieve this goal I follow the following concepts:

  1. I use the canny() metod for finding the object.
  2. Using findContours() for edge detection.
  3. using drawContours() for coloring the object. If there is any other concept require to achieve the goal please suggest me. I have tried but not getting exact contours edge. original input

original image

  • How to slide an ImageView from left to right smoothly in Android?
  • DialogFragment : Using AlertDialog with custom layout
  • Difference between ActionBarSherlock and ActionBar Compatibility
  • Memory leak in Android when trying to send a form with image to PHP server
  • IllegalArgumentException: Service not registered:
  • ActionBarActivity with ActionBarDrawerToggle - Not using drawerImageRes
  • Expected output

    Expected output

    Current output

    getting output

    I am getting image in gray scale but i want in rgb mode.

    here is my code:

    package com.example.imageprocess;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.opencv.android.BaseLoaderCallback;
    import org.opencv.android.CameraBridgeViewBase;
    import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
    import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
    import org.opencv.android.LoaderCallbackInterface;
    import org.opencv.android.OpenCVLoader;
    import org.opencv.core.CvType;
    import org.opencv.core.Mat;
    import org.opencv.core.MatOfPoint;
    import org.opencv.core.Point;
    import org.opencv.core.Scalar;
    import org.opencv.core.Size;
    import org.opencv.imgproc.Imgproc;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.WindowManager;
    
    public class MainActivity extends Activity implements CvCameraViewListener2{
    
    
            private Mat                    mRgba;
            private Mat                    mIntermediateMat;
            private Mat                    mGray;
    
            private CameraBridgeViewBase   mOpenCvCameraView;
    
            private BaseLoaderCallback  mLoaderCallback = new BaseLoaderCallback(this) {
                @Override
                public void onManagerConnected(int status) {
                    switch (status) {
                        case LoaderCallbackInterface.SUCCESS:
                        {
                            Log.i("OPENCVACTIVITY", "OpenCV loaded successfully");
    
                            // Load native library after(!) OpenCV initialization
                           // System.loadLibrary("mixed_sample");
    
                            mOpenCvCameraView.enableView();
                        } break;
                        default:
                        {
                            super.onManagerConnected(status);
                        } break;
                    }
                }
            };
    
           /* public MainActivity() {
                Log.i("OPENCVACTIVITY", "Instantiated new " + this.getClass());
            }
    */
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
              getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    
                setContentView(R.layout.activity_main);
    
                mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.tutorial2_activity_surface_view);
                mOpenCvCameraView.setCvCameraViewListener(this);
        }
    
    
    
        @Override
        public void onPause()
        {
            super.onPause();
            if (mOpenCvCameraView != null)
                mOpenCvCameraView.disableView();
        }
    
        @Override
        public void onResume()
        {
            super.onResume();
            OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
        }
    
        public void onDestroy() {
            super.onDestroy();
            if (mOpenCvCameraView != null)
                mOpenCvCameraView.disableView();
        }
    
        @Override
        public void onCameraViewStarted(int width, int height) {
            // TODO Auto-generated method stub
             mRgba = new Mat(height, width, CvType.CV_8UC4);
                mIntermediateMat = new Mat(height, width, CvType.CV_8UC4);
                mGray = new Mat(height, width, CvType.CV_8UC1);
    
        }
    
        @Override
        public void onCameraViewStopped() {
             mRgba.release();
                mGray.release();
                mIntermediateMat.release();
    
        }
    
        @Override
        public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
            Mat gaussian_output = new Mat();
             mRgba = inputFrame.rgba();
             Imgproc.Canny(inputFrame.gray(), mIntermediateMat, 80, 100);
             Imgproc.cvtColor(mIntermediateMat, mRgba, Imgproc.COLOR_YUV2RGBA_NV21, 4);
             Imgproc.GaussianBlur(mIntermediateMat, gaussian_output, new Size(5, 5), 5);
             List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
             Imgproc.findContours( gaussian_output, contours, new Mat(),Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE, new Point(0,0) );
             Scalar color = new Scalar(165, 30, 215);
            // Imgproc.drawContours(gaussian_output, contours, -1, color, 3);
             Mat hierarchy = new Mat();
          // find contours:
          Imgproc.findContours(gaussian_output, contours, hierarchy, Imgproc.RETR_TREE,Imgproc.CHAIN_APPROX_SIMPLE);
          for (int contourIdx = 0; contourIdx < contours.size(); contourIdx++) {
              Imgproc.drawContours(gaussian_output, contours, contourIdx,color, -1);
          }
    
            return gaussian_output;
        }
    
    
    }
    

    Related posts:

    Android: how to warp images?
    Using MediaCodec to save series of images as Video
    Heart Rate measuring using Xiaomi MiBand and BLE
    Positioning menu items to the left of the ActionBar in Honeycomb
    Android: include a xml into an other xml
    Difference between cocos2d-android and cocos2d-android-1
  • Drawable Rotating around its center Android
  • Android RuntimeException: Unable to instantiate the service
  • Suppress “Identifier not allowed in Android”
  • Best practice: passing objects between Android activities
  • Cannot Resolve ContextCompat in Android
  • Remove glare from photo opencv
  • 2 Solutions collect form web for “Changing the color of an object in an Android application”

    I believe that you made the error of moving the grayscale image to the coloured image.

    Try:
    Imgproc.cvtColor(mRgba, mIntermediateMat, Imgproc.COLOR_YUV2RGBA_NV21, 4);
    Instead of:
    Imgproc.cvtColor(mIntermediateMat, mRgba, Imgproc.COLOR_YUV2RGBA_NV21, 4);

    A bit late to the party. I have not tried the code out, but I suspect:

    mIntermediateMat = new Mat(height, width, CvType.CV_8UC4);
    

    Even though mIntermediateMat is 8bit 4 channel mat here,

    Imgproc.Canny(inputFrame.gray(), mIntermediateMat, 80, 100);
    

    It was turned into a 8bit 1 channel mat here. ref: canny doc.

    output edge map; it has the same size and type as image .

    As a result,

    Imgproc.GaussianBlur(mIntermediateMat, gaussian_output, new Size(5, 5), 5);
    

    gaussian_output is an 8bit 1 channel mat, and…

    return gaussian_output;
    

    returns an 8 bit 1 channel (grayscale) image.

    Android Babe is a Google Android Fan, All about Android Phones, Android Wear, Android Dev and Android Games Apps and so on.