Advertisement
Guest User

Faster Technique

a guest
Mar 16th, 2018
2,282
2
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.84 KB | None | 2 0
  1. import cv2
  2. import numpy
  3. import sys
  4.  
  5. from numpy import pi
  6. from PIL import Image
  7.  
  8. # Convert using an inverse transformation
  9. def generate_mapping_data(image_width):
  10.     in_size = [image_width, image_width * 3 / 4]
  11.     edge = in_size[0] / 4  # The length of each edge in pixels
  12.  
  13.     # Create our numpy arrays
  14.     out_pix = numpy.zeros((in_size[1], in_size[0], 2), dtype="f4")
  15.     xyz = numpy.zeros((in_size[1] * in_size[0] / 2, 3), dtype="f4")
  16.     vals = numpy.zeros((in_size[1] * in_size[0] / 2, 3), dtype="i4")
  17.  
  18.     # Much faster to use an arange when we assign to to vals
  19.     start, end = 0, 0
  20.     rng_1 = numpy.arange(0, edge * 3)
  21.     rng_2 = numpy.arange(edge, edge * 2)
  22.     for i in xrange(in_size[0]):
  23.         # 0: back
  24.         # 1: left
  25.         # 2: front
  26.         # 3: right
  27.         face = int(i / edge)
  28.         rng = rng_1 if face == 2 else rng_2
  29.  
  30.         end += len(rng)
  31.         vals[start:end, 0] = rng
  32.         vals[start:end, 1] = i
  33.         vals[start:end, 2] = face
  34.         start = end
  35.  
  36.     # Top/bottom are special conditions
  37.     j, i, face = vals.T
  38.     face[j < edge] = 4  # top
  39.     face[j >= 2 * edge] = 5  # bottom
  40.  
  41.     # Convert to image xyz
  42.     a = 2.0 * i / edge
  43.     b = 2.0 * j / edge
  44.     one_arr = numpy.ones(len(a))
  45.     for k in range(6):
  46.         face_idx = face == k
  47.  
  48.         # Using the face_idx version of each is 50% quicker
  49.         one_arr_idx = one_arr[face_idx]
  50.         a_idx = a[face_idx]
  51.         b_idx = b[face_idx]
  52.  
  53.         if k == 0:
  54.            vals_to_use =  [-one_arr_idx, 1.0 - a_idx, 3.0 - b_idx]
  55.         elif k == 1:
  56.            vals_to_use =  [a_idx - 3.0, -one_arr_idx, 3.0 - b_idx]
  57.         elif k == 2:
  58.            vals_to_use =  [one_arr_idx, a_idx - 5.0, 3.0 - b_idx]
  59.         elif k == 3:
  60.            vals_to_use =  [7.0 - a_idx, one_arr_idx, 3.0 - b_idx]
  61.         elif k == 4:
  62.            vals_to_use =  [b_idx - 1.0, a_idx - 5.0, one_arr_idx]
  63.         elif k == 5:
  64.            vals_to_use =  [5.0 - b_idx, a_idx - 5.0, -one_arr_idx]
  65.  
  66.         xyz[face_idx] = numpy.array(vals_to_use).T
  67.  
  68.     # Convert to theta and pi
  69.     x, y, z = xyz.T
  70.     theta = numpy.arctan2(y, x)
  71.     r = numpy.sqrt(x**2 + y**2)
  72.     phi = numpy.arctan2(z, r)
  73.  
  74.     # Source img coords
  75.     uf = (2.0 * edge * (theta + pi) / pi) % in_size[0]
  76.     uf[uf==in_size[0]] = 0.0 # Wrap to pixel 0 (much faster than modulus)
  77.     vf = (2.0 * edge * (pi / 2 - phi) / pi)
  78.  
  79.     # Mapping matrix
  80.     out_pix[j, i, 0] = vf
  81.     out_pix[j, i, 1] = uf
  82.  
  83.     map_x_32 = out_pix[:, :, 1]
  84.     map_y_32 = out_pix[:, :, 0]
  85.     return map_x_32, map_y_32
  86.  
  87. imgIn = Image.open(sys.argv[1])
  88. inSize = imgIn.size
  89.  
  90. map_x_32, map_y_32 = generate_mapping_data(inSize[0])
  91. cubemap = cv2.remap(numpy.array(imgIn), map_x_32, map_y_32, cv2.INTER_LINEAR)
  92.  
  93. imgOut = Image.fromarray(cubemap)
  94. imgOut.save(sys.argv[1].split('.')[0]+"_out.png")
  95. imgOut.show()
Advertisement
Comments
  • florentii
    148 days
    # text 0.16 KB | 0 0
    1. Great code!!! He helped us a lot in solving our problems. Tell me if there is an inverse solution, that is, converting a cubic map into an equidistant panorama?
Add Comment
Please, Sign In to add comment
Advertisement