Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Warp an image to cylindrical coordinates for cylindrical panorama stitching, using Python OpenCV
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)
@taut-and-yare

This comment has been minimized.

Copy link

commented Jan 25, 2019

line 18 throws an error, could you please fix / explain what's happening there?

@royshil

This comment has been minimized.

Copy link
Owner Author

commented Feb 6, 2019

line 18 throws an error, could you please fix / explain what's happening there?

Fixed. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.