Created
December 12, 2020 07:31
-
-
Save kozokomiya/701c2ca269d6afccdf7a4fd5f252fe05 to your computer and use it in GitHub Desktop.
Dual-fisheye to Equirectangular Converter using OpenCV remap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Dual-fisheye to Equirectangular Converter using OpenCV remap | |
import sys | |
import numpy as np | |
import cv2 | |
try: | |
# try to load map file | |
xmap = np.load("xmap.npy") | |
ymap = np.load("ymap.npy") | |
except IOError: | |
# if the map files are not exist, generate new map files. | |
print("Generating map miles...") | |
COLS = 1280 | |
ROWS = 720 | |
xmap = np.zeros((ROWS, COLS), np.float32) | |
ymap = np.zeros((ROWS, COLS), np.float32) | |
DST_X = float(COLS) | |
DST_Y = DST_X / 2 | |
SRC_CX1 = DST_X / 4 | |
SRC_CX2 = DST_X - SRC_CX1 | |
SRC_CY = DST_X / 4 | |
SRC_R = 0.884 * DST_X / 4 | |
SRC_RX = SRC_R * 1.00 | |
SRC_RY = SRC_R * 1.00 | |
# | |
for y in range(COLS // 2): | |
for x in range(COLS): | |
ph1 = np.pi * x / DST_Y | |
th1 = np.pi * y / DST_Y | |
x1 = np.sin(th1) * np.cos(ph1) | |
y1 = np.sin(th1) * np.sin(ph1) | |
z1 = np.cos(th1) | |
ph2 = np.arccos(-x1) | |
th2 = (1 if y1 >= 0 else -1) * np.arccos(-z1 / np.sqrt(y1 * y1 + z1 * z1)) | |
if ph2 < np.pi / 2: | |
r0 = ph2 / (np.pi / 2) | |
xmap[y,x] = SRC_RX * r0 * np.cos(th2) + SRC_CX1 | |
ymap[y,x] = SRC_RY * r0 * np.sin(th2) + SRC_CY | |
else: | |
r0 = (np.pi - ph2) / (np.pi / 2) | |
xmap[y,x] = SRC_RX * r0 * np.cos(np.pi - th2) + SRC_CX2 | |
ymap[y,x] = SRC_RY * r0 * np.sin(np.pi - th2) + SRC_CY | |
np.save("xmap.npy", xmap) | |
np.save("ymap.npy", ymap) | |
def convert_dualfisheye_to_equirectangular(frmae): | |
return cv2.remap(frame, xmap, ymap, cv2.INTER_LINEAR, cv2.BORDER_CONSTANT) | |
if __name__ == '__main__': | |
if len(sys.argv) < 3: | |
print('Usage: Python3 dualfisheye.py <inputfile> <outputfile>') | |
sys.exit(1) | |
cap = cv2.VideoCapture(sys.argv[1]) | |
if not cap.isOpened(): | |
print('file not opened') | |
sys.exit(1) | |
fps = cap.get(cv2.CAP_PROP_FPS) | |
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) | |
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) | |
fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v') | |
out = cv2.VideoWriter(sys.argv[2], fourcc, fps, (int(width), int(height))) | |
count = 0 | |
while(cap.isOpened()): | |
ret, frame = cap.read() | |
if ret == False: | |
break | |
frame = convert_dualfisheye_to_equirectangular(frame) | |
out.write(frame) | |
if count % 30 == 0: | |
print('.', end="") | |
sys.stdout.flush() | |
count += 1 | |
print() | |
cap.release() | |
cv2.destroyAllWindows() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment