Python script to create sky image maps in rectangular format from such in equirectangular format, Blender setup to render equirectangular image maps.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. from __future__ import print_function
  2. import sys
  3. import os.path
  4. from PIL import Image
  5. from math import pi,sin,cos,tan,atan2,hypot,floor
  6. from numpy import clip
  7. # get x,y,z coords from out image pixels coords
  8. # i,j are pixel coords
  9. # face is face number
  10. # edge is edge length
  11. def outImgToXYZ(i,j,face,edge):
  12. a = 2.0*float(i)/edge
  13. b = 2.0*float(j)/edge
  14. if face==0: # back
  15. (x,y,z) = (-1.0, 1.0-a, 3.0 - b)
  16. elif face==1: # left
  17. (x,y,z) = (a-3.0, -1.0, 3.0 - b)
  18. elif face==2: # front
  19. (x,y,z) = (1.0, a - 5.0, 3.0 - b)
  20. elif face==3: # right
  21. (x,y,z) = (7.0-a, 1.0, 3.0 - b)
  22. elif face==4: # top
  23. (x,y,z) = (b-1.0, a -5.0, 1.0)
  24. elif face==5: # bottom
  25. (x,y,z) = (5.0-b, a-5.0, -1.0)
  26. return (x,y,z)
  27. # convert using an inverse transformation
  28. def convertBack(imgIn,imgOut):
  29. inSize = imgIn.size
  30. outSize = imgOut.size
  31. inPix = imgIn.load()
  32. outPix = imgOut.load()
  33. edge = inSize[0]/4 # the length of each edge in pixels
  34. for i in range(outSize[0]):
  35. face = int(i/edge) # 0 - back, 1 - left 2 - front, 3 - right
  36. if face==2:
  37. rng = range(0,int(edge*3))
  38. else:
  39. rng = range(int(edge), int(edge) * 2)
  40. for j in rng:
  41. if j<edge:
  42. face2 = 4 # top
  43. elif j>=2*edge:
  44. face2 = 5 # bottom
  45. else:
  46. face2 = face
  47. (x,y,z) = outImgToXYZ(i,j,face2,edge)
  48. theta = atan2(y,x) # range -pi to pi
  49. r = hypot(x,y)
  50. phi = atan2(z,r) # range -pi/2 to pi/2
  51. # source img coords
  52. uf = ( 2.0*edge*(theta + pi)/pi )
  53. vf = ( 2.0*edge * (pi/2 - phi)/pi)
  54. # Use bilinear interpolation between the four surrounding pixels
  55. ui = floor(uf) # coord of pixel to bottom left
  56. vi = floor(vf)
  57. u2 = ui+1 # coords of pixel to top right
  58. v2 = vi+1
  59. mu = uf-ui # fraction of way across pixel
  60. nu = vf-vi
  61. # Pixel values of four corners
  62. # import sys
  63. # print('inPix ->', inPix)
  64. # print('ui ->', ui)
  65. # print('inSize[0]', inSize[0])
  66. # bar = clip(vi,0,inSize[1]-1)
  67. # print('bar ->', bar, type(bar), int(bar))
  68. # baz = ui % inSize[0]
  69. # print('baz ->', baz, type(baz))
  70. # foo = inPix[ui % inSize[0], bar]
  71. # sys.exit(-1)
  72. A = inPix[ui % inSize[0],int(clip(vi,0,inSize[1]-1))]
  73. B = inPix[u2 % inSize[0],int(clip(vi,0,inSize[1]-1))]
  74. C = inPix[ui % inSize[0],int(clip(v2,0,inSize[1]-1))]
  75. D = inPix[u2 % inSize[0],int(clip(v2,0,inSize[1]-1))]
  76. # interpolate
  77. (r,g,b) = (
  78. A[0]*(1-mu)*(1-nu) + B[0]*(mu)*(1-nu) + C[0]*(1-mu)*nu+D[0]*mu*nu,
  79. A[1]*(1-mu)*(1-nu) + B[1]*(mu)*(1-nu) + C[1]*(1-mu)*nu+D[1]*mu*nu,
  80. A[2]*(1-mu)*(1-nu) + B[2]*(mu)*(1-nu) + C[2]*(1-mu)*nu+D[2]*mu*nu )
  81. outPix[i,j] = (int(round(r)),int(round(g)),int(round(b)))
  82. imgIn = Image.open(sys.argv[1])
  83. inSize = imgIn.size
  84. i1 = inSize[0]
  85. imgOut = Image.new("RGB",(inSize[0],int(inSize[0]*3/4)),"black")
  86. convertBack(imgIn,imgOut)
  87. imgOut.save(sys.argv[1].split('.')[0]+"_cubemap.png")
  88. file_extension = ".jpg"
  89. name_map = [ \
  90. ["", "", "py", ""],
  91. ["nz", "nx", "pz", "px"],
  92. ["", "", "ny", ""]]
  93. try:
  94. width, height = imgOut.size
  95. cube_size = width / 4
  96. filelist = []
  97. for row in range(3):
  98. for col in range(4):
  99. if name_map[row][col] != "":
  100. sx = cube_size * col
  101. sy = cube_size * row
  102. fn = name_map[row][col] + file_extension
  103. filelist.append(fn)
  104. imgOut.crop((sx, sy, sx + cube_size, sy + cube_size)).save(fn)
  105. except IOError:
  106. pass