def main(): usage = "usage: %prog [options] in_homogs out_homogs\n\n" usage += " Transform a homography file by translating then scaling\n" usage += " in_homog is input homography sequence\n" usage += " out_homog is output homography sequence\n" parser = OptionParser(usage=usage) parser.add_option("-x", "--x-trans", type='float', default=0.0, action="store", dest="x_trans", help="X translation, or image width if used with -a") parser.add_option("-y", "--y-trans", type='float', default=0.0, action="store", dest="y_trans", help="Y translation, or image height if used with -a") parser.add_option("-s", "--scale", type='float', default=1.0, action="store", dest="scale", help="scale factor") parser.add_option("-a", "--auto-translate", default=False, action="store_true", dest="auto_trans", help="compute the translation from image bounds") (options, args) = parser.parse_args() in_homog_file = args[0] out_homog_file = args[1] homogs = homography_io.load_homography_file(in_homog_file) x, y = options.x_trans, options.y_trans s = options.scale if options.auto_trans: x_rng, y_rng = compute_extents([H for _, H in homogs], (y,x)) x = -x_rng[0] y = -y_rng[0] print "output image size:", s * (x_rng[1] - x_rng[0]), \ s * (y_rng[1] - y_rng[0]) print "translating output by (%g, %g)" % (x,y) print "scaling output by ", s trans_homogs = [] for md, H in homogs: H = translate_homog(H, x, y) H = scale_homog(H, s) trans_homogs.append((md,H)) homography_io.write_homography_file(trans_homogs, out_homog_file)
def main(): usage = "usage: %prog [options] image_list_file homography_file mosaic_file" description = "warp all of the images by homography and overlay into a mosaic" parser = OptionParser(usage=usage, description=description) parser.add_option("-e", "--expand", default=False, action="store_true", dest="expand", help="expand the output image to fit entire mosaic") parser.add_option("-b", "--blend", default=False, action="store_true", dest="blend", help="blend the pixels when creating the mosaic") parser.add_option("-m", "--match-resolution", default=False, action="store_true", dest="match_resolution", help="automatically estimate the output image scale " "to match the input resolution on average") parser.add_option("-f", "--frame-width", default=0, type="int", dest="frame", help="draw a frame around each image") parser.add_option("-s", "--scale", default=1.0, type="float", dest="scale", help="scale of the output mosaic size") parser.add_option("-a", "--all-frame", default=False, action="store_true", dest="all_frame", help="draw all parts of the frames, even when obscured") (options, args) = parser.parse_args() image_filename = args[0] homog_filename = args[1] mosaic_filename = args[2] with open(image_filename, 'r') as f: image_files = [line.rstrip() for line in f] homogs = homography_io.load_homography_file(homog_filename) if len(homogs) != len(image_files): sys.exit("Number of homographies ("+str(len(homogs))+ ") does not match number of images ("+ str(len(image_files))+")") shapes = [image_file_dims(fn) for fn in image_files] img = cv2.imread(image_files[0]) img_dtype = img.dtype scale = options.scale if options.match_resolution: scale = 1.0 / compute_average_scale([H for _, H in homogs], shapes) sH = np.diag([scale, scale, 1.0]) homogs = [(f, sH * H) for f, H in homogs] if options.expand: x_rng, y_rng = compute_extents([H for _, H in homogs], shapes) H_offset = np.matrix([[1, 0, -x_rng[0]], [0, 1, -y_rng[0]], [0, 0, 1]]) mosaic_shape = (int(math.ceil(x_rng[1] - x_rng[0])), int(math.ceil(y_rng[1] - y_rng[0]))) else: H_offset = np.eye(3) mosaic_shape = img.shape[1::-1] if options.blend: out_type = np.int32 else: out_type = img_dtype print "creating mosaic of size", mosaic_shape mosaic = np.zeros(mosaic_shape[::-1] + (4,), out_type) edges = np.zeros(mosaic.shape[:2], np.bool) for fname, (_, H) in zip(image_files, homogs): print "processing", fname H = H_offset * H img = cv2.imread(fname) imgt = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA) warped = cv2.warpPerspective(imgt, H, mosaic_shape) if options.frame > 0: edge_map = warped[:,:,3] == 255 structure = np.ones((2*options.frame+1,)*2) edge_map = np.logical_xor(edge_map, morph.binary_erosion(edge_map, structure)) if options.all_frame: edges = np.logical_or(edges, edge_map) else: warped[edge_map] = (0,0,255,255) mask = np.nonzero(warped[:,:,3] == 255) if options.blend: mosaic[mask] += warped[mask] else: mosaic[mask] = warped[mask] if options.blend: mask = np.nonzero(mosaic[:,:,3] > 255) for i in range(4): mosaic[:,:,i][mask] /= mosaic[:,:,3][mask] / 255 mosaic.astype(img_dtype) if options.frame > 0 and options.all_frame: mosaic[edges] = (0,0,255,255) cv2.imwrite(mosaic_filename, mosaic)
def main(): usage = "usage: %prog [options] image_list_file homography_file mosaic_file" description = "warp all of the images by homography and overlay into a mosaic" parser = OptionParser(usage=usage, description=description) parser.add_option("-e", "--expand", default=False, action="store_true", dest="expand", help="expand the output image to fit entire mosaic") parser.add_option("-b", "--blend", default=False, action="store_true", dest="blend", help="blend the pixels when creating the mosaic") parser.add_option("-f", "--frame-width", default=0, type="int", dest="frame", help="draw a frame around each image") parser.add_option("-a", "--all-frame", default=False, action="store_true", dest="all_frame", help="draw all parts of the frames, even when obscured") (options, args) = parser.parse_args() image_filename = args[0] homog_filename = args[1] mosaic_filename = args[2] with open(image_filename, 'r') as f: image_files = [line.rstrip() for line in f] homogs = homography_io.load_homography_file(homog_filename) if len(homogs) != len(image_files): sys.exit("Number of homographies (" + str(len(homogs)) + ") does not match number of images (" + str(len(image_files)) + ")") images = [cv2.imread(fn) for fn in image_files] shapes = [img.shape[:2] for img in images] if options.expand: x_rng, y_rng = compute_extents([H for _, H in homogs], shapes) H_offset = np.matrix([[1, 0, -x_rng[0]], [0, 1, -y_rng[0]], [0, 0, 1]]) mosaic_shape = (int(math.ceil(x_rng[1] - x_rng[0])), int(math.ceil(y_rng[1] - y_rng[0]))) else: H_offset = np.eye(3) mosaic_shape = images[0].shape[1::-1] if options.blend: out_type = np.int32 else: out_type = images[0].dtype mosaic = np.zeros(mosaic_shape[::-1] + (4, ), out_type) edges = np.zeros(mosaic.shape[:2], np.bool) for fname, img, (_, H) in zip(image_files, images, homogs): H = H_offset * H imgt = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA) warped = cv2.warpPerspective(imgt, H, mosaic_shape) if options.frame > 0: edge_map = warped[:, :, 3] == 255 structure = np.ones((2 * options.frame + 1, ) * 2) edge_map = np.logical_xor( edge_map, morph.binary_erosion(edge_map, structure)) if options.all_frame: edges = np.logical_or(edges, edge_map) else: warped[edge_map] = (0, 0, 255, 255) mask = np.nonzero(warped[:, :, 3] == 255) if options.blend: mosaic[mask] += warped[mask] else: mosaic[mask] = warped[mask] if options.blend: mask = np.nonzero(mosaic[:, :, 3] > 255) for i in range(4): mosaic[:, :, i][mask] /= mosaic[:, :, 3][mask] / 255 mosaic.astype(images[0].dtype) if options.frame > 0 and options.all_frame: mosaic[edges] = (0, 0, 255, 255) cv2.imwrite(mosaic_filename, mosaic)
def main(): usage = "usage: %prog [options] in_homogs out_homogs\n\n" usage += " Transform a homography file by translating then scaling\n" usage += " in_homog is input homography sequence\n" usage += " out_homog is output homography sequence\n" parser = OptionParser(usage=usage) parser.add_option("-x", "--x-trans", type='float', default=0.0, action="store", dest="x_trans", help="X translation, or image width if used with -a") parser.add_option("-y", "--y-trans", type='float', default=0.0, action="store", dest="y_trans", help="Y translation, or image height if used with -a") parser.add_option("-s", "--scale", type='float', default=1.0, action="store", dest="scale", help="scale factor") parser.add_option("-a", "--auto-translate", default=False, action="store_true", dest="auto_trans", help="compute the translation from image bounds") (options, args) = parser.parse_args() in_homog_file = args[0] out_homog_file = args[1] homogs = homography_io.load_homography_file(in_homog_file) x, y = options.x_trans, options.y_trans s = options.scale if options.auto_trans: x_rng, y_rng = compute_extents([H for _, H in homogs], (y, x)) x = -x_rng[0] y = -y_rng[0] print "output image size:", s * (x_rng[1] - x_rng[0]), \ s * (y_rng[1] - y_rng[0]) print "translating output by (%g, %g)" % (x, y) print "scaling output by ", s trans_homogs = [] for md, H in homogs: H = translate_homog(H, x, y) H = scale_homog(H, s) trans_homogs.append((md, H)) homography_io.write_homography_file(trans_homogs, out_homog_file)