Cogs.Core
build_pyramid.py
1import os
2os.environ["OPENCV_IO_ENABLE_OPENEXR"]="1"
3
4import math
5import numpy as np
6import cv2
7
8
9
10output_dir = "Q:\\Foo\\pyramid_1k";
11#output_dir = "Q:\\360\\4k\\pyramid";
12
13#assert base_size & (base_size-1) == 0, "Base size must be a power of two"
14
15if not os.path.exists(output_dir):
16 os.makedirs(output_dir)
17
18def handle_cube_face_level(conf, path, l, x, y, w, source_img):
19
20 cropped = source_img[y:y+w, x:x+w]
21 rescaled = cv2.resize(cropped, [conf.base_size]*2, cv2.INTER_NEAREST if conf.is_distance else cv2.INTER_LANCZOS4)
22
23
24 if conf.is_distance:
25 #output_path = os.path.join(output_dir, "{}{}.png".format(conf.prefix, path, ".png"))
26 #cv2.imwrite(output_path, np.round(65535 * rescaled[:,:]).astype('uint16'))
27 output_path = os.path.join(output_dir, "{}{}.u16".format(conf.prefix, path))
28 np.round(65535 * rescaled[:,:]).astype('uint16').tofile(output_path)
29
30
31 elif conf.is_color:
32 output_path = os.path.join(output_dir, "{}{}.png".format(conf.prefix, path, ".png"))
33
34 # convert from [0,1] linear to srgb
35 rescaled = np.power(rescaled, 1.0/2.4)
36
37 # convert to bytes
38 rescaled = np.clip(np.round(255 * rescaled), 0, 255).astype('uint8')
39 cv2.imwrite(output_path, rescaled)
40
41 if conf.is_color and w <= conf.base_size:
42 rescaled = cv2.rectangle(rescaled, (0,0), (conf.base_size - 1, conf.base_size - 1), (1, 0.5, 1))
43
44 print("Wrote {}".format(output_path))
45
46 if l + 1 == conf.tree_depth:
47 assert w == conf.base_size
48 return
49
50 l = l + 1;
51 w = w >> 1
52 for k in range(4):
53 xx = x + w*(k & 1)
54 yy = y + w*((k >> 1) & 1)
55 handle_cube_face_level(conf, path + str(k), l, xx, yy, w, source_img)
56
57def handle_cube_faces(conf, base_images):
58
59 base_image_size = conf.base_size << (conf.tree_depth-1)
60
61 assert(len(base_images) == 6)
62 for i in range(6):
63 source_img = cv2.imread(base_images[i], cv2.IMREAD_UNCHANGED);
64 print(base_images[i])
65
66 assert source_img.shape[0] == source_img.shape[1], "not square"
67
68 if source_img.shape[0] != base_image_size:
69 source_img = cv2.resize(source_img, [base_image_size]*2, cv2.INTER_NEAREST)
70
71 assert source_img.shape[0] == base_image_size, "base image has unexpected size"
72
73 # convert source image to [0,1] float
74 if source_img.dtype == 'float32':
75 pass
76 if source_img.dtype == 'uint8':
77 source_img = source_img.astype('float32')/255.0
78 elif source_img.dtype == 'uint16':
79 source_img = source_img.astype('float32')/65535.0
80 else:
81 assert False, "unsupported dtype"
82
83 if conf.is_distance:
84
85 assert len(source_img.shape) == 2, "Distance image is not single channel"
86
87 if conf.distance_from_depth:
88 # convert distnance along z to actual distance from eye
89 w = source_img.shape[0]
90 unit = (1.0/w)*(0.5+np.arange(w))
91 theta = np.pi * 0.5 * (unit - 0.5)
92 cos = np.cos(theta)
93 factor = 1.0/cos
94 factor2d = np.outer(factor, factor)
95 source_img = np.clip(factor2d * source_img, 0.0, 1.0)
96
97
98 if conf.is_color:
99 print(source_img.shape)
100 assert len(source_img.shape) == 3, "Color image has not three axises"
101
102 # convert from srgb to linear
103 source_img = np.power(source_img, 2.4)
104
105 handle_cube_face_level(conf, str(i), 0, 0, 0, base_image_size, source_img)
106
107
108if __name__ == "__main__":
109 from collections import namedtuple
110
111 Conf = namedtuple('Conf', ['base_size', 'tree_depth', 'prefix', 'is_color', 'is_distance', 'distance_from_depth'])
112
113
114 if True:
115 conf_color =Conf(base_size=256,
116 tree_depth=7,
117 is_color=True,
118 prefix='color',
119 is_distance=False,
120 distance_from_depth=False)
121
122 color_base_images = [
123 "Q:\\Foo\\16k\\color_east.png",
124 "Q:\\Foo\\16k\\color_west.png",
125 "Q:\\Foo\\16k\\color_down.png",
126 "Q:\\Foo\\16k\\color_up.png",
127 "Q:\\Foo\\16k\\color_north.png",
128 "Q:\\Foo\\16k\\color_south.png",
129 ]
130 handle_cube_faces(conf_color, color_base_images)
131
132 if True:
133 conf_depth = Conf(base_size=256,
134 tree_depth=7,
135 is_color=False,
136 prefix='depth',
137 is_distance=True,
138 distance_from_depth=True)
139 depth_base_images = [
140 "Q:\\Foo\\16k\\depth_east.png",
141 "Q:\\Foo\\16k\\depth_west.png",
142 "Q:\\Foo\\16k\\depth_down.png",
143 "Q:\\Foo\\16k\\depth_up.png",
144 "Q:\\Foo\\16k\\depth_north.png",
145 "Q:\\Foo\\16k\\depth_south.png",
146 ]
147 handle_cube_faces(conf_depth, depth_base_images)
148 print("Done")