Last active
September 6, 2024 19:34
-
-
Save royshil/0b21e8e7c6c1f46a16db66c384742b2b to your computer and use it in GitHub Desktop.
Warp an image to cylindrical coordinates for cylindrical panorama stitching, using Python OpenCV
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
import cv2 | |
import numpy as np | |
def cylindricalWarp(img, K): | |
"""This function returns the cylindrical warp for a given image and intrinsics matrix K""" | |
h_,w_ = img.shape[:2] | |
# pixel coordinates | |
y_i, x_i = np.indices((h_,w_)) | |
X = np.stack([x_i,y_i,np.ones_like(x_i)],axis=-1).reshape(h_*w_,3) # to homog | |
Kinv = np.linalg.inv(K) | |
X = Kinv.dot(X.T).T # normalized coords | |
# calculate cylindrical coords (sin\theta, h, cos\theta) | |
A = np.stack([np.sin(X[:,0]),X[:,1],np.cos(X[:,0])],axis=-1).reshape(w_*h_,3) | |
B = K.dot(A.T).T # project back to image-pixels plane | |
# back from homog coords | |
B = B[:,:-1] / B[:,[-1]] | |
# make sure warp coords only within image bounds | |
B[(B[:,0] < 0) | (B[:,0] >= w_) | (B[:,1] < 0) | (B[:,1] >= h_)] = -1 | |
B = B.reshape(h_,w_,-1) | |
img_rgba = cv2.cvtColor(img,cv2.COLOR_BGR2BGRA) # for transparent borders... | |
# warp the image according to cylindrical coords | |
return cv2.remap(img_rgba, B[:,:,0].astype(np.float32), B[:,:,1].astype(np.float32), cv2.INTER_AREA, borderMode=cv2.BORDER_TRANSPARENT) | |
if __name__ == '__main__': | |
img = cv2.imread("image.png") | |
h, w = img.shape[:2] | |
K = np.array([[800,0,w/2],[0,800,h/2],[0,0,1]]) # mock intrinsics | |
img_cyl = cylindricalWarp(img, K) | |
cv2.imwrite("image_cyl.png", img_cyl) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Did not work. Only outputted the same image without the outer pixels. I used this image:
And got this: