├── README.md ├── Transform.iml ├── out └── production │ └── Transform │ ├── com │ └── creative │ │ └── transform │ │ ├── Cubemap.class │ │ ├── Equirectangular.class │ │ ├── Fisheye.class │ │ └── Main.class │ ├── mp4 │ ├── cubemap.mp4 │ ├── equirectangular.mp4 │ └── fisheye.mp4 │ └── output │ ├── cb2fe.avi │ ├── eq2cm.avi │ ├── fe2eq.avi │ └── temp.png ├── resources ├── mp4 │ ├── cubemap.mp4 │ ├── equirectangular.mp4 │ └── fisheye.mp4 └── output │ ├── cb2fe.avi │ ├── eq2cm.avi │ └── fe2eq.avi └── src └── com └── creative └── transform ├── Cubemap.java ├── Equirectangular.java ├── Fisheye.java └── Main.java /README.md: -------------------------------------------------------------------------------- 1 | # 360ImageTransform -------------------------------------------------------------------------------- /Transform.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /out/production/Transform/com/creative/transform/Cubemap.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minogump/360ImageTransform/b9fd35057e5c6e3df4eea075d2d0ea4b0358214b/out/production/Transform/com/creative/transform/Cubemap.class -------------------------------------------------------------------------------- /out/production/Transform/com/creative/transform/Equirectangular.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minogump/360ImageTransform/b9fd35057e5c6e3df4eea075d2d0ea4b0358214b/out/production/Transform/com/creative/transform/Equirectangular.class -------------------------------------------------------------------------------- /out/production/Transform/com/creative/transform/Fisheye.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minogump/360ImageTransform/b9fd35057e5c6e3df4eea075d2d0ea4b0358214b/out/production/Transform/com/creative/transform/Fisheye.class -------------------------------------------------------------------------------- /out/production/Transform/com/creative/transform/Main.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minogump/360ImageTransform/b9fd35057e5c6e3df4eea075d2d0ea4b0358214b/out/production/Transform/com/creative/transform/Main.class -------------------------------------------------------------------------------- /out/production/Transform/mp4/cubemap.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minogump/360ImageTransform/b9fd35057e5c6e3df4eea075d2d0ea4b0358214b/out/production/Transform/mp4/cubemap.mp4 -------------------------------------------------------------------------------- /out/production/Transform/mp4/equirectangular.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minogump/360ImageTransform/b9fd35057e5c6e3df4eea075d2d0ea4b0358214b/out/production/Transform/mp4/equirectangular.mp4 -------------------------------------------------------------------------------- /out/production/Transform/mp4/fisheye.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minogump/360ImageTransform/b9fd35057e5c6e3df4eea075d2d0ea4b0358214b/out/production/Transform/mp4/fisheye.mp4 -------------------------------------------------------------------------------- /out/production/Transform/output/cb2fe.avi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minogump/360ImageTransform/b9fd35057e5c6e3df4eea075d2d0ea4b0358214b/out/production/Transform/output/cb2fe.avi -------------------------------------------------------------------------------- /out/production/Transform/output/eq2cm.avi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minogump/360ImageTransform/b9fd35057e5c6e3df4eea075d2d0ea4b0358214b/out/production/Transform/output/eq2cm.avi -------------------------------------------------------------------------------- /out/production/Transform/output/fe2eq.avi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minogump/360ImageTransform/b9fd35057e5c6e3df4eea075d2d0ea4b0358214b/out/production/Transform/output/fe2eq.avi -------------------------------------------------------------------------------- /out/production/Transform/output/temp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minogump/360ImageTransform/b9fd35057e5c6e3df4eea075d2d0ea4b0358214b/out/production/Transform/output/temp.png -------------------------------------------------------------------------------- /resources/mp4/cubemap.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minogump/360ImageTransform/b9fd35057e5c6e3df4eea075d2d0ea4b0358214b/resources/mp4/cubemap.mp4 -------------------------------------------------------------------------------- /resources/mp4/equirectangular.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minogump/360ImageTransform/b9fd35057e5c6e3df4eea075d2d0ea4b0358214b/resources/mp4/equirectangular.mp4 -------------------------------------------------------------------------------- /resources/mp4/fisheye.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minogump/360ImageTransform/b9fd35057e5c6e3df4eea075d2d0ea4b0358214b/resources/mp4/fisheye.mp4 -------------------------------------------------------------------------------- /resources/output/cb2fe.avi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minogump/360ImageTransform/b9fd35057e5c6e3df4eea075d2d0ea4b0358214b/resources/output/cb2fe.avi -------------------------------------------------------------------------------- /resources/output/eq2cm.avi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minogump/360ImageTransform/b9fd35057e5c6e3df4eea075d2d0ea4b0358214b/resources/output/eq2cm.avi -------------------------------------------------------------------------------- /resources/output/fe2eq.avi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/minogump/360ImageTransform/b9fd35057e5c6e3df4eea075d2d0ea4b0358214b/resources/output/fe2eq.avi -------------------------------------------------------------------------------- /src/com/creative/transform/Cubemap.java: -------------------------------------------------------------------------------- 1 | package com.creative.transform; 2 | 3 | 4 | import com.sun.javafx.geom.Vec2d; 5 | import org.opencv.core.CvType; 6 | import org.opencv.core.Mat; 7 | import org.opencv.core.Size; 8 | import org.opencv.imgcodecs.Imgcodecs; 9 | import org.opencv.videoio.VideoCapture; 10 | import org.opencv.videoio.VideoWriter; 11 | import org.opencv.videoio.Videoio; 12 | 13 | /** 14 | * Created by mino on 16-6-6. 15 | */ 16 | public class Cubemap { 17 | private String filename; 18 | private int width; 19 | private int height; 20 | private VideoCapture cap; 21 | 22 | /** 23 | * 24 | * @param filename the file's path 25 | */ 26 | Cubemap(String filename) { 27 | this.filename = filename; 28 | cap = new VideoCapture(filename); 29 | width = (int)(cap.get(Videoio.CV_CAP_PROP_FRAME_WIDTH)); 30 | height = (int)(cap.get(Videoio.CV_CAP_PROP_FRAME_HEIGHT)); 31 | } 32 | 33 | /** 34 | * 35 | * @return the file's path 36 | */ 37 | public String getFilename() { 38 | return filename; 39 | } 40 | 41 | /** 42 | * 43 | * @return the frame's height of the video 44 | */ 45 | public int getHeight() { 46 | return height; 47 | } 48 | 49 | /** 50 | * 51 | * @return the frame's width of the video 52 | */ 53 | public int getWidth() { 54 | return width; 55 | } 56 | 57 | /** 58 | * 59 | * @param filename set the file's path 60 | */ 61 | public void setFilename(String filename) { 62 | this.filename = filename; 63 | cap = new VideoCapture(filename); 64 | width = (int)(cap.get(Videoio.CV_CAP_PROP_FRAME_WIDTH)); 65 | height = (int)(cap.get(Videoio.CV_CAP_PROP_FRAME_HEIGHT)); 66 | } 67 | 68 | public void toFisheye(String savepath) { 69 | VideoWriter oVideoWriter = new VideoWriter(); 70 | oVideoWriter.open(savepath, VideoWriter.fourcc('D', 'I', 'V', 'X'), 24, new Size(this.width * 2 / 3, this.height / 2)); 71 | int count = 0; 72 | Mat frame = new Mat(); 73 | if (cap.isOpened()) { 74 | System.out.println("Input capture is opened"); 75 | } 76 | if (oVideoWriter.isOpened()) { 77 | System.out.println("Output writer is opened"); 78 | } 79 | while (true) { 80 | if (cap.read(frame)) { 81 | count++; 82 | Mat outputMat = Mat.zeros(this.height / 2, this.width * 2 / 3, frame.type()); 83 | cubeToFish(frame, outputMat); 84 | System.out.print(count + "\r"); 85 | oVideoWriter.write(outputMat); 86 | } else { 87 | break; 88 | } 89 | } 90 | oVideoWriter.release(); 91 | } 92 | 93 | /** 94 | * Convert the cubemap image to fisheye image. 95 | * @param inMat the input frame's matrix 96 | * @param outMat the output frame's matrix 97 | */ 98 | private void cubeToFish(Mat inMat, Mat outMat) { 99 | int outSizeY = outMat.rows(), outSizeX = outMat.cols(); 100 | int radius = width / 6; // 256 101 | int edge = width / 3; // 512 102 | for (int i = 0; i < outSizeX; i++) { 103 | for (int j = 0; j < outSizeY; j++) { 104 | double originX, originY, originZ; 105 | if (i < radius * 2 && j < height / 2) { // back face 106 | if (Math.hypot(radius - i, radius - j) <= radius) { 107 | double fishY = radius - j, fishZ = radius - i; 108 | double r = Math.hypot(fishY, fishZ); 109 | double theta = Math.asin(r / radius); 110 | double ballX = -radius * Math.cos(theta), ballY = fishY, ballZ = fishZ; 111 | if (Math.abs(ballX) >= Math.abs(ballY) && Math.abs(ballX) >= Math.abs(ballZ)) { 112 | originX = -radius; 113 | originZ = ballZ * (originX / ballX); 114 | originY = ballY * (originX / ballX); 115 | Vec2d v2d = getXY((int) originX, (int) originY, (int) originZ); 116 | outMat.put(j, i, inMat.get((int) (v2d.y), (int) (v2d.x))); 117 | } else if (Math.abs(ballY) >= Math.abs(ballX) && Math.abs(ballY) >= Math.abs(ballZ)) { 118 | originY = (ballY / Math.abs(ballY)) * radius; 119 | originZ = ballZ * (originY / ballY); 120 | originX = ballX * (originY / ballY); 121 | Vec2d v2d = getXY((int) originX, (int) originY, (int) originZ); 122 | outMat.put(j, i, inMat.get((int) (v2d.y), (int) (v2d.x))); 123 | } else if (Math.abs(ballZ) >= Math.abs(ballX) && Math.abs(ballZ) >= Math.abs(ballY)) { 124 | originZ = (ballZ / Math.abs(ballZ)) * radius; 125 | originY = ballY * (originZ / ballZ); 126 | originX = ballX * (originZ / ballZ); 127 | Vec2d v2d = getXY((int) originX, (int) originY, (int) originZ); 128 | outMat.put(j, i, inMat.get((int) (v2d.y), (int) (v2d.x))); 129 | } 130 | } 131 | } else if (i >= radius * 2 && i < radius * 4 && j < height / 2) { 132 | double fishY = radius - j, fishZ = (i - radius * 2) - radius; 133 | double r = Math.hypot(fishY, fishZ); 134 | double theta = Math.asin(r / radius); 135 | double ballX = radius * Math.cos(theta), ballY = fishY, ballZ = fishZ; 136 | if (Math.abs(ballX) >= Math.abs(ballY) && Math.abs(ballX) >= Math.abs(ballZ)) { 137 | originX = radius; 138 | originZ = ballZ * (originX / ballX); 139 | originY = ballY * (originX / ballX); 140 | Vec2d v2d = getXY((int) originX, (int) originY, (int) originZ); 141 | outMat.put(j, i, inMat.get((int) (v2d.y), (int) (v2d.x))); 142 | } else if (Math.abs(ballY) >= Math.abs(ballX) && Math.abs(ballY) >= Math.abs(ballZ)) { 143 | originY = (ballY / Math.abs(ballY)) * radius; 144 | originZ = ballZ * (originY / ballY); 145 | originX = ballX * (originY / ballY); 146 | Vec2d v2d = getXY((int) originX, (int) originY, (int) originZ); 147 | outMat.put(j, i, inMat.get((int) (v2d.y), (int) (v2d.x))); 148 | } else if (Math.abs(ballZ) >= Math.abs(ballX) && Math.abs(ballZ) >= Math.abs(ballY)) { 149 | originZ = (ballZ / Math.abs(ballZ)) * radius; 150 | originY = ballY * (originZ / ballZ); 151 | originX = ballX * (originZ / ballZ); 152 | Vec2d v2d = getXY((int) originX, (int) originY, (int) originZ); 153 | outMat.put(j, i, inMat.get((int) (v2d.y), (int) (v2d.x))); 154 | } 155 | } 156 | } 157 | } 158 | } 159 | 160 | /** 161 | * For each pair of X, Y and Z, return the X, Y coordinate of the input image. 162 | * @param X X coordinate in 3D world 163 | * @param Y Y coordinate in 3D world 164 | * @param Z Z coordinate in 3D world 165 | * @return the X, Y pair in input image 166 | */ 167 | private Vec2d getXY(int X, int Y, int Z) { 168 | int edge = width / 3; 169 | int halfEdge = edge / 2; 170 | Vec2d v2d = new Vec2d(); 171 | if (X == halfEdge) { 172 | v2d.x = edge + halfEdge - Y; 173 | v2d.y = edge + halfEdge - Z; 174 | } else if (X == -halfEdge) { 175 | v2d.x = 2 * edge + halfEdge + Y; 176 | v2d.y = edge + halfEdge - Z; 177 | } else if (Y == halfEdge) { 178 | v2d.x = edge + halfEdge + X; 179 | v2d.y = halfEdge - Z; 180 | } else if (Y == -halfEdge) { 181 | v2d.x = halfEdge - X; 182 | v2d.y = halfEdge - Z; 183 | } else if (Z == halfEdge) { 184 | v2d.x = 2 * edge + halfEdge + Y; 185 | v2d.y = halfEdge + X; 186 | } else if (Z == -halfEdge) { 187 | v2d.x = halfEdge - Y; 188 | v2d.y = edge + halfEdge - X; 189 | } 190 | if (v2d.x >= width) v2d.x = width - 1; 191 | if (v2d.x < 0) v2d.x = 0; 192 | if (v2d.y < 0) v2d.y = 0; 193 | if (v2d.y >= height) v2d.y = height - 1; 194 | return v2d; 195 | } 196 | 197 | } 198 | -------------------------------------------------------------------------------- /src/com/creative/transform/Equirectangular.java: -------------------------------------------------------------------------------- 1 | package com.creative.transform; 2 | 3 | import com.sun.javafx.geom.Vec2d; 4 | import com.sun.javafx.geom.Vec3d; 5 | import org.opencv.core.Mat; 6 | import org.opencv.core.MatOfByte; 7 | import org.opencv.core.Size; 8 | import org.opencv.videoio.VideoCapture; 9 | import org.opencv.videoio.VideoWriter; 10 | import org.opencv.videoio.Videoio; 11 | import org.opencv.core.CvType; 12 | import org.opencv.imgcodecs.Imgcodecs; 13 | 14 | import javax.imageio.ImageIO; 15 | import java.awt.*; 16 | import java.awt.image.BufferedImage; 17 | import java.awt.image.DataBufferByte; 18 | import java.io.ByteArrayInputStream; 19 | import java.io.IOException; 20 | 21 | 22 | /** 23 | * Created by mino on 16-6-6. 24 | */ 25 | public class Equirectangular { 26 | private String filename; 27 | private int width; 28 | private int height; 29 | private VideoCapture cap; 30 | 31 | /** 32 | * 33 | * @param filename the file's path 34 | */ 35 | Equirectangular(String filename) { 36 | this.filename = filename; 37 | this.cap = new VideoCapture(filename); 38 | width = (int)(cap.get(Videoio.CV_CAP_PROP_FRAME_WIDTH)); 39 | height = (int)(cap.get(Videoio.CV_CAP_PROP_FRAME_HEIGHT)); 40 | } 41 | 42 | /** 43 | * 44 | * @return the file's path 45 | */ 46 | public String getFilename() { 47 | return filename; 48 | } 49 | 50 | /** 51 | * 52 | * @return the frame's height of the video 53 | */ 54 | public int getHeight() { 55 | return height; 56 | } 57 | 58 | /** 59 | * 60 | * @return the frame's width of the video 61 | */ 62 | public int getWidth() { 63 | return width; 64 | } 65 | 66 | /** 67 | * 68 | * @param filename set the file's path 69 | */ 70 | public void setFilename(String filename) { 71 | this.filename = filename; 72 | cap = new VideoCapture(filename); 73 | width = (int)(cap.get(Videoio.CV_CAP_PROP_FRAME_WIDTH)); 74 | height = (int)(cap.get(Videoio.CV_CAP_PROP_FRAME_HEIGHT)); 75 | } 76 | 77 | 78 | 79 | /** 80 | * 81 | * @param savepath the path to save the video 82 | */ 83 | public void toCubemap(String savepath) { 84 | VideoWriter oVideoWriter = new VideoWriter(); 85 | oVideoWriter.open(savepath, VideoWriter.fourcc('D', 'I', 'V', 'X'), 20, new Size(width * 3 / 4, height)); 86 | int count = 0; 87 | Mat frame = new Mat(); 88 | if (cap.isOpened()) { 89 | System.out.println("Input capture is opened"); 90 | } 91 | if (oVideoWriter.isOpened()) { 92 | System.out.println("Output writer is opened"); 93 | } 94 | while (true) { 95 | if (cap.read(frame)) { 96 | count++; 97 | Mat out = new Mat(height, width * 3 / 4, frame.type()); 98 | convertBack(frame, out); 99 | System.out.print(count + "\r"); 100 | oVideoWriter.write(out); 101 | } else { 102 | break; 103 | } 104 | } 105 | oVideoWriter.release(); 106 | } 107 | 108 | /** 109 | * 110 | * @param i the output pixel's width index 111 | * @param j the output pixel's height index 112 | * @param face cubemap's face, from 0 to 5 113 | * @param edge the face's field of view, the length of the 114 | * @return the corresponding xyz ordinance of the output ordinance 115 | */ 116 | private Vec3d outImgToXYZ(int i, int j, int face, int edge) { 117 | double a = 2.0 * (double)i / (double)edge; 118 | double b = 2.0 * (double)j / (double)edge; 119 | Vec3d v = new Vec3d(); 120 | if (face == 0) { // right 121 | v.set(1.0 - a, 1.0, 1.0 - b); 122 | } else if (face == 1) { // left 123 | v.set(a - 3.0, -1.0, 1.0 - b); 124 | } else if (face == 2) { // top 125 | v.set(b - 1.0, a - 5.0, 1.0); 126 | } else if (face == 3) { // bottom 127 | v.set(3.0 - b, a - 1.0, -1.0); 128 | } else if (face == 4) { // front 129 | v.set(1.0, a - 3.0, 3.0 - b); 130 | } else if (face == 5) { // back 131 | v.set(-1.0, 5.0 - a, 3.0 - b); 132 | } 133 | return v; 134 | } 135 | 136 | private void convertBack(Mat imgIn, Mat imgOut) { 137 | int inSizeY = imgIn.rows(), inSizeX = imgIn.cols(); 138 | int outSizeY = imgOut.rows(), outSizeX = imgOut.cols(); 139 | int edge = inSizeX / 4; // 视角宽度 140 | for (int i = 0; i < outSizeX; i++) { 141 | int face = (i/edge); // 0 - right, 1 - left, 2 - top 142 | int face2; 143 | for (int j = 0; j < outSizeY; j++) { 144 | if (j >= edge) { 145 | if (face == 0) face2 = 3; // 3 - bottom 146 | else if (face == 1) face2 = 4; // 4 - front 147 | else face2 = 5; // 5 - back 148 | } else { 149 | face2 = face; 150 | } 151 | Vec3d v = outImgToXYZ(i, j, face2, edge); 152 | double theta = Math.atan2(v.y, v.x); // 水平方向夹角 153 | double r = Math.hypot(v.x, v.y); // 半径 154 | double phi = Math.atan2(v.z, r); // 垂直方向夹角 155 | // 对应原图像的坐标值 156 | double uf = ( 2.0 * edge * ( theta + Math.PI ) / Math.PI ); 157 | double vf = ( 2.0 * edge * (Math.PI / 2 - phi ) / Math.PI); 158 | // 非双线性插值法求像素值 159 | if ((int)vf < 0) vf = 0; 160 | else if ((int)vf >= inSizeY) vf = inSizeY - 1; 161 | imgOut.put(j, i, imgIn.get((int)vf, ((int)uf) % inSizeX)); 162 | } 163 | } 164 | } 165 | 166 | } 167 | -------------------------------------------------------------------------------- /src/com/creative/transform/Fisheye.java: -------------------------------------------------------------------------------- 1 | package com.creative.transform; 2 | 3 | import org.opencv.core.Mat; 4 | import org.opencv.core.Size; 5 | import org.opencv.imgcodecs.Imgcodecs; 6 | import org.opencv.videoio.VideoCapture; 7 | import org.opencv.videoio.VideoWriter; 8 | import org.opencv.videoio.Videoio; 9 | 10 | 11 | /** 12 | * Created by mino on 16-6-6. 13 | */ 14 | public class Fisheye { 15 | private String filename; 16 | private int width; 17 | private int height; 18 | private VideoCapture cap; 19 | private double FOV = Math.PI * (202.7 / 180.0); 20 | 21 | /** 22 | * 23 | * @param filename the file's path 24 | */ 25 | Fisheye(String filename) { 26 | this.filename = filename; 27 | cap = new VideoCapture(filename); 28 | width = (int)(cap.get(Videoio.CV_CAP_PROP_FRAME_WIDTH)); 29 | height = (int)(cap.get(Videoio.CV_CAP_PROP_FRAME_HEIGHT)); 30 | } 31 | 32 | /** 33 | * 34 | * @return the file's path 35 | */ 36 | public String getFilename() { 37 | return filename; 38 | } 39 | 40 | /** 41 | * 42 | * @return the frame's height of the video 43 | */ 44 | public int getHeight() { 45 | return height; 46 | } 47 | 48 | /** 49 | * 50 | * @return the frame's width of the video 51 | */ 52 | public int getWidth() { 53 | return width; 54 | } 55 | 56 | /** 57 | * 58 | * @param filename set the file's path 59 | */ 60 | public void setFilename(String filename) { 61 | this.filename = filename; 62 | cap = new VideoCapture(filename); 63 | width = (int)(cap.get(Videoio.CV_CAP_PROP_FRAME_WIDTH)); 64 | height = (int)(cap.get(Videoio.CV_CAP_PROP_FRAME_HEIGHT)); 65 | } 66 | 67 | public void toEquirectangular(String savepath) { 68 | VideoWriter oVideoWriter = new VideoWriter(); 69 | oVideoWriter.open(savepath, VideoWriter.fourcc('D', 'I', 'V', 'X'), 20, new Size(width, height)); 70 | int count = 0; 71 | Mat frame = new Mat(); 72 | if (cap.isOpened()) { 73 | System.out.println("Input capture is opened"); 74 | } 75 | if (oVideoWriter.isOpened()) { 76 | System.out.println("Output writer is opened"); 77 | } 78 | while (true) { 79 | if (cap.read(frame)) { 80 | count++; 81 | Mat out = new Mat(height, width, frame.type()); 82 | fishToEq(frame, out); 83 | System.out.print(count + "\r"); 84 | oVideoWriter.write(out); 85 | } else { 86 | break; 87 | } 88 | } 89 | oVideoWriter.release(); 90 | } 91 | 92 | private void fishToEq(Mat inMat, Mat outMat) { 93 | int length = width / 2; 94 | for (int i = 0; i < length; i++) { 95 | for (int j = 0; j < 2 * length; j++) { 96 | double theta = 2.0 * Math.PI * ((double)j / (2.0 * length) - 0.5); 97 | double phi = Math.PI * ((double)i / length - 0.5); 98 | double sphx = Math.cos(phi) * Math.sin(theta); 99 | double sphy = Math.cos(phi) * Math.cos(theta); 100 | double sphz = Math.sin(phi); 101 | theta = Math.atan2(sphz, sphx); 102 | phi = Math.atan2(Math.hypot(sphx, sphz) , sphy); 103 | double r = length * phi / FOV; 104 | int x = (int)(0.5 * length + r * Math.cos(theta)); 105 | int y = (int)(0.5 * length + r * Math.sin(theta)); 106 | if (x >= 0 && x < length && y >= 0 && y < length) { 107 | if (x >= 0 && x < 0.5 * length && j >= 0.5 * length && j < length) { 108 | outMat.put(i, j+length, inMat.get(length - 1 - x, y)); 109 | } else if (x >= length / 2 && x < length && j >= length && j < 1.5 * length) { 110 | outMat.put(i, j - length, inMat.get(length - 1 - x, y)); 111 | } 112 | if (j >= 0.5 * length && j < 1.5 * length) { 113 | outMat.put(i, j, inMat.get(x, width - 1 - y)); 114 | } 115 | } 116 | } 117 | } 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /src/com/creative/transform/Main.java: -------------------------------------------------------------------------------- 1 | package com.creative.transform; 2 | 3 | 4 | import org.opencv.core.Core; 5 | 6 | /** 7 | * Created by mino on 16-5-30. 8 | */ 9 | public class Main { 10 | 11 | private static final String equireactangular = "resources/mp4/equirectangular.mp4"; 12 | private static final String fisheye = "resources/mp4/fisheye.mp4"; 13 | private static final String cubemap = "resources/mp4/cubemap.mp4"; 14 | 15 | public static void main(String[] args) { 16 | System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 17 | Equirectangular eq1 = new Equirectangular(equireactangular); 18 | eq1.toCubemap("/home/mino/IdeaProjects/Transform/resources/output/eq2cm.avi"); 19 | 20 | Fisheye fe = new Fisheye(fisheye); 21 | fe.toEquirectangular("resources/output/fe2eq.avi"); 22 | 23 | Cubemap cb = new Cubemap(cubemap); 24 | cb.toFisheye("resources/output/cb2fe.avi"); 25 | } 26 | 27 | } 28 | --------------------------------------------------------------------------------