def main(folder): """ Reads and process the images given by the read_and_store_data function and creates a new hdr file """ images, times = read_and_store_data(folder) """ Align the pictures using the brightest spots, it doesn't matter the exposures are different """ logging.debug("Aligning pictures") alignMTB = cv2.createAlignMTB() alignMTB.process(images, images) """ Finds the camera response function """ logging.debug("Calculating Camera response function") calibrate = cv2.createCalibrateDebevec() response = calibrate.process(images, times) """ Putting everything together into a single hdr image """ logging.debug("Merging images...") merge = cv2.createMergeDebevec() hdr = merge.process(images, times, response) """ Saving the hdr file into the specified folder """ hdr_folder = os.path.join(cwd, "HDR") logging.debug("Saving HDR at {}....".format(hdr_folder)) cv2.imwrite(hdr_folder + "/file2.hdr", hdr) logging.debug("Saved file")
def HDR(_imgs_nx1, _times_nx1, method=Debevec): assert _imgs_nx1.dtype == np.uint8 and _times_nx1.dtype == np.float32, "Type Error" assert len(_imgs_nx1) == len( _times_nx1) and len(_times_nx1) > 0, "Len Error" if method == Debevec: CalibrateDebevec = cv2.createCalibrateDebevec(samples=70, random=True) crf = CalibrateDebevec.process(src=_imgs_nx1, times=_times_nx1) merge_debvec = cv2.createMergeDebevec() hdr_img = merge_debvec.process(src=_imgs_nx1, times=_times_nx1, response=crf) tonemap = cv2.createTonemapDurand(gamma=1.4) res_img = tonemap.process(hdr_img.copy()) return crf, hdr_img, res_img if method == Robertson: CalibrateRobertson = cv2.createCalibrateRobertson() crf = CalibrateRobertson.process(src=_imgs_nx1, times=_times_nx1) merge_robertson = cv2.createMergeRobertson() hdr_img = merge_robertson.process(src=_imgs_nx1, times=_times_nx1, response=crf) #local tonermap tonemap = cv2.createTonemapDurand(gamma=1.4) res_img = tonemap.process(hdr_img.copy()) return crf, hdr_img, res_img if method == Mertens: merge_mertens = cv2.createMergeMertens() res_img = merge_mertens.process(_imgs_nx1) # cv2.imshow("ss", res_img) # cv2.waitKey(0) # cv2.destroyAllWindows() # res_mertens_8bit = np.clip(res_img*255, 0, 255).astype('uint8') # cv2.imwrite("PyFusion.png", res_mertens_8bit) return res_img
def obtain_camera_response_function(): """ reason of doing this :return: """ calibrateDebevec = cv2.createCalibrateDebevec() responseDebevec = calibrateDebevec.process(images, times)
def process_photos(folders): psave = folders["psave"] ptmp = folders["ptmp"] pgal = folders["pgal"] foldername = folders["foldername"] save_folder = psave + "/" + foldername makedirs(save_folder) onlyfiles = [f for f in listdir(ptmp) if isfile(join(ptmp, f))] images = [] times = np.array([], dtype=np.float32) logging.info("Loading images for HDR") for filename in onlyfiles: filesrc = ptmp + "/" + filename filedest = save_folder + "/" + filename shutil.move(filesrc, filedest) file_data = open(filedest, 'rb') tags = exifread.process_file(file_data) exposure = float(tags['EXIF ExposureTime'].values[0]) im = cv2.imread(filedest) images.append(im) times = np.append(times, np.float32(exposure)) logging.info("Align input images") align_MTB = cv2.createAlignMTB() align_MTB.process(images, images) logging.info('Obtain Camera Response Function (CRF)') calibrate_debevec = cv2.createCalibrateDebevec() response_debevec = calibrate_debevec.process(images, times) logging.info('Merge images into an HDR linear image') merge_debevec = cv2.createMergeDebevec() hdr_debevec = merge_debevec.process(images, times, response_debevec) logging.info('Save HDR image') save_file = pgal + "/" + foldername cv2.imwrite(save_file + ".hdr", hdr_debevec) logging.info("Tonemaping using Drago's method ... ") tonemap_drago = cv2.createTonemapDrago(1.0, 0.7) ldr_drago = tonemap_drago.process(hdr_debevec) ldr_drago = 3 * ldr_drago cv2.imwrite(save_file + "_drago.jpg", ldr_drago * 255) logging.info("Tonemaping using Reinhard's method ... ") tonemap_reinhard = cv2.createTonemapReinhard(1.5, 0,0,0) ldr_reinhard = tonemap_reinhard.process(hdr_debevec) cv2.imwrite(save_file + "_reinhard.jpg", ldr_reinhard * 255) logging.info("Tonemaping using Mantiuk's method ... ") tonemap_mantiuk = cv2.createTonemapMantiuk(2.2,0.85, 1.2) ldr_mantiuk = tonemap_mantiuk.process(hdr_debevec) ldr_mantiuk = 3 * ldr_mantiuk cv2.imwrite(save_file + "_mantiuk.jpg", ldr_mantiuk * 255)
def calc_scene_hdr_psnr(): scenes_obj = parse_json_file(args.scene_map_fp) scenes_psnr = {} for i, scene in enumerate(scenes_obj): scene_fd = os.path.dirname(scene['ldr_fps'][0]) scene_rend_fp = scene['rend_fp'] scene_cv_fp = os.path.join(scene_fd, '{}_cv-hdr.jpg'.format(scene['ldr_fd'])) # scene_ldr_fps = scene['ldr_fps'] scene_exptime_fp = get_scene_exptime_fp(scene_fd) print('Processing: ' + scene_fd) print(' scene_rend_fp (r): ' + scene_rend_fp) rend_hdr_img = cv2.imread(scene_rend_fp) # Render HDR image using OpenCV if args.force or not os.path.isfile(scene_cv_fp): print(' scene_cv_fp (w): ' + scene_cv_fp) ldr_imgs = [] ldr_exptimes = [] with open(scene_exptime_fp, 'r') as exptimes_file: for line in exptimes_file: vals = line.split(',') ldr_imgs.append( cv2.imread( os.path.join(scene_fd, vals[0].split('/')[-1]))) ldr_exptimes.append(float(vals[1])) ldr_exptimes = np.array(ldr_exptimes, dtype=np.float32) # Estimate Camera response function, merge exposures calib_debevec = cv2.createCalibrateDebevec() resp_debevec = calib_debevec.process(ldr_imgs, ldr_exptimes) merge_debevec = cv2.createMergeDebevec() hdr_debevec = merge_debevec.process(ldr_imgs, ldr_exptimes, resp_debevec) # Tone mapping tone_map = cv2.createTonemapReinhard(1.5, 0, 0, 0) cv_hdr_img = tone_map.process(hdr_debevec) cv2.imwrite(scene_cv_fp, cv_hdr_img * 255.0) else: print(' scene_cv_fp (r): ' + scene_cv_fp) cv_hdr_img = cv2.imread(scene_cv_fp) # Calculate PSNR cv_hdr_img = cv2.resize(cv_hdr_img, dsize=(rend_hdr_img.shape[1], rend_hdr_img.shape[0]), interpolation=cv2.INTER_CUBIC) scene_rend_fn = scene_rend_fp.split('/')[-1] scenes_psnr[scene_rend_fn] = img_psnr(cv_hdr_img, rend_hdr_img) return scenes_psnr
def merge2HDR(self, input_path, output_path, exp_times, verbosity): """ *************************************************************** Function to merge Debayered images into HDR images :param input_path: the debayered images path :param output_path: the output HDR path :param exp_times: the input exposure times in seconds :param verbosity: show individual file progress :return: <none> NOTE: Function uses Debevec's merging algorithm to merge exposures to HDR file. *************************************************************** """ # global starting number of the HDR frames hdrnum = 0 # list all files in the debayer folder filelist = [ filename for dirpath, dirnames, filenames in os.walk(input_path) for filename in filenames if filename.endswith('.jpg') ] # check whether directory exists else create a directory if not os.path.exists(output_path): os.makedirs(output_path) # process debayer images to HDR images for i in range(0, len(filelist), len(exp_times)): exposures = [] # read the exposures and append a list of exposures to be merged to HDR for j in range(i, i + 4): filename = os.path.join(input_path, filelist[j]) ldr_image = cv2.imread(filename, cv2.IMREAD_COLOR) ldr_image = cv2.cvtColor(ldr_image, cv2.COLOR_BGR2RGB) exposures.append(ldr_image) # align the exposure list alignMTB = cv2.createAlignMTB() alignMTB.process(exposures, exposures) # obtain camera response function calibrateDebevec = cv2.createCalibrateDebevec() responseDebevec = calibrateDebevec.process(exposures, exp_times) # create HDR from camera response mergeDebevec = cv2.createMergeDebevec() hdr = mergeDebevec.process(exposures, exp_times, responseDebevec) # set output file name and write exr (we use a separate exr because OpenCV EXR is not compressed) outfilename = os.path.join(output_path, '{0:05d}.exr'.format(hdrnum)) self.writeEXR(hdr, outfilename) if verbosity == 1: print('HDR file: {0} merged..'.format(outfilename)) hdrnum += 1 return
def process_debevec(images, exposures): calibrate_debevec = cv2.createCalibrateDebevec() response_debevec = calibrateDebevec.process(images, times=exposures) merge_debevec = cv2.createMergeDebevec() return merge_debevec.process( images, times=exposures, response=response_debevec )
def batch_hdr(image_dict, exposures, response=None): """ generate response and then run combine_hdr in batch. https://www.toptal.com/opencv/python-image-processing-in-computational-photography """ exposures = np.float32([e / 1000000 for e in exposures]) if response is None: calibration = cv.createCalibrateDebevec() response = calibration.process(image_dict[calibrate_img_idx], exposures) result = batch_process(combine_hdr, image_dict, exposures, response) return result
def doneByOpenCV(): print('doing HDR and TM by openCV') images, shutters, max_shift = readInfo() images = readImg(images) calibrateDebevec = cv2.createCalibrateDebevec() responseDebevec = calibrateDebevec.process(images, shutters) mergeDebevec = cv2.createMergeDebevec() hdrDebevec = mergeDebevec.process(images, shutters, responseDebevec) print('HDR max:%.2f, min:%.2f' % (hdrDebevec.max(), hdrDebevec.min())) cv2.imwrite('%s/hdr_%d_OpenCV.hdr' % (RESULT_DIR, IMG_NUM), hdrDebevec) tonemapDrago = cv2.createTonemapDrago(1, 0.8) # hand set params ldrDrago = tonemapDrago.process(hdrDebevec) ldrDrago = 255 * ldrDrago * 1.5 # hand set params print('LDR max:%.2f, min:%.2f' % (ldrDrago.max(), ldrDrago.min())) cv2.imwrite('%s/ldr_%d_OpenCV.jpg' % (RESULT_DIR, IMG_NUM), ldrDrago)
def run(): images, times = loadExposureSeq(settings.BASE_DIR) calibrate = cv.createCalibrateDebevec() response = calibrate.process(images, times) merge_debevec = cv.createMergeDebevec() hdr = merge_debevec.process(images, times, response) tonemap = cv.createTonemap(2.2) ldr = tonemap.process(hdr) merge_mertens = cv.createMergeMertens() fusion = merge_mertens.process(images) out_file_name = 'fusion' + date_time + '.png' OUT_FILE = os.path.join(settings.HDR_ROOT, out_file_name) cv.imwrite(OUT_FILE, fusion * 255)
def __init__(self, ip_pi): QThread.__init__(self) self.threadID = 1 self.name = "ImgThread" self.window = None self.saveOn = False self.mergeMertens = cv2.createMergeMertens( 0, 1, 1) #contrast saturation exposure # self.mergeMertens = cv2.createMergeMertens() # print("Contrast:",self.mergeMertens.getContrastWeight()) # print("Saturation:",self.mergeMertens.getSaturationWeight()) # print("Exposure:",self.mergeMertens.getExposureWeight()) self.mergeDebevec = cv2.createMergeDebevec() self.calibrateDebevec = cv2.createCalibrateDebevec() # self.toneMap = cv2.createTonemapReinhard(gamma=1.) self.toneMap = cv2.createTonemapDrago() # self.linearTonemap = cv2.createTonemap(1.) #Normalize with Gamma 1.2 # self.toneMap = cv2.createTonemapMantiuk() # self.claheProc = cv2.createCLAHE(clipLimit=1, tileGridSize=(8,8)) # self.simpleWB = cv2.xphoto.createSimpleWB() # self.simpleWB = cv2.xphoto.createGrayworldWB() # self.wb= False # self.equalize = False # self.clahe = False # self.clipLimit = 1. # self.alignMTB = cv2.createAlignMTB() self.invgamma = np.empty((1, 256), np.uint8) for i in range(256): self.invgamma[0, i] = np.clip(pow(i / 255.0, 0.45) * 255.0, 0, 255) self.gamma = np.empty((1, 256), np.uint8) for i in range(256): self.gamma[0, i] = np.clip(pow(i / 255.0, 2.2) * 255.0, 0, 255) self.reduceFactor = 1 self.ip_pi = ip_pi self.hflip = False self.vflip = False self.table = None self.doCalibrate = False try: npz = np.load("calibrate.npz") self.table = npz['table'] except Exception as e: pass
def test_calCRF(self): global images, times, resDebevec time_cv = times.copy() time_our = times.copy() print("Calculating Camera Response Function (CRF) ... ") calibrateDebevec = cv2.createCalibrateDebevec() tStart = time.time() resDebevec_cv = calibrateDebevec.process(images, time_cv) tEnd = time.time() tOril = tEnd - tStart resDebevec = resDebevec_cv tStart = time.time() resDebevec_our = _calCRF.process(images, time_our) tEnd = time.time() tOur = tEnd - tStart print("tOril:", tOril) print("tOur:", tOur) resDebevec_our_np = np.array(resDebevec_our, dtype=np.float32) resDebevec_our_np.resize((256, 1, 3)) #resDebevec = resDebevec_our self.assertEqual(np.allclose(resDebevec_our_np, resDebevec_cv), True)
def main(): #读取多张曝光的图像 images,times = readImagesAndTimes() #对齐图像 alignMTB = cv2.createAlignMTB() alignMTB.process(images, images) #恢复相机响应函数 calibrateDebevec = cv2.createCalibrateDebevec() responseDebevec = calibrateDebevec.process(images, times) # 将多张图像融合成hdr mergeDebevec = cv2.createMergeDebevec() hdrDebevec = mergeDebevec.process(images, times, responseDebevec) # 保存融合结果,可用ps打开 cv2.imwrite("hdrDebevec.hdr", hdrDebevec) # Tonemap using Drago's method to obtain 24-bit color image tonemapDrago = cv2.createTonemapDrago(1.0, 0.7) ldrDrago = tonemapDrago.process(hdrDebevec) ldrDrago = 3 * ldrDrago cv2.imwrite("ldr-Drago.jpg", ldrDrago * 255) # Tonemap using Durand's method obtain 24-bit color image tonemapDurand = cv2.createTonemapDurand(1.5,4,1.0,1,1) ldrDurand = tonemapDurand.process(hdrDebevec) ldrDurand = 3 * ldrDurand cv2.imwrite("ldr-Durand.jpg", ldrDurand * 255) # Tonemap using Reinhard's method to obtain 24-bit color image tonemapReinhard = cv2.createTonemapReinhard(1.5, 0,0,0) ldrReinhard = tonemapReinhard.process(hdrDebevec) cv2.imwrite("ldr-Reinhard.jpg", ldrReinhard * 255) # Tonemap using Mantiuk's method to obtain 24-bit color image tonemapMantiuk = cv2.createTonemapMantiuk(2.2,0.85, 1.2) ldrMantiuk = tonemapMantiuk.process(hdrDebevec) ldrMantiuk = 3 * ldrMantiuk cv2.imwrite("ldr-Mantiuk.jpg", ldrMantiuk * 255)
def main(): images, times = readImagesAndTimes() # Align input images alignMTB = cv2.createAlignMTB() alignMTB.process(images, images) # Obtain Camera Response Function (CRF) calibrateDebevec = cv2.createCalibrateDebevec() responseDebevec = calibrateDebevec.process(images, times) # Merge images into an HDR linear image mergeDebevec = cv2.createMergeDebevec() hdrDebevec = mergeDebevec.process(images, times, responseDebevec) # Save HDR image. cv2.imwrite("hdrDebevec.hdr", hdrDebevec) # Tonemap using Drago's method to obtain 24-bit color image tonemapDrago = cv2.createTonemapDrago(1.0, 0.7) ldrDrago = tonemapDrago.process(hdrDebevec) ldrDrago = 3 * ldrDrago cv2.imwrite("ldr-Drago.jpg", ldrDrago * 255)
def createHDR(self): """ Numpy array of exposure times from exif data """ for image in self.image_paths: p = Photo(image) self.exposure_times.append(p.exifData()) times_np = np.asarray(self.exposure_times, dtype=np.float32) # Align Images alignMTB = cv.createAlignMTB() alignMTB.process(self.im_list, self.im_list) # Find Camera Response Curve calibrateDebevec = cv.createCalibrateDebevec() responseDebevec = calibrateDebevec.process(self.im_list, times_np) # Merge Images mergeDebevec = cv.createMergeDebevec() hdrDebevec = mergeDebevec.process(self.im_list, times_np, responseDebevec) # Generate HDR image and LDR tone mapped preview cv.imwrite("hdr.hdr", hdrDebevec) toneMapReinhard = cv.createTonemapReinhard(1.5, 0.0) ldrReinhard = toneMapReinhard.process(hdrDebevec) cv.imwrite("hdr_preview.jpg", ldrReinhard * 255)
hdr_robertson = merge_robertson.process(img_list, times=exposure_times.copy()) # Tonemap HDR image tonemap1 = cv.createTonemap(gamma=2.2) res_debevec = tonemap1.process(hdr_debevec.copy()) tonemap2 = cv.createTonemap(gamma=1.3) res_robertson = tonemap2.process(hdr_robertson) # Exposure fusion using Mertens merge_mertens = cv.createMergeMertens() res_mertens = merge_mertens.process(img_list) # Convert datatype to 8-bit and save res_debevec_8bit = np.clip(res_debevec * 255, 0, 255).astype('uint8') res_robertson_8bit = np.clip(res_robertson * 255, 0, 255).astype('uint8') res_mertens_8bit = np.clip(res_mertens * 255, 0, 255).astype('uint8') cv.imwrite("hdr_debevec.jpg", res_debevec_8bit) cv.imwrite("hdr_robertson.jpg", res_robertson_8bit) cv.imwrite("fusion_mertens.jpg", res_mertens_8bit) # Estimate camera response function (CRF) cal_debevec = cv.createCalibrateDebevec() crf_debevec = cal_debevec.process(img_list, times=exposure_times) hdr_debevec = merge_debevec.process(img_list, times=exposure_times.copy(), response=crf_debevec.copy()) cal_robertson = cv.createCalibrateRobertson() crf_robertson = cal_robertson.process(img_list, times=exposure_times) hdr_robertson = merge_robertson.process(img_list, times=exposure_times.copy(), response=crf_robertson.copy())
batch_process(demosaic_channel, imgs, channel).values()) if run_hdr: images = batch_hdr(data, exposures, response) images = batch_process(hdr_uint_convert, images, np.uint16, np.max(list(images.values()))) else: images = {} for key in data.keys(): images[key] = data[key][exposure_chosen_idx] for pxl, img in images.items(): print("writing {}".format( str(dest_dir / Path("img{}.tiff".format(pxl))))) tiff.imwrite(str(dest_dir / Path("img{}.tiff".format(pxl))), img[:, :, channel]) if __name__ == '__main__': led_count, exposures = get_img_info(local_data_dir) cal_data = {} exp = np.float32([e / 1000000 for e in exposures]) load_images(local_data_dir, 43, cal_data, as_uint8) response = cv.createCalibrateDebevec().process(cal_data[43], exp) for chunk_start in range(0, led_count, chunksize): chunk_end = min(chunk_start + chunksize, led_count) print("starting imgs {} -> {}".format(chunk_start, chunk_end - 1)) data, exposures = load_dataset(local_data_dir, range(chunk_start, chunk_end), as_uint8) process_dataset(data, exposures, response, 0) # 0 = red channel
def findCRF(images, exposure_times): calibrateDebevec = cv.createCalibrateDebevec() responseDebevec = calibrateDebevec.process(images, exposure_times) return responseDebevec
with open(os.path.join(path, 'list.txt')) as f: content = f.readlines() for line in content: tokens = line.split() images.append(cv.imread(os.path.join(path, tokens[0]))) times.append(1 / float(tokens[1])) return images, np.asarray(times, dtype=np.float32) print("Working on the HDR image. (takes a few seconds.)") ## [Load images and exposure times] images, times = loadExposureSeq('../Data') ## [Load images and exposure times] ## [Estimate camera response] calibrate = cv.createCalibrateDebevec() response = calibrate.process(images, times) ## [Estimate camera response] ## [Make HDR image] merge_debevec = cv.createMergeDebevec() hdr = merge_debevec.process(images, times, response) ## [Make HDR image] ## [Tonemap HDR image] tonemap = cv.createTonemap(2.2) ldr = tonemap.process(hdr) ## [Tonemap HDR image] ## [Perform exposure fusion] merge_mertens = cv.createMergeMertens()
if good_pixel: pixel_values[(i, j)] = [ img[i, j, args.color_i] for img in images ] log_ts = [np.log2(t) for t in times] for [(i, j), vv], marker in zip(pixel_values.items(), MARKERS): plt.scatter(vv, log_ts, marker=marker, label=f'Pixel [{i}, {j}]') plt.xlabel('Output Pixel value (8-bit)') plt.ylabel('log exposure') plt.legend() plt.show() cal_debevec = cv2.createCalibrateDebevec(samples=200) print('Calibrated Debevec') crf_debevec = cal_debevec.process(images, times=times_array) merge_debevec = cv2.createMergeDebevec() hdr_debevec = merge_debevec.process(images, times=times_array.copy(), response=crf_debevec) print("merged") if args.show_steps: for [(i, j), vv], marker in zip(pixel_values.items(), MARKERS): e = hdr_debevec[i, j, args.color_i] plt.scatter(vv, np.array(log_ts) + np.log(e) + 1.6,
return images, np.asarray(times, dtype=np.float32) parser = argparse.ArgumentParser(description='Code for High Dynamic Range Imaging tutorial.') parser.add_argument('--input', type=str, help='Path to the directory that contains images and exposure times.') args = parser.parse_args() if not args.input: parser.print_help() exit(0) ## [Load images and exposure times] images, times = loadExposureSeq(args.input) ## [Load images and exposure times] ## [Estimate camera response] calibrate = cv.createCalibrateDebevec() response = calibrate.process(images, times) ## [Estimate camera response] ## [Make HDR image] merge_debevec = cv.createMergeDebevec() hdr = merge_debevec.process(images, times, response) ## [Make HDR image] ## [Tonemap HDR image] tonemap = cv.createTonemapDurand(2.2) ldr = tonemap.process(hdr) ## [Tonemap HDR image] ## [Perform exposure fusion] merge_mertens = cv.createMergeMertens()
def recover_camera_response(inputFolder = '.', exposureListFile = None, outputResponseCurve = "camera_response.spi1d", outputResponseFormat = "spi1d", calibrationApproach = "berkeley", mergeExposures = False, mergedExposuresOutput = None, verbose = False, robertsonMaxIter = 30.0, robertsonThreshold = 0.01, berkeleyLambda = 20.0, berkeleySamples = 1024, berkeleySamplePlacementRandom = False): extensions = generalExtensions if exposureListFile: with open(exposureListFile, 'r') as f: exposuresList = f.readlines() exposuresList = [x.strip() for x in exposuresList if len(x) > 1] imageUris = [x.split(' ')[0] for x in exposuresList] exposure_times = [1.0/float(x.split(' ')[1]) for x in exposuresList] else: imageUris = sorted( os.listdir( inputFolder ) ) imageUris = [x for x in imageUris if (os.path.splitext(x)[-1].lower()[1:] in extensions) and (x[0] != '.')] if verbose: print( imageUris ) cwd = os.getcwd() os.chdir( inputFolder ) exposure_times = [0]*len(imageUris) for i in range(len(imageUris)): exposure_times[i] = getShutterSpeed( imageUris[i], verbose=verbose ) # List has to be sorted from longest shutter speed to shortest for opencv functions to work exposure_times, imageUris = (list(x) for x in zip(*sorted(zip(exposure_times, imageUris)))) imageUris.reverse() exposure_times.reverse() exposure_times = np.array(exposure_times, dtype=np.float32) if verbose: for exposure in zip(exposure_times, imageUris): print( "Image : %s, Shutter speed : %2.6f" % (exposure[1], exposure[0]) ) img_list = [cv2.imread(fn) for fn in imageUris ] if not exposureListFile: os.chdir( cwd ) if calibrationApproach == "robertson": merge = cv2.createMergeRobertson() calibrate = cv2.createCalibrateRobertson() calibrate.setMaxIter(robertsonMaxIter) calibrate.setThreshold(robertsonThreshold) if verbose: print( calibrationApproach ) print( "\tmax iter : %d" % robertsonMaxIter ) print( "\tthreshold : %f" % robertsonThreshold ) else: merge = cv2.createMergeDebevec() calibrate = cv2.createCalibrateDebevec() calibrate.setLambda(berkeleyLambda) calibrate.setSamples(berkeleySamples) calibrate.setRandom(berkeleySamplePlacementRandom) if verbose: print( calibrationApproach ) print( "\tlambda : %3.2f" % berkeleyLambda ) print( "\tsamples : %d" % berkeleySamples ) print( "\trandom : %s" % berkeleySamplePlacementRandom ) if verbose: print( "recovering camera response" ) curve = calibrate.process(img_list, times=exposure_times) if verbose: print( "writing camera response - %s, %s" % (outputResponseFormat, outputResponseCurve) ) if outputResponseFormat == "spi1d": with open(outputResponseCurve, "w") as f: f.write( "Version 1\n" ) f.write( "From 0.000000 1.000000\n" ) f.write( "Length 256\n" ) f.write( "Components 3\n" ) f.write( "{\n" ) for i in range(len(curve)): f.write( "%3.6f %3.6f %3.6f\n" % (curve[i][0][0]*0.18, curve[i][0][1]*0.18, curve[i][0][2]*0.18) ) f.write( "}\n" ) else: with open(outputResponseCurve, "w") as f: for i in range(len(curve)): f.write( "%3.6f %3.6f %3.6f\n" % (curve[i][0][0], curve[i][0][1], curve[i][0][2]) ) if mergedExposuresOutput: if verbose: print( "merging exposures" ) hdr = merge.process(img_list, times=exposure_times.copy(), response=curve.copy()) cv2.imwrite(mergedExposuresOutput, hdr)
import numpy as np import cv2 # Read all the files with OpenCV files = ['images/memorial00.png', 'images/memorial01.png', 'images/memorial02.png', 'images/memorial03.png',\ 'images/memorial04.png', 'images/memorial05.png', 'images/memorial06.png', 'images/memorial07.png',\ 'images/memorial08.png', 'images/memorial09.png', 'images/memorial10.png', 'images/memorial11.png',\ 'images/memorial12.png', 'images/memorial13.png', 'images/memorial14.png', 'images/memorial15.png'] images = list([cv2.imread(f) for f in files]) # Compute the exposure times in seconds exposures = np.float32([1. / t for t in [0.03125, 0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]]) # Compute the response curve calibration = cv2.createCalibrateDebevec() response = calibration.process(images, exposures) # Compute the HDR image merge = cv2.createMergeDebevec() hdr = merge.process(images, exposures, response) # Save it to disk cv2.imwrite('hdr22_image.hdr', hdr) durand = cv2.createTonemapDurand(gamma=2.5) ldr_durand = durand.process(hdr) # Tonemap operators create floating point images with values in the 0..1 range # This is why we multiply the image with 255 before saving
tonemap1 = cv2.createTonemapDurand(gamma=2.2) res_debvec = tonemap1.process(hdr_debvec.copy()) tonemap2 = cv2.createTonemapDurand(gamma=1.3) res_robertson = tonemap2.process(hdr_robertson.copy()) # Exposure fusion using Mertens # 这里我们展示了一种可以合并曝光图像的替代算法,我们不需要曝光时间。我们也不需要使用任何tonemap算法,因为Mertens算法已经给出了[0..1]范围内的结果。 merge_mertens = cv2.createMergeMertens() res_mertens = merge_mertens.process(img_list) # Convert datatype to 8-bit and save # 为了保存或显示结果,我们需要将数据转换为[0..255]范围内的8位整数。 res_debvec_8bit = np.clip(res_debvec * 255, 0, 255).astype('uint8') res_robertson_8bit = np.clip(res_robertson * 255, 0, 255).astype('uint8') res_mertens_8bit = np.clip(res_mertens * 255, 0, 255).astype('uint8') cv2.imwrite("ldr_debvec.jpg", res_debvec_8bit) cv2.imwrite("ldr_robertson.jpg", res_robertson_8bit) cv2.imwrite("fusion_mertens.jpg", res_mertens_8bit) exit(0) # Estimate camera response function (CRF) # 相机响应功能(CRF)给出了场景辐射度与测量强度值之间的连接。如果在一些计算机视觉算法中非常重要,包括HDR算法,CRF。这里我们估计反相机响应函数并将其用于HDR合并。 cal_debvec = cv2.createCalibrateDebevec() crf_debvec = cal_debvec.process(img_list, times=exposure_times) hdr_debvec = merge_debvec.process(img_list, times=exposure_times.copy(), response=crf_debvec.copy()) cal_robertson = cv2.createCalibrateRobertson() crf_robertson = cal_robertson.process(img_list, times=exposure_times) hdr_robertson = merge_robertson.process(img_list, times=exposure_times.copy(), response=crf_robertson.copy())
# Do tone mapping based on Reinhard algorithm and do the gamma correction #tune the gamma value tonemap1 = cv2.createTonemapDurand(gamma=2.2) res_debvec1 = tonemap1.process(debe_hdr.copy()) #tonemap2 = cv2.createTonemapReinhard(gamma=2.2) #res_debvec2 = tonemap2.process(debe_hdr.copy()) #tonemap2 = cv2.createTonemapDurand(gamma=1.3) #res_robertson = tonemap2.process(hdr_robertson.copy()) # Convert typp to save and display res_debvec_8bit1 = np.clip(res_debvec1*255, 0, 255).astype('uint8') #res_debvec_8bit2 = np.clip(res_debvec2*255, 0, 255).astype('uint8') #res_robertson_8bit = np.clip(res_robertson*255, 0, 255).astype('uint8') #res_mertens_8bit = np.clip(res_mertens*255, 0, 255).astype('uint8') #cv2.imwrite("ldr_debvec24_Durand35.jpg", res_debvec_8bit1) #cv2.imwrite("ldr_debvec24_Reinhard35.jpg", res_debvec_8bit2) #cv2.imwrite("ldr_robertson.jpg", res_robertson_8bit) #cv2.imwrite("fusion_mertens.jpg", res_mertens_8bit) # Get the response function func1_deve = cv2.createCalibrateDebevec() func2_deve = func1_deve.process(img_list, times=exposure_times) func3_deve = debe1.process(img_list, times=exposure_times.copy(), response=func2_deve.copy()) #func1_rob = cv2.createCalibrateRobertson() #func2_rob = func1_rob.process(img_list, times=exposure_times) #func3_rob = merge_robertson.process(img_list, times=exposure_times.copy(), response=func2_rob.copy()) #save the results cv2.imwrite("response.jpg", func3_deve)
print("step3") # Convert datatype to 8-bit and save res_debvec_8bit = np.clip(res_debvec * 255, 0, 255).astype('uint8') res_robertson_8bit = np.clip(res_robertson * 255, 0, 255).astype('uint8') res_mertens_8bit = np.clip(res_mertens * 255, 0, 255).astype('uint8') cv2.imwrite("/home/pi/Desktop/ldr_debvec.jpg", res_debvec_8bit) cv2.imwrite("/home/pi/Desktop/ldr_robertson.jpg", res_robertson_8bit) cv2.imwrite("/home/pi/Desktop/fusion_mertens.jpg", res_mertens_8bit) cv2.imwrite("/home/pi/Desktop/hdr_debvec.jpg", hdr_debvec) cv2.imwrite("/home/pi/Desktop/hdr_robertson.jpg", hdr_robertson) cal_debvec = cv2.createCalibrateDebevec() crf_debvec = cal_debvec.process(img_list, times=exposure_times) hdr_debvec = merge_debvec.process(img_list, times=exposure_times.copy(), response=crf_debvec.copy()) cal_robertson = cv2.createCalibrateRobertson() crf_robertson = cal_robertson.process(img_list, times=exposure_times) hdr_robertson = merge_robertson.process(img_list, times=exposure_times.copy(), response=crf_robertson.copy()) # Obtain Camera Response Function (CRF) gr = crf_debvec[:, :, 0] gb = crf_debvec[:, :, 1] gg = crf_debvec[:, :, 2]
def getRespCurve(images, times): calDev = cv2.createCalibrateDebevec() response = calDev.process(images, times) return response
import sys import numpy as np import cv2 if __name__ == '__main__': if len(sys.argv) < 2: print ("[Usage] python script <num of img> <dir of img>") sys.exit(0) num = int(sys.argv[1]) dir = sys.argv[2] img = [] for k in range(num): filename = dir + "/%02d.png" % k img.append(cv2.imread(filename, cv2.IMREAD_UNCHANGED)) lst = [32, 16, 8, 4, 2, 1, 0.5, 0.25, 0.125, 0.0625, 0.03125, 0.015625, 0.007125, 0.00390625, 0.001953125, 0.00097656525] exp = np.array(lst[0:num], dtype=np.float32) Align = cv2.createAlignMTB() Align.process(img, img) ResponseCurve = cv2.createCalibrateDebevec() cur = ResponseCurve.process(img, exp) RadianceMap = cv2.createMergeDebevec() hdr = RadianceMap.process(img, exp, cur) cv2.imwrite("result.hdr", hdr)
if __name__ == '__main__': # Read images and exposure times print("Reading images ... ") images, times = readImagesAndTimes() # Align input images print("Aligning images ... ") alignMTB = cv2.createAlignMTB() alignMTB.process(images, images) # Obtain Camera Response Function (CRF) print("Calculating Camera Response Function (CRF) ... ") calibrateDebevec = cv2.createCalibrateDebevec() responseDebevec = calibrateDebevec.process(images, times) # Merge images into an HDR linear image print("Merging images into one HDR image ... ") mergeDebevec = cv2.createMergeDebevec() hdrDebevec = mergeDebevec.process(images, times, responseDebevec) # Save HDR image. cv2.imwrite("./images/HDR/hdrDebevec-example.hdr", hdrDebevec) print("saved hdrDebevec.hdr ") # Tonemap using Drago's method to obtain 24-bit color image print("Tonemaping using Drago's method ... ") tonemapDrago = cv2.createTonemapDrago(1.0, 0.7) ldrDrago = tonemapDrago.process(hdrDebevec) # The final output is multiplied by 3 just because it gave the most pleasing results.
def obtain_camera_response_function(images, times): calibrateDebevec = cv2.createCalibrateDebevec() responseDebevec = calibrateDebevec.process(images, times) return responseDebevec