28

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 have used the canny() method for finding the object.
  2. Using findContours() for edge detection.
  3. using drawContours() for coloring the object.

If there is any other concept required to achieve the goal please suggest to me. I have tried but not getting exact contours edge.

Original input:

original image

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;
    }


}
RobC
  • 22,977
  • 20
  • 73
  • 80
Prabhakar
  • 1,781
  • 1
  • 17
  • 23

3 Answers3

1

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);

  • above code is not working ... right now I am getting grayscale image but i want camera should be opened with colored image and when i touch the particular object then object color be changed – Prabhakar Jun 24 '15 at 08:55
  • I still feel as if you are making some grave errors in the onCameraFrame method. You get a rgba and grayscale version of the inputFrame, then you later use the grayscale as an input and the rgba as an outpur effectively overriding it. –  Jun 24 '15 at 09:00
  • when i tried following code in oncameraFrame() getting same output, i mean image shows in grayscale Imgproc.Canny(mRgba, mIntermediateMat, 80, 100); Imgproc.cvtColor(mIntermediateMat, mRgba, Imgproc.COLOR_YUV2RGBA_NV21, 4); – Prabhakar Jun 24 '15 at 09:20
  • I'm not saying that that is the error it might be something else because you are reseting the rgba to grayscale. –  Jun 24 '15 at 09:25
  • Could you please put up the project somewhere so that I can mess with it in Eclipse and see if I can get it working? –  Jun 24 '15 at 09:36
  • could you share your mail id with me – Prabhakar Jun 24 '15 at 09:43
  • diedgaming@gmail.com :) –  Jun 24 '15 at 09:44
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/81386/discussion-between-prabhakar-and-user2693587). – Prabhakar Jun 24 '15 at 10:00
1

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.

pandamakes
  • 571
  • 3
  • 8
0

http://www.labbookpages.co.uk/software/imgProc/libPNG.html

You should use LIBPNG for image processing. Using it you can convert it to grayscale or colored image by setting color matrix.

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
PRATEEK BHARDWAJ
  • 2,364
  • 2
  • 21
  • 35