Один рыбий глаз для проекции angular с камерой, направленной вниз - PullRequest
0 голосов
/ 25 марта 2020

Я пытаюсь сгенерировать equire cangular изображение из одного «рыбьего глаза» в программе Java с использованием OpenCV. Мой код основан на странице Пола Бурка http://paulbourke.net/dome/fish2/

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;

public class FishEyeToEqui {
    static {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);   
    }

    private static double FOV = Math.PI * (220 / 180.0); //Fisheye has 220 deg of FOV

    public static void main(String[] args) {
        String filename = new String("");
        if(args.length > 0) {
            filename = args[0];
        }
        if("".equals(filename)) {
            filename = "/test/fish2sphere220.jpg";
        }
        Mat fisheyeImage = Imgcodecs.imread(filename);

        Mat equirectangularImage = fishToEq(fisheyeImage);

        Imgcodecs.imwrite("/test/equi.jpeg", equirectangularImage);
    }


    private static Mat fishToEq(Mat fisheyeImage) {
        Mat equirectangularImage = new Mat(fisheyeImage.height(), fisheyeImage.width()*2, fisheyeImage.type());
        int length = fisheyeImage.width();

        for (int i = 0; i < length; i++) {
            for (int j = 0; j < 2 * length; j++) {
                double theta = 2.0 * Math.PI * ((double)j / (2.0 * length) - 0.5);
                double phi = Math.PI * ((double)i / length - 0.5);
                double sphx = Math.cos(phi) * Math.sin(theta);
                double sphy = Math.cos(phi) * Math.cos(theta);
                double sphz = Math.sin(phi);
                theta = Math.atan2(sphz, sphx);
                phi = Math.atan2(Math.hypot(sphx, sphz) , sphy);
                double r = length * phi / FOV;
                int x = (int)(0.5 * length + r * Math.cos(theta));
                int y = (int)(0.5 * length + r * Math.sin(theta));


                if (x >= 0 && x < length && y >= 0 && y < length) {
                    double[] res = fisheyeImage.get(x, fisheyeImage.width() - 1 - y);
                    equirectangularImage.put(i, j, res);
                }
            }
        }

        return equirectangularImage;
    }   
}

Использование этого изображения http://paulbourke.net/dome/fish2/fish2sphere220.jpg Я получаю этот результат: https://photos.app.goo.gl/BrBkXpmxhvqZR1S1A Это почти нормально, но я получаю поворот точек: красная часть находится на верхнем месте, а не на правой. Если кто-то может дать мне решение, должно быть здорово!

Но это не главная цель этого поста. Реальное изображение было снято с камерой, направленной вниз под углом 45 градусов. Тогда я думаю, что должен получить прямую проекцию angular с этой формой: http://paulbourke.net/dome/fish2/polar220v60.jpg (эта на 60 градусов вверх)

Я читал эту статью: Как преобразовать сферические координаты в равные angular координаты проекции?

Но мои математические навыки слишком ограничены, чтобы реализовать это в моем коде.

Как я могу реализовать это, чтобы получить правильные прямое angular изображение для каждой камеры, направленное вниз / вверх?

Большое спасибо

...