2013-02-18 16 views
18

Sto cercando di scrivere un codice che si applica SURF rilevamento di oggetti, così ho preso uno dei campioni OpenCV (campione 3) e ho iniziato l'aggiornamento dei onCameraViewStarted() e onCameraFrame() metodi, ma continuo a ricevere un errore di runtime quando provarlo sul mio Galaxy S3 telefono e non ho trovato nulla per aiutare con il mio problema qui è il mio codice e quello che ho aggiornato:OpenCV FeatureDetector

public class Sample3Native extends Activity implements CvCameraViewListener{ 

private static final String TAG = "OCVSample::Activity"; 

private Mat     mRgba; 
private Mat     mGrayMat; 
private CameraBridgeViewBase mOpenCvCameraView; 

Mat descriptors ;   
List<Mat> descriptorsList; 

FeatureDetector featureDetector; 
MatOfKeyPoint keyPoints; 
DescriptorExtractor descriptorExtractor; 
DescriptorMatcher descriptorMatcher;** 


private BaseLoaderCallback  mLoaderCallback = new BaseLoaderCallback(this) { 
    @Override 
    public void onManagerConnected(int status) { 
     switch (status) { 
      case LoaderCallbackInterface.SUCCESS: 
      { 
       Log.i(TAG, "OpenCV loaded successfully"); 

       // Load native library after(!) OpenCV initialization 
       System.loadLibrary("native_sample"); 

       mOpenCvCameraView.enableView(); 
      } break; 
      default: 
      { 
       super.onManagerConnected(status); 
      } break; 
     } 
    } 
}; 

public void onCameraViewStarted(int width, int height) { 
    mRgba = new Mat(height, width, CvType.CV_8UC4); 
    mGrayMat = new Mat(height, width, CvType.CV_8UC1); 
    featureDetector=FeatureDetector.create(4); // SURF= 4; 
    descriptorExtractor=DescriptorExtractor.create(2);//SURF = 2 
    descriptorMatcher=DescriptorMatcher.create(6); //BRUTEFORCE_SL2 = 6** 

} 

public Mat onCameraFrame(Mat inputFrame) { 
    inputFrame.copyTo(mRgba); 
    //detect_1(0, mRgba.getNativeObjAddr(), keyPoints.getNativeObjAddr()); 
    //Now mRgba contains the current frame (start manipulation part) 
    //detecting keypoints 
    featureDetector.detect(mRgba, keyPoints); 
    //draw keypoints 
    // Features2d.drawKeypoints(mRgba, keyPoints, mRgba); 
    //finding descriptors 
    descriptorExtractor.compute(mRgba, keyPoints, descriptors); 
    //Matcher between 2 images or set of images 
    // Note: training set and query set are handled here! (in matcher) 
    //descriptorsList = descriptorMatcher.getTrainDescriptors(); 
    //descriptorsList.add(descriptors); 
    // descriptorMatcher.add(descriptorsList); 

    //Imgproc.cvtColor(mRgba, mGrayMat, Imgproc.COLOR_RGBA2GRAY); 
    //FindFeatures(mGrayMat.getNativeObjAddr(), mRgba.getNativeObjAddr()); 

    return mRgba; 
} 
} 

Nota: ho provato commentare tutto, ma il featureDetector.detect(mRgba, keyPoints) nel metodo onCameraFrame() e ha ancora dato errore di runtime sul mio telefono.

+4

Puoi condividere ulteriori dettagli sull'errore? Cioè un output di stack trace/adb logcat? – T045T

risposta

1

Se non sbaglio, OpenCV SURF Feature Detector funziona solo con immagini in scala di grigi. Quindi cercate di aggiungere questo dopo la vostra chiamata a copyTo nel metodo onCameraFrame():

cvtColor(mRgba, mGrayMat, COLOR_RGBA2GRAY); 
0

SURF o SIFT solo in scala di grigi di supporto. Quindi devi prima convertirlo in scala di grigi con il seguente codice: cvtColor (mRgba, mRgba, CV_BGR2GRAY);

1

Sei sicuro di utilizzare SIFT in modo corretto? Per quanto ne so, SIFT e SURF non sono inclusi nel pacchetto di distribuzione di OpenCV Android. Per utilizzarli, è necessario compilare il modulo non libero e utilizzarlo nel progetto. Quindi, quello che devi fare è creare un progetto NDK, compilare il modulo non libero come libreria indipendente. Quindi utilizzare questa libreria per compilare il programma. Quindi dovresti essere in grado di creare la tua applicazione. È possibile fare riferimento a questo tutorial.

Dopo aver ottenuto la libreria jni, è possibile ricondurla facilmente a un'interfaccia JNI JNI. Quindi dovresti essere in grado di utilizzare l'interfaccia JAVA nella tua applicazione Android.

0

Per commentare la risposta di cid e HMK (mi dispiace, non ho 50 reputazione per "aggiungi commento", quindi devo creare una nuova risposta).

La libreria OpenCV può accettare immagini a colori come input. Quanto segue è il mio rilevamento SIFT e il codice di estrazione della descrizione. Funziona piuttosto bene. Significa che non è necessario convertire l'immagine in un formato in scala di grigi, sebbene l'algoritmo SIFT funzioni solo su immagini in scala di grigi. Credo che il rivelatore OpenCV abbia fatto qualche preelaborazione. (Dal momento che il rivelatore di suft e il vaglio funzionano in modo simile, suppongo che il SURF non richieda input in scala di grigi)

Mat image; 
image = imread(argv[1], CV_LOAD_IMAGE_COLOR); 
if(! image.data) 
{ 
    cout << "Could not open or find the image" << std::endl ; 
    return -1; 
} 

vector<KeyPoint> keypoints; 
Mat descriptors; 

// Create a SIFT keypoint detector. 
SiftFeatureDetector detector; 
detector.detect(image, keypoints); 
cout << "Detected " << (int) keypoints.size() << " keypoints" <<endl; 

// Compute feature description. 
detector.compute(image,keypoints, descriptors); 
cout << "Computed feature."<<endl;