2013-02-18 23 views
18

我想寫適用SURF目標檢測代碼,所以我把OpenCV的樣品(樣品3)中的一個,我開始更新onCameraViewStarted()onCameraFrame()方法,但我不斷收到一個運行時錯誤,當我試試我的Galaxy S3手機上,我找不到任何東西來幫助我的問題在這裏是我的代碼,我更新的內容: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; 
} 
} 

注:我曾嘗試在onCameraFrame()方法講評一切,但featureDetector.detect(mRgba, keyPoints)和仍然給我的手機運行時錯誤。

+4

你能分享有關錯誤的更多細節?即堆棧跟蹤/ adb logcat輸出? – T045T 2013-05-19 10:25:26

回答

1

如果我沒有弄錯,OpenCV SURF Feature Detector只能用於灰度圖像。因此,嘗試在onCameraFrame()方法您的來電後添加這CopyTo從

cvtColor(mRgba, mGrayMat, COLOR_RGBA2GRAY); 
0

SURF或SIFT僅支持灰度。所以你必須先用下面的代碼將它轉換成灰度: cvtColor(mRgba,mRgba,CV_BGR2GRAY);

1

您確定以正確的方式使用SIFT嗎? 據我所知,SIFT和SURF不包括在OpenCV Android的分發包中。 要使用它們,您需要編譯非自由模塊並在您的項目中使用它。因此,您需要做的是創建一個NDK項目,將非自由模塊作爲獨立庫進行編譯。然後使用這個庫來編譯你的程序。那麼你應該能夠建立你的應用程序。你可以參考這個tutorial

獲得jni庫後,您可以輕鬆將其包裝到JAVA JNI接口。那麼你應該可以在Android應用程序中使用JAVA界面。

0

要評論cid和HMK的答案(對不起,我沒有50個「添加評論」的聲望,所以我必須創建一個新的答案)。

OpenCV庫可以接受彩色圖像作爲輸入。 以下是我的SIFT檢測和說明提取代碼。它工作得很好。這意味着您不需要將圖像轉換爲灰度格式,但SIFT算法僅適用於灰度圖像。我相信OpenCV檢測器已經做了一些預處理。 (由於suft探測器,並以類似的方式篩選工作,我承擔SURF不需要灰度格式輸入要麼)

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;