如何在FeatureDetector.detect(OpenCV-2.4.11 Android)中修复分段错误(SIGSEGV)?

问题描述 投票:0回答:1

我正在尝试使用SURF算法进行对象识别。我正在使用OpenCV 2.4.11和Google的Camera2BasicExample。功能在构造函数中被提取,但它会在detectNotes函数中导致分段错误。

我尝试在互联网上搜索它,但找不到任何相关的解决方案。

我在下面附上了SURFDetector类:

public class SURFDetector {
    private FeatureDetector featureDetector;
    private DescriptorExtractor descriptorExtractor;
    private DescriptorMatcher descriptorMatcher;
    private HashMap<String, Mat> notes;
    private HashMap<String, MatOfKeyPoint> notesKeyPoints;
    private HashMap<String, KeyPoint[]> keyPoints;
    private HashMap<String, MatOfKeyPoint> notesDescriptors;

    public SURFDetector() { }

    public SURFDetector(AssetManager assets) {
        featureDetector = FeatureDetector.create(FeatureDetector.SURF);
        descriptorExtractor = DescriptorExtractor.create(DescriptorExtractor.SURF);
        descriptorMatcher = DescriptorMatcher.create(DescriptorMatcher.FLANNBASED);

        notes = new HashMap<String, Mat>();
        notesKeyPoints = new HashMap<String, MatOfKeyPoint>();
        keyPoints = new HashMap<String, KeyPoint[]>();
        notesDescriptors = new HashMap<String, MatOfKeyPoint>();

        try {
            String[] names = assets.list("");
            for(String name:names) {
                if (name.contains("India")) {
                    Mat note  = Highgui.imread(name, Highgui.CV_LOAD_IMAGE_COLOR);
                    notes.put(name, note);

                    MatOfKeyPoint kp = new MatOfKeyPoint();
                    featureDetector.detect(note, kp);
                    notesKeyPoints.put(name, kp);
                    keyPoints.put(name, kp.toArray());

                    MatOfKeyPoint d = new MatOfKeyPoint();
                    descriptorExtractor.compute(note, kp, d);
                    notesDescriptors.put(name, new MatOfKeyPoint());

                    Log.i("SURF", name +
                        "\nImage: " + notes.get(name).toString() +
                        "\nkeyPoints: " + keyPoints.get(name).toString() +
                        "\nMat: " + note.toString());
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public String detectNotes(Image image) {
        featureDetector = FeatureDetector.create(FeatureDetector.SURF);
        descriptorExtractor = DescriptorExtractor.create(DescriptorExtractor.SURF);
        descriptorMatcher = DescriptorMatcher.create(DescriptorMatcher.FLANNBASED);

        Log.v("SIGSEGV", "Converting image to Mat");
        Mat buf = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8UC1);
        ByteBuffer buffer = image.getPlanes()[0].getBuffer();
        byte[] bytes = new byte[buffer.remaining()];
        buffer.get(bytes);
        buf.put(0, 0, bytes);
        Log.v("SIGSEGV", "Image -> Mat done");

        Mat scene = Highgui.imdecode(buf, Highgui.IMREAD_COLOR);
        MatOfKeyPoint sceneKeyPoints = new MatOfKeyPoint();
        MatOfKeyPoint sceneDescriptors = new MatOfKeyPoint();

        Mat grayScene = new Mat();
        Imgproc.cvtColor(scene, grayScene, Imgproc.COLOR_BGR2GRAY);

        Log.v("SIGSEGV", scene.toString());
        Log.v("SIGSEGV", sceneKeyPoints.toString());
        Log.v("SIGSEGV", sceneDescriptors.toString());


        Log.v("SIGSEGV", "Feature detection");
        featureDetector.detect(grayScene, sceneKeyPoints);
        Log.v("SIGSEGV", "SceneKeyPoints detected");
        descriptorExtractor.compute(grayScene, sceneKeyPoints, sceneDescriptors);
        Log.v("SIGSEGV", "Feature detection done");

        float nndrRatio = 0.7f;

        Log.v("SIGSEGV", "Loop over all the images");
        for(String key : notesDescriptors.keySet()) {
            List<MatOfDMatch> matches = new LinkedList<MatOfDMatch>();
            LinkedList<DMatch> goodMatchesList = new LinkedList<DMatch>();

            descriptorMatcher.knnMatch(notesDescriptors.get(key), sceneDescriptors, matches, 2);

            for(int i = 0; i < matches.size(); i++) {
                MatOfDMatch matOfDMatch = matches.get(i);
                DMatch[] dmatchArray = matOfDMatch.toArray();
                DMatch m1 = dmatchArray[0];
                DMatch m2 = dmatchArray[1];

                if(m1.distance <= m2.distance * nndrRatio) {
                    goodMatchesList.add(m1);
                }

                if(goodMatchesList.size() >= 7) {
                    Log.i("SURF", "Match Found: " + key);
                    return key;
                }
            }
        }
        Log.v("SIGSEGV", "Loop done");
        Log.i("SURF", "Match Not Found!");
        return null;
    }

}


确切的错误:

04-13 19:46:37.903 4314-4375/com.example.android.camera2basic A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 4375 (CameraBackgroun)
04-13 19:46:37.968 2205-2205/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
    Build fingerprint: 'samsung/o5ltedd/o5lte:6.0.1/MMB29K/G550FYDDU1BRD1:user/release-keys'
    Revision: '0'
    ABI: 'arm'
    pid: 4314, tid: 4375, name: CameraBackgroun  >>> com.example.android.camera2basic <<<
    signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0

请帮我。

android opencv surf
1个回答
0
投票

我在您的代码中没有看到以下内容,因此您可能需要添加:static { System.loadLibrary("opencv_java");}

对于Android上的OpenCV来说,这是一个很好的资源:https://opencv.org/platforms/android/

© www.soinside.com 2019 - 2024. All rights reserved.