OpenCV 特征点检测器

18

我正在尝试编写一个应用SURF对象检测的代码,因此我参考了其中一个openCV的示例(示例3),并开始更新onCameraViewStarted()onCameraFrame()方法,但当我在我的Galaxy 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() 方法中的 featureDetector.detect(mRgba, keyPoints) 以外的所有内容,但在我的手机上仍然会出现运行时错误。

注:本人已尝试注释掉 onCameraFrame() 方法内除了 featureDetector.detect(mRgba, keyPoints) 外的所有内容,但在我的手机上仍然出现运行时错误。

4
你能否分享更多关于错误的细节?例如堆栈跟踪/ adb logcat 输出? - T045T
4个回答

1
如果我没记错的话,OpenCV SURF 特征检测器只能处理灰度图像。因此,请尝试在 onCameraFrame() 方法中调用 copyTo 后添加以下代码:
cvtColor(mRgba, mGrayMat, COLOR_RGBA2GRAY);

1

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

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


0

针对cid和HMK的答案发表评论(很抱歉,我没有50个声望点数来“添加评论”,所以我不得不创建一个新答案)。

OpenCV库可以接受彩色图像作为输入。以下是我的SIFT检测和描述提取代码。它运行得非常好。这意味着您不需要将图像转换为灰度格式,尽管SIFT算法只能在灰度图像上工作。我相信OpenCV检测器已经进行了一些预处理。(由于SURF检测和SIFT工作方式类似,因此我认为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;

0

SURF或SIFT仅支持灰度图像。因此,您必须首先使用以下代码将其转换为灰度图像:

cvtColor(mRgba,mRgba,CV_BGR2GRAY);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接