Я пытаюсь сгенерировать 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 изображение для каждой камеры, направленное вниз / вверх?
Большое спасибо