Как исправить ошибку сегментации (SIGSEGV) в FeatureDetector.detect (OpenCV-2.4.11 Android)?

#android #opencv #surf

#Android #opencv #серфинг

Вопрос:

Я пытаюсь использовать алгоритм SURF для распознавания объектов. Я использую OpenCV 2.4.11 и Camera2BasicExample от Google. Функции извлекаются в конструкторе, но это вызывает ошибку сегментации в функции 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
  

Пожалуйста, помогите мне.

Ответ №1:

Я не вижу в вашем коде следующего, поэтому вам может потребоваться добавить это: static { System.loadLibrary("opencv_java");}

Это также отличный ресурс для OpenCV на Android: https://opencv.org/platforms/android /

Комментарии:

1. Я добавил ее в основное действие.