OpenCV FeatureDetector

时间:2013-02-18 15:50:16

标签: java android opencv image-processing object-detection

我正在尝试编写一个应用 SURF 对象检测的代码,因此我采用了一个openCV示例(示例3)并开始更新onCameraViewStarted()和{{1}但是当我在我的Galaxy S3手机上试用它时,我一直遇到运行时错误,我找不到任何可以解决我的问题的方法,这是我的代码和我更新的内容:

onCameraFrame()

注意:我尝试在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; } } 方法中对featureDetector.detect(mRgba, keyPoints)以外的所有内容进行评论,但仍然在手机上发出运行时错误。

4 个答案:

答案 0 :(得分:1)

如果我没弄错的话,OpenCV SURF特征探测器仅适用于灰度图像。因此,请在onCameraFrame()方法中调用 copyTo 后尝试添加此内容:

cvtColor(mRgba, mGrayMat, COLOR_RGBA2GRAY);

答案 1 :(得分:1)

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

获得jni库后,可以轻松地将其包装到JAVA JNI接口。然后,您应该能够在Android应用程序中使用JAVA界面。

答案 2 :(得分:0)

SURF或SIFT仅支持灰度。因此,您必须先使用以下代码将其转换为灰度: cvtColor(mRgba,mRgba,CV_BGR2GRAY);

答案 3 :(得分: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;