OpenCV FeatureDetector

我试图编写一个应用SURF对象检测的代码,所以我拿了一个openCV示例(示例3),并开始更新onCameraViewStarted()onCameraFrame()方法,但是当我尝试使用onCameraViewStarted()onCameraFrame()我的银河S3手机,我找不到任何东西来帮助我的问题在这里是我的代码和我更新:

 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()方法中的onCameraFrame() featureDetector.detect(mRgba, keyPoints)所有其他注释featureDetector.detect(mRgba, keyPoints)并且仍然在我的手机上给出了运行时错误。

Solutions Collecting From Web of "OpenCV FeatureDetector"

如果我没有弄错,OpenCV SURF Feature Detector只能用于灰度图像。 所以尝试在onCameraFrame()方法中调用copyTo之后添加它:

 cvtColor(mRgba, mGrayMat, COLOR_RGBA2GRAY); 

你确定以正确的方式使用SIFT吗? 据我所知,SIFT和SURF都不包含在OpenCV Android的发行包中。 要使用它们,您需要编译非自由模块并在您的项目中使用它。 所以,你需要做的是创build一个NDK项目,将非自由模块作为独立的库进行编译。 然后使用这个库来编译你的程序。 那么你应该能够build立你的应用程序。 你可以参考这个教程 。

获得jni库后,可以轻松将其包装到JAVA JNI接口。 那么你应该可以在Android应用程序中使用JAVA界面。

SURF或SIFT只支持灰度。 所以你必须先用下面的代码将它转换成灰度:cvtColor(mRgba,mRgba,CV_BGR2GRAY);

要评论cid和HMK的答案(对不起,我没有50的声望,因为“添加评论”,所以我必须创build一个新的答案)。

OpenCV库可以接受彩色图像作为input。 以下是我的SIFT检测和描述提取代码。 它工作得很好。 这意味着您不需要将图像转换为灰度格式,尽pipeSIFTalgorithm仅适用于灰度图像。 我相信OpenCV检测器已经做了一些预处理。 (由于suft探测器和筛选工作的方式相似,我假设SURF不需要灰度格式input)

 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;