Распознавание объектов ORB не работает с Java OpenCV - PullRequest
0 голосов
/ 02 июля 2019

Я пытаюсь реализовать обнаружение объекта ORB, используя opencv на Java.Я установил opencv 4.1.0 и следовал этому учебнику и менял вещи по мере необходимости (я знаю, что это не для ORB, только чтобы понять, что делать).Однако, когда я на самом деле запускаю код, область, которую он обнаруживает, находится совсем рядом с зеленой книгой, которую он должен найти.

nowhere near the green book that its supposed to find.

Я понятия не имею, почему это так, может быть, потому чтокакой-то код технически для другого метода?Я пытался использовать больше ключевых точек, но это ничего не изменило.

Вот код, он использует javafx для отображения изображения на случай, если оно имеет значение:

public class OrbDetector extends Application{

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {

        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

        String bookObject = "/Users/yoelkastro/Desktop/bookobject.jpg";
        String bookScene = "/Users/yoelkastro/Desktop/bookscene.jpg";

        // Get images
        Mat objectImage = Imgcodecs.imread(bookObject, Imgcodecs.IMREAD_COLOR);
        Mat sceneImage = Imgcodecs.imread(bookScene, Imgcodecs.IMREAD_COLOR);

        // Find keypoints and descriptor using ORB
        ORB orb = ORB.create(500);
        MatOfKeyPoint keypoints = new MatOfKeyPoint();
        Mat descriptors = new Mat();
        orb.detectAndCompute(objectImage, new Mat(), keypoints, descriptors);
        Mat outputImage = new Mat(objectImage.rows(), objectImage.cols(), Imgcodecs.IMREAD_COLOR);
        Features2d.drawKeypoints(objectImage, keypoints, outputImage);

        // Find keypoints and descriptor for scene using ORB
        ORB orb2 = ORB.create(500);
        MatOfKeyPoint sceneKeypoints = new MatOfKeyPoint();
        Mat sceneDescriptors = new Mat();
        orb2.detectAndCompute(sceneImage, new Mat(), sceneKeypoints, sceneDescriptors);
        Mat sceneOutputImage = new Mat(sceneImage.rows(), sceneImage.cols(), Imgcodecs.IMREAD_COLOR);
        Features2d.drawKeypoints(sceneImage, sceneKeypoints, sceneOutputImage);

        // Convert descriptors
        descriptors.convertTo(descriptors, CvType.CV_32F);
        sceneDescriptors.convertTo(sceneDescriptors, CvType.CV_32F);

        DescriptorMatcher descriptorMatcher = DescriptorMatcher.create(DescriptorMatcher.FLANNBASED);
        Mat matchOutput = new Mat(sceneImage.rows() * 2, sceneImage.cols() * 2, Imgcodecs.IMREAD_COLOR);

        List<MatOfDMatch> matches = new LinkedList<MatOfDMatch>();

        // Match the descriptors for the scene and object
        descriptorMatcher.knnMatch(descriptors, sceneDescriptors, matches, 2);

        LinkedList<DMatch> goodMatchesList = new LinkedList<DMatch>();

        float nndrRatio = 0.8f;

        // Find the number of good matches+
        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.addLast(m1);

            }
        }
        System.out.println(goodMatchesList.size());

        if (goodMatchesList.size() >= 4) {
            System.out.println("Object Found!!!");

            List<KeyPoint> objKeypointlist = keypoints.toList();
            List<KeyPoint> scnKeypointlist = sceneKeypoints.toList();

            LinkedList<Point> objectPoints = new LinkedList<>();
            LinkedList<Point> scenePoints = new LinkedList<>();

            for (int i = 0; i < goodMatchesList.size(); i++) {
                objectPoints.addLast(objKeypointlist.get(goodMatchesList.get(i).queryIdx).pt);
                scenePoints.addLast(scnKeypointlist.get(goodMatchesList.get(i).trainIdx).pt);
            }

            MatOfPoint2f objMatOfPoint2f = new MatOfPoint2f();
            objMatOfPoint2f.fromList(objectPoints);
            MatOfPoint2f scnMatOfPoint2f = new MatOfPoint2f();
            scnMatOfPoint2f.fromList(scenePoints);

            Mat homography = Calib3d.findHomography(objMatOfPoint2f, scnMatOfPoint2f, Calib3d.RANSAC, 3);

            Mat obj_corners = new Mat(4, 1, CvType.CV_32FC2);
            Mat scene_corners = new Mat(4, 1, CvType.CV_32FC2);

            obj_corners.put(0, 0, new double[]{0, 0});
            obj_corners.put(1, 0, new double[]{objectImage.cols(), 0});
            obj_corners.put(2, 0, new double[]{objectImage.cols(), objectImage.rows()});
            obj_corners.put(3, 0, new double[]{0, objectImage.rows()});

            System.out.println("Transforming object corners to scene corners...");
            Core.perspectiveTransform(obj_corners, scene_corners, homography);

            Imgproc.line(sceneImage, new Point(scene_corners.get(0, 0)), new Point(scene_corners.get(1, 0)), new Scalar(0, 255, 0), 4);
            Imgproc.line(sceneImage, new Point(scene_corners.get(1, 0)), new Point(scene_corners.get(2, 0)), new Scalar(0, 255, 0), 4);
            Imgproc.line(sceneImage, new Point(scene_corners.get(2, 0)), new Point(scene_corners.get(3, 0)), new Scalar(0, 255, 0), 4);
            Imgproc.line(sceneImage, new Point(scene_corners.get(3, 0)), new Point(scene_corners.get(0, 0)), new Scalar(0, 255, 0), 4);

            System.out.println("Drawing matches image...");
            MatOfDMatch goodMatches = new MatOfDMatch();
            goodMatches.fromList(goodMatchesList);

            Features2d.drawMatches(objectImage, keypoints, sceneImage, sceneKeypoints, goodMatches, matchOutput);

        } else {
            System.out.println("Object Not Found");
        }



        ImageView i = new ImageView(Test.mat2Img(matchOutput));
        Group root = new Group();
        root.getChildren().add(i);

        stage.setScene(new Scene(root));
        stage.show();

    }
}

Любая помощь вообщеочень признателен, так как я довольно новичок в opencv в целом и не знаю, как с этим справиться

...