def exr_saver(EXR_PATH, ndarr, ndim=3): '''Saves a numpy array as an EXR file with HALF precision (float16) Args: EXR_PATH (str): The path to which file will be saved ndarr (ndarray): A numpy array containing img data ndim (int): The num of dimensions in the saved exr image, either 3 or 1. If ndim = 3, ndarr should be of shape (height, width) or (3 x height x width), If ndim = 1, ndarr should be of shape (height, width) Returns: None ''' if ndim == 3: # Check params if len(ndarr.shape) == 2: # If a depth image of shape (height x width) is passed, convert into shape (3 x height x width) ndarr = np.stack((ndarr, ndarr, ndarr), axis=0) if ndarr.shape[0] != 3 or len(ndarr.shape) != 3: raise ValueError( 'The shape of the tensor should be (3 x height x width) for ndim = 3. Given shape is {}' .format(ndarr.shape)) # Convert each channel to strings Rs = ndarr[0, :, :].astype(np.float16).tostring() Gs = ndarr[1, :, :].astype(np.float16).tostring() Bs = ndarr[2, :, :].astype(np.float16).tostring() # Write the three color channels to the output file HEADER = OpenEXR.Header(ndarr.shape[2], ndarr.shape[1]) half_chan = Imath.Channel(Imath.PixelType(Imath.PixelType.HALF)) HEADER['channels'] = dict([(c, half_chan) for c in "RGB"]) out = OpenEXR.OutputFile(EXR_PATH, HEADER) out.writePixels({'R': Rs, 'G': Gs, 'B': Bs}) out.close() elif ndim == 1: # Check params if len(ndarr.shape) != 2: raise ValueError(( 'The shape of the tensor should be (height x width) for ndim = 1. ' + 'Given shape is {}'.format(ndarr.shape))) # Convert each channel to strings Rs = ndarr[:, :].astype(np.float16).tostring() # Write the color channel to the output file HEADER = OpenEXR.Header(ndarr.shape[1], ndarr.shape[0]) half_chan = Imath.Channel(Imath.PixelType(Imath.PixelType.HALF)) HEADER['channels'] = dict([(c, half_chan) for c in "R"]) out = OpenEXR.OutputFile(EXR_PATH, HEADER) out.writePixels({'R': Rs}) out.close()
def create_class_map_reflectance(output_file): band_start = const.get_value("NO_BAND_WIDTH_MODE_BAND_START") band_end = const.get_value("NO_BAND_WIDTH_MODE_BAND_END") resolution_width = 2 resolution_height = 2 band_num = 5 wavelengths = np.linspace(band_start, band_end, band_num + 1) radiance_map = np.zeros((resolution_height, resolution_width, band_num)) for i in range(0, resolution_height / 2): # upper for j in range(0, resolution_width): radiance_map[i, j, :] = [0.5, 0.4, 0.3,0.2,0.1] # for i in range(0, resolution_height / 2): # upper # for j in range(0, resolution_width / 2): # radiance_map[i, j, :] = [0.1, 0.15, 0.18,0.3,0.8] for i in range(resolution_height / 2, resolution_height): # down for j in range(0, resolution_width): radiance_map[i, j, :] = [0.2, 0.1, 0.05, 0.04,0.03] # for i in range(70, 90): # upper # for j in range(0, 10): # radiance_map[i, resolution_width - j - 1, :] = [0.5, 0.15, 0.18, 0.3, 0.8] # write this into exr file band_dict = dict() half_chan = Imath.Channel(Imath.PixelType(Imath.PixelType.FLOAT)) chaneldict = dict() for i in range(0, band_num): start = wavelengths[i] end = wavelengths[i + 1] band_name = "%.2f" % start + "-" + "%.2fnm" % end singleband = radiance_map[:, :, i] singleband = np.reshape(singleband, (resolution_width * resolution_height)) radiance_str = array.array('f', singleband).tostring() # generate arr band_dict[band_name] = radiance_str chaneldict[band_name] = half_chan header = OpenEXR.Header(resolution_width, resolution_height) header["channels"] = chaneldict if not isinstance(output_file, str): # writing to a temperal place, since OpenEXR do not support unicode tmpExrPath = os.path.join(os.path.expanduser('~'), "_tmp_sky.exr") out = OpenEXR.OutputFile(tmpExrPath, header) out.writePixels(band_dict) out = None # copy back shutil.move(tmpExrPath, output_file) else: out = OpenEXR.OutputFile(output_file, header) out.writePixels(band_dict) out = None
def write_exr(self, root, shape): x, y = shape header = openexr.Header(x, y) exr = root + '/foo.exr' output = openexr.OutputFile(exr, header) data = dict( R=np.ones((y, x, 1), dtype=np.float32).tobytes(), G=np.zeros((y, x, 1), dtype=np.float32).tobytes(), B=np.zeros((y, x, 1), dtype=np.float32).tobytes(), ) output = openexr.OutputFile(exr, header) output.writePixels(data) return exr
def saveEXR_grey_np(img, filename): img = img.astype(numpy.float32) # comment this out if we have problems d = len(img.shape) if d >= 3: w, h, _ = img.shape else: w, h = img.shape assert d == 3 or d == 4 or d == 2 # get the channels if d == 2: intensity = numpy.array(img[:, :]).data else: red = numpy.array(img[:, :, 0]) green = numpy.array(img[:, :, 1]) blue = numpy.array(img[:, :, 2]) itentensity_temp = (red + green + blue) / 3 intensity = itentensity_temp.data intensity = intensity.tobytes() # Write the three color channels to the output file out = OpenEXR.OutputFile(filename, OpenEXR.Header(h, w)) dict = {'R': intensity, 'G': intensity, 'B': intensity} out.writePixels(dict)
def test_compression(self): infile = OpenEXR.InputFile("GoldenGate.exr") h = infile.header() channels = h['channels'].keys() newchannels = dict(zip(channels, infile.channels(channels))) compressions = [ Imath.Compression.NO_COMPRESSION, Imath.Compression.RLE_COMPRESSION, Imath.Compression.ZIPS_COMPRESSION, Imath.Compression.ZIP_COMPRESSION, Imath.Compression.PIZ_COMPRESSION, Imath.Compression.PXR24_COMPRESSION ] if OpenEXR.OPENEXR_VERSION_HEX >= 0x02020000: compressions += [ Imath.Compression.B44_COMPRESSION, Imath.Compression.B44A_COMPRESSION, Imath.Compression.DWAA_COMPRESSION, Imath.Compression.DWAB_COMPRESSION ] for c in compressions: h['compression'] = Imath.Compression(c) out = OpenEXR.OutputFile("out.exr", h) out.writePixels(newchannels) out.close() actual = OpenEXR.InputFile("out.exr").header()['compression'] self.assertEqual(actual, Imath.Compression(c))
def test_one(self): oexr = OpenEXR.InputFile("GoldenGate.exr") #for k,v in sorted(oexr.header().items()): # print "%20s: %s" % (k, v) first_header = oexr.header() default_size = len(oexr.channel('R')) half_size = len( oexr.channel('R', Imath.PixelType(Imath.PixelType.HALF))) float_size = len( oexr.channel('R', Imath.PixelType(Imath.PixelType.FLOAT))) uint_size = len( oexr.channel('R', Imath.PixelType(Imath.PixelType.UINT))) self.assertTrue(default_size in [half_size, float_size, uint_size]) self.assertTrue(float_size == uint_size) self.assertTrue((float_size / 2) == half_size) self.assertTrue( len( oexr.channel( 'R', pixel_type=self.FLOAT, scanLine1=10, scanLine2=10)) == (4 * (first_header['dataWindow'].max.x + 1))) data = b" " * (4 * 100 * 100) h = OpenEXR.Header(100, 100) x = OpenEXR.OutputFile("out.exr", h) x.writePixels({'R': data, 'G': data, 'B': data}) x.close()
def test_put_img_together_exr_to_exr(self): self.bt.output_format = "EXR" self.bt.output_file += ".EXR" for chunks in [1, 5, 7, 11, 13, 31, 57]: res_y = 0 self.bt.collected_file_names = {} for i in range(1, chunks + 1): # Subtask numbers start from 1. y = randrange(1, 100) res_y += y file1 = self.temp_file_name('chunk{}.exr'.format(i)) exr = OpenEXR.OutputFile(file1, OpenEXR.Header(self.bt.res_x, y)) data = array.array('f', [1.0] * (self.bt.res_x * y)).tostring() exr.writePixels({ 'R': data, 'G': data, 'B': data, 'F': data, 'A': data }) exr.close() self.bt.collected_file_names[i] = file1 self.bt.res_y = res_y self.bt._put_image_together() self.assertTrue(path.isfile(self.bt.output_file)) img = load_img(self.bt.output_file) img_x, img_y = img.get_size() self.assertTrue(self.bt.res_x == img_x and res_y == img_y)
def blend_im_mask_to_exr(exr_filename, im_mask, clip_min=-1, clip_max=1): exrfile = exr.InputFile(exr_filename) #print(exrfile.header()) dw = exrfile.header()['dataWindow'] isize = (dw.max.y - dw.min.y + 1, dw.max.x - dw.min.x + 1) channels = ['R', 'G', 'B'] channelData = dict() for c in channels: C = exrfile.channel(c, Imath.PixelType(Imath.PixelType.FLOAT)) C_arr = np.fromstring(C, dtype=np.float32) #C_arr = np.reshape(C_arr, isize) C_arr = np.clip(C_arr, a_min=clip_min, a_max=clip_max) channelData[c] = array.array( 'f', C_arr.astype(np.float32).flatten().tostring()) # alpha channel with im_mask data channelData['A'] = array.array( 'f', im_mask.astype(np.float32).flatten().tostring()) os.remove(exr_filename) new_header = exr.Header(args.reso, args.reso) new_header['channel'] = { 'R': Imath.Channel(Imath.PixelType(exr.FLOAT)), 'G': Imath.Channel(Imath.PixelType(exr.FLOAT)), 'B': Imath.Channel(Imath.PixelType(exr.FLOAT)), 'A': Imath.Channel(Imath.PixelType(exr.FLOAT)) } exr_out = exr.OutputFile(exr_filename.replace('0001', ''), new_header) exr_out.writePixels(channelData) return
def save_exr(filename, pixels, dtype=np.float32): pt = None if dtype == np.float32: pt = Imath.PixelType(Imath.PixelType.FLOAT) elif dtype == np.float16: pt = Imath.PixelType(Imath.PixelType.HALF) elif dtype == np.uint: pt = Imath.PixelType(Imath.PixelType.UINT) else: print("Error - unknown dtype passed to load_exr") return None if pixels.dtype != dtype: pixels = pixels.astype(dtype) header = OpenEXR.Header(pixels.shape[1], pixels.shape[0]) header['channels'] = { 'R': Imath.Channel(pt), 'G': Imath.Channel(pt), 'B': Imath.Channel(pt) } outputFile = OpenEXR.OutputFile(filename, header) outputFile.writePixels({ 'R': pixels[:, :, 0].tostring(), 'G': pixels[:, :, 1].tostring(), 'B': pixels[:, :, 2].tostring() }) outputFile.close()
def apply_mask_to_exr(exr_path, mask_image, mask_value, output_path): load_file = OpenEXR.InputFile(exr_path) header = load_file.header() downscale = header['AliceVision:downscale'] dw = header['dataWindow'] size = (dw.max.x - dw.min.x + 1, dw.max.y - dw.min.y + 1) channel_type = header['channels']['Y'].type buf = load_file.channel('Y', channel_type) np_type = np.float32 if channel_type == Imath.PixelType( Imath.PixelType.FLOAT) else np.float16 arr = np.frombuffer(buf, dtype=np_type).copy() arr.shape = (size[1], size[0]) load_file.close() # load mask mask = cv2.resize(mask_image, None, fx=1 / downscale, fy=1 / downscale) mask = mask[:, :, 0] arr[mask == 255] = mask_value # save out_file = OpenEXR.OutputFile(output_path, header) out_file.writePixels({'Y': arr.tobytes()}) out_file.close()
def clearHeaders(inputfile): """ Clears metadata from the file texture """ if os.path.exists(inputfile): fileext=os.path.splitext(os.path.split(inputfile)[-1])[-1] attrStr='' if fileext.lower() in ['.tif', '.tiff', '.jpg', '.jpeg', '.dpx']: clear_cmd="oiio_iconvert --inplace --clear-keywords %s" % inputfile output, error=runCommand(clear_cmd) elif fileext.lower() in ['.exr']: fileIn=OpenEXR.InputFile(inputfile) header=fileIn.header() for k in header.keys(): if 'mrx:' in k: header.pop(k) oldChannels = header["channels"].keys() newChannels = dict(zip(oldChannels, fileIn.channels(oldChannels))) fileIn.close() fileOut = OpenEXR.OutputFile(inputfile, header) fileOut.writePixels(newChannels) fileOut.close()
def merge_exr(args): if len(args.image) < 3: print( 'Error: --merge requires at least two inputs and one output image.', file=sys.stderr) raise SystemExit(1) exr = _open_inputfile(args.image[0]) output_header = _create_output_header(exr.header()) exr.close() views = args.view or [] if len(views) > 1: print('Using views {}'.format(', '.join(views))) output_header['multiView'] = [x.encode('UTF-8') for x in views] elif len(views) == 1: print('Using view {}'.format(views[0])) output_header['view'] = views[0].encode('UTF-8') channel_data = {} for i, filename in enumerate(args.image[:-1]): print('{}/{} - Merging {}'.format(i + 1, len(args.image) - 1, filename)) _exr_to_multilayer(output_header, channel_data, filename) if 'multiView' in output_header: # The OpenEXR Python bindings returns bytes when multiView information from a header # is read and expects strings when writing output_header['multiView'] = [ x.decode('UTF-8') for x in output_header['multiView'] ] output = OpenEXR.OutputFile(args.image[-1], output_header) try: output.writePixels(channel_data) finally: output.close()
def exr2ctl2arr(im, im_rows, im_columns, ctl_transforms): #creating OpenEXR file pixels = im.astype(numpy.float16).tostring() HEADER = OpenEXR.Header(im_rows, im_columns) half_chan = Imath.Channel(Imath.PixelType(Imath.PixelType.HALF)) HEADER['channels'] = dict([(c, half_chan) for c in "RGB"]) exr = OpenEXR.OutputFile("exr_in.exr", HEADER) exr.writePixels({'R': pixels, 'G': pixels, 'B': pixels}) exr.close() # #calling CTL Render function call_ctl_min = colour.utilities.ctl_render("./exr_in.exr", "./exr_out.exr", ctl_transforms) #opening newly formed OpenEXR file with transformed applied im = OpenEXR.InputFile('exr_out.exr') (r,g,b) = im.channels("RGB") dw = im.header()['dataWindow'] size = (dw.max.x - dw.min.x + 1, dw.max.y - dw.min.y + 1) #reshaping and reformating image channels to put into new array red = numpy.reshape(numpy.fromstring(r, dtype=numpy.float16), (size[0], size[1])) green = numpy.reshape(numpy.fromstring(g, dtype=numpy.float16), (size[0], size[1])) blue = numpy.reshape(numpy.fromstring(b, dtype=numpy.float16), (size[0], size[1])) image = numpy.stack((blue, green, red), axis=-1) test = numpy.array(2**16) cv2.imwrite('cv1.tif', test) return image
def write_exr(data, path): ''' data를 exr파일로 저장 Args: path: 경로 + 파일 이름.exr data: 3차원 이미지 데이터 ''' assert data.ndim == 3, "exr 파일 write하려는데 차원 수가 다름" + str(data.shape) if not os.path.isdir(os.path.dirname(path)): os.makedirs(os.path.dirname(path)) h, w, c = data.shape if c == 3: channel_list = ['B', 'G', 'R'] else: channel_list = ['B'] header = OpenEXR.Header(w, h) header['compression'] = Imath.Compression( Imath.Compression.PIZ_COMPRESSION) # header['channels'] = {c: pixel_type#Imath.Channel(Imath.PixelType.FLOAT) # for c in channel_list} out = OpenEXR.OutputFile(path, header) ch_data = { ch: data[:, :, index].astype(np.float32).tostring() for index, ch in enumerate(channel_list) } out.writePixels(ch_data)
def createLandAlbedoMap(band_num, landAlbedoRasterFile, out_exr_file): band_start = const.get_value("NO_BAND_WIDTH_MODE_BAND_START") band_end = const.get_value("NO_BAND_WIDTH_MODE_BAND_END") wavelengths = np.linspace(band_start, band_end, band_num + 1) import gdal dataset = gdal.Open(landAlbedoRasterFile) imgXsize = dataset.RasterXSize imgYSize = dataset.RasterYSize band_dict = dict() half_chan = Imath.Channel(Imath.PixelType(Imath.PixelType.FLOAT)) chaneldict = dict() for i in range(0, band_num): start = wavelengths[i] end = wavelengths[i + 1] band_name = "%.2f" % start + "-" + "%.2fnm" % end band = dataset.GetRasterBand(i+1) singleband = band.ReadAsArray(0, 0, imgXsize, imgYSize) singleband = np.fliplr(singleband) singleband = np.reshape(singleband, (imgXsize * imgYSize)) radiance_str = array.array('f', singleband).tostring() # generate arr band_dict[band_name] = radiance_str chaneldict[band_name] = half_chan header = OpenEXR.Header(imgXsize, imgYSize) header["channels"] = chaneldict out = OpenEXR.OutputFile(out_exr_file, header) out.writePixels(band_dict)
def save_exr(img, filename): c, h, w = img.shape if c == 1: img = img.reshape(w * h) Gs = array.array('f', img).tostring() out = OpenEXR.OutputFile(filename, OpenEXR.Header(w, h)) out.writePixels({'G': Gs}) else: data = np.array(img).reshape(c, w * h) Rs = array.array('f', data[0, :]).tostring() Gs = array.array('f', data[1, :]).tostring() Bs = array.array('f', data[2, :]).tostring() out = OpenEXR.OutputFile(filename, OpenEXR.Header(w, h)) out.writePixels({'R': Rs, 'G': Gs, 'B': Bs})
def compose_one(self, layer): wave_data = {} for f in self.all_files: waves = [x for x in f.split('_')[1:4]] tmp_img = OpenEXR.InputFile(os.path.join(self.folder, f)) if self.img_shape is None: dw = tmp_img.header()['dataWindow'] self.img_shape = (dw.max.y - dw.min.y + 1, dw.max.x - dw.min.x + 1) for i, w in enumerate(waves): buffed = tmp_img.channel(layer['layers'][i], half_pixel) wave_data[w] = buffed header = OpenEXR.Header(self.img_shape[1], self.img_shape[0]) half_channel = Imath.Channel(half_pixel) header['compression'] = Imath.Compression( Imath.Compression.PIZ_COMPRESSION) header['channels'] = dict([(x, half_channel) for x in wave_data.keys()]) exr = OpenEXR.OutputFile( os.path.join(self.base_path, f"{self.filename}_{layer['name']}.exr"), header) exr.writePixels(wave_data) exr.close()
def save_rgb(image, filePath, comp=OexrCompression.ZIP): '''Saves the rgb (image) in OpenEXR format. Expects a 3-chan uint32 image.''' if len(image.shape) != 3: raise Exception("Incorrect dimensions!") h, w, c = image.shape # expects Numpy convention (row, col) -> (height, width) if c != 3: raise Exception("Incorrect number of channels!") if image.dtype != "uint32": raise Exception("Incorrect type!, expected uint32") try: header = oe.Header(w, h) header["channels"] = { "R": im.Channel(im.PixelType(oe.UINT)), "G": im.Channel(im.PixelType(oe.UINT)), "B": im.Channel(im.PixelType(oe.UINT)) } header['compression'] = im.Compression(comp) of = oe.OutputFile(filePath, header) r_data = image[:, :, 0].tostring() g_data = image[:, :, 1].tostring() b_data = image[:, :, 2].tostring() of.writePixels({"R": r_data, "G": g_data, "B": b_data}) of.close() except: raise
def arrays2exr(r, g, b, exrpath): rstr = r.astype(numpy.float32).tostring() gstr = g.astype(numpy.float32).tostring() bstr = b.astype(numpy.float32).tostring() exr = OpenEXR.OutputFile(exrpath, OpenEXR.Header(r.shape[1], r.shape[0])) exr.writePixels({'R': rstr, 'G': gstr, 'B': bstr}) exr.close()
def save_exr(fname, r=None, g=None, b=None, comments=''): r = np.array(r) assert r.ndim == 2 g = np.array(g) assert g.ndim == 2 assert g.shape == r.shape b = np.array(b) assert b.ndim == 2 assert b.shape == r.shape header = OpenEXR.Header(r.shape[1], r.shape[0]) header['channels'] = { 'R': Imath.Channel(PIXEL_TYPE), 'G': Imath.Channel(PIXEL_TYPE), 'B': Imath.Channel(PIXEL_TYPE), } header['comments'] = comments out = OpenEXR.OutputFile(fname, header) data = { 'R': r.astype(np.float32).tostring(), 'G': g.astype(np.float32).tostring(), 'B': b.astype(np.float32).tostring() } out.writePixels(data) out.close()
def save_depth(image, filePath, comp=OexrCompression.ZIP): ''' Saves the zBuffer (image) in OpenEXR format. Expects a 1-chann float32 image. ''' if len(image.shape) != 2: raise Exception("Incorrect dimensions!") if image.dtype != "float32": raise Exception("Incorrect type!, expected float32") try: h, w = image.shape header = oe.Header(w, h) header["channels"] = {"Z": im.Channel(im.PixelType(oe.FLOAT))} header['compression'] = im.Compression(comp) of = oe.OutputFile(filePath, header) image_data = image.tostring() of.writePixels({"Z": image_data}) of.close() except: raise
def write_image(filename, image, channels=None): """ Write the exr image to the specified filename. If no channels are given, write_image will guess """ if channels is None: if image.shape[2] == 1: channels = ("z") elif image.shape[2] == 3: channels = ("R", "G", "B") elif image.shape[2] == 4: channels = ("R", "G", "B", "A") else: assert False, "Unable to guess channel names" splitted = [ layer.flatten() for layer in np.split(image, image.shape[2], 2) ] channel_strings = [array.array('f', Chan).tostring() for Chan in splitted] ch_dict = {} for ch_name, ch_string in zip(channels, channel_strings): ch_dict[ch_name] = ch_string # Write the three color channels to the output file header = OpenEXR.Header(image.shape[1], image.shape[0]) if channels == ("R", "G", "B", "A"): header["channels"]["A"] = header["channels"]["R"] out = OpenEXR.OutputFile(filename, header) out.writePixels(ch_dict)
def test_put_img_together_exr(self): for chunks in [1, 5, 7, 11, 13, 31, 57, 100]: res_y = 0 self.bt.collected_file_names = {} for i in range(1, chunks + 1): # Subtask numbers start from 1. y = randrange(1, 100) res_y += y file1 = self.temp_file_name('chunk{}.exr'.format(i)) exr = OpenEXR.OutputFile(file1, OpenEXR.Header(self.bt.res_x, y)) data = array.array('f', [1.0] * (self.bt.res_x * y)).tostring() exr.writePixels({ 'R': data, 'G': data, 'B': data, 'F': data, 'A': data }) exr.close() self.bt.collected_file_names[i] = file1 self.bt.res_y = res_y self.bt._put_image_together() self.assertTrue(path.isfile(self.bt.output_file)) img = Image.open(self.bt.output_file) img_x, img_y = img.size img.close() self.assertTrue(self.bt.res_x == img_x and res_y == img_y) self.bt.restart() assert self.bt.preview_updater.chunks == {} assert self.bt.preview_updater.perfectly_placed_subtasks == 0 assert self.bt.preview_updater.perfect_match_area_y == 0
def imwrite(img, filename, normalize = False): directory = os.path.dirname(filename) if directory != '' and not os.path.exists(directory): os.makedirs(directory) img = img.data.numpy() if normalize: img_rng = np.max(img) - np.min(img) if img_rng > 0: img = (img - np.min(img)) / img_rng if filename[-4:] == '.exr': if len(img.shape) == 2: img = img.reshape((img.shape[0], img.shape[1], 1)) if img.shape[2] == 1: img = np.tile(img, (1, 1, 3)) img_r = img[:, :, 0] img_g = img[:, :, 1] img_b = img[:, :, 2] pixels_r = img_r.astype(np.float16).tostring() pixels_g = img_g.astype(np.float16).tostring() pixels_b = img_b.astype(np.float16).tostring() HEADER = OpenEXR.Header(img.shape[1], img.shape[0]) half_chan = Imath.Channel(Imath.PixelType(Imath.PixelType.HALF)) HEADER['channels'] = dict([(c, half_chan) for c in "RGB"]) exr = OpenEXR.OutputFile(filename, HEADER) exr.writePixels({'R': pixels_r, 'G': pixels_g, 'B': pixels_b}) exr.close() else: with warnings.catch_warnings(): warnings.simplefilter("ignore") skimage.io.imsave(filename, np.power(np.clip(img, 0.0, 1.0), 1.0 / 2.2))
def save_as_hdr(arr, filename, gamma=2.2, allow_negative=True): """Saves a float32 ndarray to a high dynamic range (OpenEXR or float32 TIFF) file. Args: arr (ndarray): The input array. filename (str | Path): The output filename. gamma (Optional[float]): The encoding gamma of arr. allow_negative (Optional[bool]): Clip negative values to zero if false.""" arr = arr.astype(np.float32)/255 if not allow_negative: arr[arr < 0] = 0 if gamma != 1: arr = np.sign(arr)*np.abs(arr)**gamma filename = str(filename) extension = filename.rpartition('.')[2].lower() if extension == 'exr': import OpenEXR exr = OpenEXR.OutputFile(filename, OpenEXR.Header(arr.shape[1], arr.shape[0])) exr.writePixels({'R': arr[..., 0].tobytes(), 'G': arr[..., 1].tobytes(), 'B': arr[..., 2].tobytes()}) exr.close() elif extension == 'tif' or extension == 'tiff': import tifffile tiff = tifffile.TiffWriter(filename) tiff.save(arr, photometric='rgb') tiff.close() else: raise Exception('Unknown HDR file format.')
def write_openexr_image(filename, image): """Save image in OpenEXR file format from numpy array.""" filename = check_file_ext(filename, ".exr") height = len(image) width = len(image[0]) channels = len(image[0][0]) # Default header only has RGB channels hdr = OpenEXR.Header(width, height) if channels == 4: data_r = image[:, :, 0].tobytes() data_g = image[:, :, 1].tobytes() data_b = image[:, :, 2].tobytes() data_a = image[:, :, 3].tobytes() image_data = {"R": data_r, "G": data_g, "B": data_b, "A": data_a} # Add alpha channel to header alpha_channel = {"A": Imath.Channel(Imath.PixelType(OpenEXR.FLOAT))} hdr["channels"].update(alpha_channel) elif channels == 3: data_r = image[:, :, 0].tobytes() data_g = image[:, :, 1].tobytes() data_b = image[:, :, 2].tobytes() image_data = {"R": data_r, "G": data_g, "B": data_b} else: raise RuntimeError("Invalid number of channels of starmap image.") file_handler = OpenEXR.OutputFile(str(filename), hdr) file_handler.writePixels(image_data) file_handler.close()
def test_code_loopback(self): """ Verify timeCode and keyCode field transit """ data = b" " * (4 * 100 * 100) h = OpenEXR.Header(100, 100) timecodes = [ Imath.TimeCode(1, 2, 3, 4, 0, 0, 0, 0, 0, 0), Imath.TimeCode(1, 2, 3, 4, 1, 0, 0, 0, 0, 0), Imath.TimeCode(1, 2, 3, 4, 0, 1, 0, 0, 0, 0), Imath.TimeCode(1, 2, 3, 4, 0, 0, 1, 0, 0, 0), Imath.TimeCode(1, 2, 3, 4, 0, 0, 0, 1, 0, 0), Imath.TimeCode(1, 2, 3, 4, 0, 0, 0, 0, 1, 0), Imath.TimeCode(1, 2, 3, 4, 0, 0, 0, 0, 0, 1), Imath.TimeCode(1, 2, 3, 4, 1, 1, 1, 1, 1, 1), ] keycode = Imath.KeyCode(1, 2, 3, 4, 5, 6, 60) for timecode in timecodes: h['keyCode'] = keycode h['timeCode'] = timecode x = OpenEXR.OutputFile("out2.exr", h) x.writePixels({'R': data, 'G': data, 'B': data}) x.close() h = OpenEXR.InputFile("out2.exr").header() self.assertEqual(h['keyCode'], keycode) self.assertEqual(h['timeCode'], timecode)
def xtest_multiView(self): h = OpenEXR.Header(640, 480) for views in [[], ['single'], ['left', 'right'], list("abcdefghijklmnopqrstuvwxyz")]: h['multiView'] = views x = OpenEXR.OutputFile("out0.exr", h) x.close() self.assertEqual(OpenEXR.InputFile('out0.exr').header()['multiView'], views)
def write_exr(filename, values, channel_names): """Writes the values in a multi-channel ndarray into an EXR file. Args: filename: The filename of the output file values: A numpy ndarray with shape [height, width, channels] channel_names: A list of strings with length = channels Raises: TypeError: If the numpy array has an unsupported type. ValueError: If the length of the array and the length of the channel names list do not match. """ if values.shape[-1] != len(channel_names): raise ValueError( 'Number of channels in values does not match channel names (%d, %d)' % (values.shape[-1], len(channel_names))) header = OpenEXR.Header(values.shape[1], values.shape[0]) try: exr_channel_type = Imath.PixelType(_np_to_exr[values.dtype.type]) except KeyError: raise TypeError('Unsupported numpy type: %s' % str(values.dtype)) header['channels'] = { n: Imath.Channel(exr_channel_type) for n in channel_names } channel_data = [values[..., i] for i in range(values.shape[-1])] exr = OpenEXR.OutputFile(filename, header) exr.writePixels( dict((n, d.tobytes()) for n, d in zip(channel_names, channel_data))) exr.close()
def test_header_bytes(self): ctype = Imath.Channel(Imath.PixelType(Imath.PixelType.HALF)) target = 'test_exr.exr' data = {} chans = {} channels = list('RGBA') for c in channels: chan = c.upper() data[chan] = b'X' * (10 * 5 * 2) chans[chan] = ctype header = OpenEXR.Header(10, 5) header['channels'] = chans header['foo1'] = b'bar' header['foo2'] = 'bar'.encode('ascii') header['foo3'] = 'bar'.encode('utf-8') file_ = OpenEXR.OutputFile(target, header) file_.writePixels(data) file_.close() # Read them back and confirm they are all b'bar' infile = OpenEXR.InputFile(target) h = infile.header() infile.close() self.assertEqual(h["foo1"], b'bar') self.assertEqual(h["foo2"], b'bar') self.assertEqual(h["foo3"], b'bar')