2015-06-22 23 views
28

Fondamentalmente il mio obiettivo è cambiare il colore dell'oggetto in tempo reale per l'applicazione di pittura. Per raggiungere questo obiettivo, seguo i seguenti concetti:Modifica del colore di un oggetto in un'applicazione Android

  1. Ho utilizzato il metodo canny() per trovare l'oggetto.
  2. Utilizzo di findContours() per il rilevamento dei bordi.
  3. utilizzando drawContours() per colorare l'oggetto.

Se c'è qualche altro concetto richiesto per raggiungere l'obiettivo, per favore mi suggerisco . Ho provato ma non ottenendo il contorno preciso.

ingresso originale:

uscita prevista:

Expected output

Uscita in corrente:

getting output

Sto ottenendo l'immagine in scala di grigi ma voglio in modalità rgb.

Ecco il mio codice:

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


} 

risposta

1

Credo che hai fatto l'errore di spostare l'immagine in scala di grigi per l'immagine colorata.

Prova: Imgproc.cvtColor(mRgba, mIntermediateMat, Imgproc.COLOR_YUV2RGBA_NV21, 4); Invece di: Imgproc.cvtColor(mIntermediateMat, mRgba, Imgproc.COLOR_YUV2RGBA_NV21, 4);

+0

codice sopra non funziona ... in questo momento sto ottenendo l'immagine in scala di grigi ma voglio che la fotocamera debba essere aperta con un'immagine colorata e quando tocco l'oggetto particolare quindi il colore dell'oggetto deve essere cambiato – Prabhakar

+0

Mi sento ancora come se si sta facendo un po ' gravi errori nel metodo onCameraFrame. Si ottiene una versione rgba e in scala di grigi di inputFrame, quindi in seguito si utilizza la scala di grigi come input e l'rgba come un outpur lo sovrascrive in modo efficace. – marko5049

+0

quando ho provato a seguire il codice in oncameraFrame() ottenendo lo stesso risultato, voglio dire l'immagine mostra in scala di grigi \t \t Imgproc.Canny (mRgba, mIntermediateMat, 80, 100); Imgproc.cvtColor (mIntermediateMat, mRgba, Imgproc.COLOR_YUV2RGBA_NV21, 4); – Prabhakar

1

Un po 'in ritardo alla festa. Non ho provato il codice, ma ho il sospetto:

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

Anche se mIntermediateMat è 8bit 4 canali mat qui,

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

E 'stato trasformato in un tappeto di canale 8bit 1 qui. rif: canny doc.

mappa bordo di uscita; ha le stesse dimensioni e tipo dell'immagine.

Come risultato,

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

gaussian_output è un tappetino canale 8bit 1, e ...

return gaussian_output; 

restituisce un'immagine a 8 bit 1 canale (scala di grigi).