def view_post_pmcc_mfov(pmcc_matches_fname, matches_num, seed, scale, output_dir): # Load the preliminary matches with open(pmcc_matches_fname, 'r') as data_matches: pmcc_matches_data = json.load(data_matches) if len(pmcc_matches_data["pointmatches"]) == 0: print("No matches were found in pmcc-matching, aborting") return tiles_fname1 = pmcc_matches_data["tilespec1"] tiles_fname2 = pmcc_matches_data["tilespec2"] # Read the tilespecs ts1 = utils.load_tilespecs(tiles_fname1) ts2 = utils.load_tilespecs(tiles_fname2) indexed_ts1 = utils.index_tilespec(ts1) indexed_ts2 = utils.index_tilespec(ts2) # Create the (lazy) renderers for the two sections img1_renderer = TilespecAffineRenderer(ts1) img2_renderer = TilespecAffineRenderer(ts2) scale_transformation = np.array([[scale, 0., 0.], [0., scale, 0.]]) img1_renderer.add_transformation(scale_transformation) img2_renderer.add_transformation(scale_transformation) # Find a random number of points np.random.seed(seed) matches_idxs = np.random.choice(len(pmcc_matches_data["pointmatches"]), matches_num, replace=False) template_size = int(TEMPLATE_SIZE * scale) print("Actual template size: {}".format(template_size)) utils.create_dir(output_dir) # save the matches thumbnails to the output dir for idx in matches_idxs: # rescale the matches p1 = np.array(pmcc_matches_data["pointmatches"][idx]["point1"]) p2 = np.array(pmcc_matches_data["pointmatches"][idx]["point2"]) print("Saving match {}: {} and {}".format(idx, p1, p2)) p1_scaled = p1 * scale p2_scaled = p2 * scale out_fname_prefix = os.path.join( output_dir, 'pmcc_match_{}-{}_{}-{}'.format(int(p1[0]), int(p1[1]), int(p2[0]), int(p2[1]))) # Crop and save cropped_img1, _ = img1_renderer.crop(p1_scaled[0] - template_size, p1_scaled[1] - template_size, p1_scaled[0] + template_size, p1_scaled[1] + template_size) cv2.imwrite('{}_image1.jpg'.format(out_fname_prefix), cropped_img1) cropped_img2, _ = img2_renderer.crop(p2_scaled[0] - template_size, p2_scaled[1] - template_size, p2_scaled[0] + template_size, p2_scaled[1] + template_size) cv2.imwrite('{}_image2.jpg'.format(out_fname_prefix), cropped_img2)
def match_layers_sift_features(tiles_fname1, features_dir1, tiles_fname2, features_dir2, out_fname, conf_fname=None): params = utils.conf_from_file(conf_fname, 'MatchLayersSiftFeaturesAndFilter') if params is None: params = {} actual_params = {} # Parameters for the matching actual_params["max_attempts"] = params.get("max_attempts", 10) actual_params["num_filtered_cutoff"] = params.get("num_filtered_cutoff", 50) actual_params["filter_rate_cutoff"] = params.get("filter_rate_cutoff", 0.25) actual_params["ROD_cutoff"] = params.get("ROD_cutoff", 0.92) # Parameters for the RANSAC actual_params["model_index"] = params.get("model_index", 1) actual_params["iterations"] = params.get("iterations", 500) actual_params["max_epsilon"] = params.get("max_epsilon", 500.0) actual_params["min_inlier_ratio"] = params.get("min_inlier_ratio", 0.01) actual_params["min_num_inlier"] = params.get("min_num_inliers", 7) actual_params["max_trust"] = params.get("max_trust", 3) print("Matching layers: {} and {}".format(tiles_fname1, tiles_fname2)) starttime = time.clock() # Read the tilespecs indexed_ts1 = utils.index_tilespec(utils.load_tilespecs(tiles_fname1)) indexed_ts2 = utils.index_tilespec(utils.load_tilespecs(tiles_fname2)) num_mfovs1 = len(indexed_ts1) num_mfovs2 = len(indexed_ts2) # Match the two sections retval = analyze2slices(indexed_ts1, indexed_ts2, num_mfovs1, num_mfovs2, features_dir1, features_dir2, actual_params) # Save the output jsonfile = {} jsonfile['tilespec1'] = tiles_fname1 jsonfile['tilespec2'] = tiles_fname2 jsonfile['matches'] = retval jsonfile['runtime'] = time.clock() - starttime with open(out_fname, 'w') as out: json.dump(jsonfile, out, indent=4) print("Done.")
def plot_tilespecs(ts_file): # Read the tilespecs file ts = utils.load_tilespecs(ts_file) # Index the tilespecs according to mfov and tile_index (1-based) indexed_ts = utils.index_tilespec(ts) # Get the centers centers = [get_center(indexed_ts[m]) for m in sorted(indexed_ts.keys())] max_x_or_y = np.max(centers) # Create the figure fig = plt.figure() fig.suptitle('{} - mfovs'.format(os.path.basename(ts_file)), fontsize=14, fontweight='bold') ax = fig.add_subplot(111) # plot text at the centers location for i, center in enumerate(centers): print (i+1), center center_x = int(center[0] / max_x_or_y * 1000) center_y = int(center[1] / max_x_or_y * 1000) ax.text(center_x, center_y, str(i + 1), fontsize=15) ax.axis([0, 1000, 0, 1000]) # TODO - plot the boundaries of the mfovs # plot the entire graph plt.show() return fig
def create_surf_features(tiles_fname, out_fname, index, conf_fname=None): # load tilespecs files tilespecs = utils.load_tilespecs(tiles_fname) tilespec = tilespecs[index] # load the image image_path = tilespec["mipmapLevels"]["0"]["imageUrl"] image_path = image_path.replace("file://", "") if image_path.endswith(".jp2"): img_gray = glymur.Jp2k(image_path)[:] # load in full resolution else: img_gray = cv2.imread(image_path, cv2.CV_LOAD_IMAGE_GRAYSCALE) print "Computing surf features for image: {}".format(image_path) # compute features for the given index # detector = cv2.FeatureDetector_create("SIFT") # extractor = cv2.DescriptorExtractor_create("SIFT") # #print("Detecting keypoints...") # kp = detector.detect(img_gray) # #print("Computing descriptions...") # pts, descs = extractor.compute(img_gray, kp) surf = cv2.SURF() pts, descs = surf.detectAndCompute(img_gray, None) descs = np.array(descs, dtype=np.uint8) print "Found {} features".format(len(descs)) # Save the features print "Saving surf features at: {}".format(out_fname) with h5py.File(out_fname, 'w') as hf: hf.create_dataset("imageUrl", data=np.array(image_path.encode("utf-8"), dtype='S')) hf.create_dataset("pts/responses", data=np.array([p.response for p in pts], dtype=np.float32)) hf.create_dataset("pts/locations", data=np.array([p.pt for p in pts], dtype=np.float32)) hf.create_dataset("pts/sizes", data=np.array([p.size for p in pts], dtype=np.float32)) hf.create_dataset("pts/octaves", data=np.array([p.octave for p in pts], dtype=np.float32)) hf.create_dataset("descs", data=descs)
def create_post_filter_jobs(slayer, filtered_ts_fname, layers_data, jobs, matched_sifts_dir, workspace_dir, output_dir, conf_file_name): layer_matched_sifts_intra_dir = os.path.join( matched_sifts_dir, os.path.join(layers_data[slayer]['prefix'], 'intra')) layer_matched_sifts_inter_dir = os.path.join( matched_sifts_dir, os.path.join(layers_data[slayer]['prefix'], 'inter')) create_dir(layer_matched_sifts_intra_dir) create_dir(layer_matched_sifts_inter_dir) # Read the filtered tilespec tiles_fname_prefix = os.path.splitext( os.path.basename(filtered_ts_fname))[0] cur_tilespec = load_tilespecs(filtered_ts_fname) mfovs = set() for ts in cur_tilespec: mfovs.add(ts["mfov"]) # create the intra matched sifts directories for mfov in mfovs: mfov_intra_dir = os.path.join(layer_matched_sifts_intra_dir, str(mfov)) create_dir(mfov_intra_dir) # A map between layer to a list of multiple matches multiple_match_jobs = {} # read every pair of overlapping tiles, and match their sift features jobs_match_intra_mfovs = {} jobs_match_inter_mfovs = [] indices = [] # TODO - use some other method to detect overlapping tiles for pair in itertools.combinations(xrange(len(cur_tilespec)), 2): idx1 = pair[0] idx2 = pair[1] ts1 = cur_tilespec[idx1] ts2 = cur_tilespec[idx2] # if the two tiles intersect, match them bbox1 = BoundingBox.fromList(ts1["bbox"]) bbox2 = BoundingBox.fromList(ts2["bbox"]) if bbox1.overlap(bbox2): imageUrl1 = ts1["mipmapLevels"]["0"]["imageUrl"] imageUrl2 = ts2["mipmapLevels"]["0"]["imageUrl"] tile_fname1 = os.path.basename(imageUrl1).split('.')[0] tile_fname2 = os.path.basename(imageUrl2).split('.')[0] index_pair = [ "{}_{}".format(ts1["mfov"], ts1["tile_index"]), "{}_{}".format(ts2["mfov"], ts2["tile_index"]) ] if ts1["mfov"] == ts2["mfov"]: # Intra mfov job cur_match_dir = os.path.join(layer_matched_sifts_intra_dir, str(ts1["mfov"])) else: # Inter mfov job cur_match_dir = layer_matched_sifts_inter_dir match_json = os.path.join( cur_match_dir, "{0}_sift_matches_{1}_{2}.json".format(tiles_fname_prefix, tile_fname1, tile_fname2)) # match the features of overlapping tiles if not os.path.exists(match_json): print "Matching sift of tiles: {0} and {1}".format( imageUrl1, imageUrl2) # The filter is done, so assumes no dependencies dependencies = [] # Check if the job already exists if ts1["mfov"] == ts2["mfov"]: # Intra mfov job if ts1["mfov"] in jobs[slayer]['matched_sifts'][ 'intra'].keys(): job_match = jobs[slayer]['matched_sifts']['intra'][ ts1["mfov"]] else: job_match = MatchMultipleSiftFeaturesAndFilter( cur_match_dir, filtered_ts_fname, "intra_l{}_{}".format(slayer, ts1["mfov"]), threads_num=4, wait_time=None, conf_fname=conf_file_name) jobs[slayer]['matched_sifts']['intra'][ ts1["mfov"]] = job_match else: # Inter mfov job if jobs[slayer]['matched_sifts']['inter'] is None: job_match = MatchMultipleSiftFeaturesAndFilter( cur_match_dir, filtered_ts_fname, "inter_{}".format(slayer), threads_num=4, wait_time=None, conf_fname=conf_file_name) jobs[slayer]['matched_sifts']['inter'] = job_match else: job_match = jobs[slayer]['matched_sifts']['inter'] job_match.add_job(dependencies, layers_data[slayer]['sifts'][imageUrl1], layers_data[slayer]['sifts'][imageUrl2], match_json, index_pair) #jobs[slayer]['matched_sifts'].append(job_match) layers_data[slayer]['matched_sifts'].append(match_json) # Create a single file that lists all tilespecs and a single file that lists all pmcc matches (the os doesn't support a very long list) matches_list_file = os.path.join( workspace_dir, "{}_matched_sifts_files.txt".format(tiles_fname_prefix)) write_list_to_file(matches_list_file, layers_data[slayer]['matched_sifts']) # optimize (affine) the 2d layer matches (affine) opt_montage_json = os.path.join( output_dir, "{0}_montaged.json".format(tiles_fname_prefix)) if not os.path.exists(opt_montage_json): print "Optimizing (affine) layer matches: {0}".format(slayer) dependencies = [] if jobs[slayer]['matched_sifts']['inter'] is not None: dependencies.append(jobs[slayer]['matched_sifts']['inter']) if jobs[slayer]['matched_sifts']['intra'] is not None and len( jobs[slayer]['matched_sifts']['intra']) > 0: dependencies.extend( jobs[slayer]['matched_sifts']['intra'].values()) job_opt_montage = OptimizeMontageTransform(dependencies, filtered_ts_fname, matches_list_file, opt_montage_json, conf_fname=conf_file_name) layers_data[slayer]['optimized_montage'] = opt_montage_json
# Get all input json files (one per section) into a dictionary {json_fname -> [filtered json fname, sift features file, etc.]} json_files = dict( (jf, {}) for jf in (glob.glob(os.path.join(args.tiles_dir, '*.json')))) skipped_layers = parse_range(args.skip_layers) all_layers = [] jobs = {} layers_data = {} fixed_tile = 0 for f in sorted(json_files.keys()): tiles_fname_prefix = os.path.splitext(os.path.basename(f))[0] cur_tilespec = load_tilespecs(f) # read the layer from the file layer = None for tile in cur_tilespec: if tile['layer'] is None: print "Error reading layer in one of the tiles in: {0}".format( f) sys.exit(1) if layer is None: layer = int(tile['layer']) break if layer != tile['layer']: print "Error when reading tiles from {0} found inconsistent layers numbers: {1} and {2}".format( f, layer, tile['layer']) sys.exit(1)
def match_layers_pmcc_matching(tiles_fname1, tiles_fname2, pre_matches_fname, out_fname, conf_fname=None): params = utils.conf_from_file(conf_fname, 'MatchLayersBlockMatching') if params is None: params = {} cv_wrap_module.setNumThreads(1) # Parameters for the matching hex_spacing = params.get("hexspacing", 500) scaling = params.get("scaling", 0.2) template_size = params.get("template_size", 200) template_size *= scaling # Read the tilespecs ts1 = utils.load_tilespecs(tiles_fname1) ts2 = utils.load_tilespecs(tiles_fname2) indexed_ts1 = utils.index_tilespec(ts1) # Get the tiles centers for each section tile_centers1 = get_tile_centers_from_json(ts1) tile_centers1tree = spatial.KDTree(tile_centers1) tile_centers2 = get_tile_centers_from_json(ts2) mfov_centers1 = get_mfov_centers_from_json(indexed_ts1) # Load the preliminary matches with open(pre_matches_fname, 'r') as data_matches: mfov_pre_matches = json.load(data_matches) # Generate an hexagonal grid according to the first section's bounding box bb = BoundingBox.read_bbox(tiles_fname1) hexgr = generatehexagonalgrid(bb, hex_spacing) if len(mfov_pre_matches["matches"]) == 0: print("No matches were found in pre-matching") return best_transformations = get_best_transformations(mfov_pre_matches) img_matches = get_img_matches(ts1, tile_centers1, ts2, tile_centers2, best_transformations, mfov_centers1) img1_url = ts1[50]["mipmapLevels"]["0"]["imageUrl"] img1_url = img1_url.replace("file://", "") img1 = cv2.imread(img1_url, 0) img1_resized = cv2.resize(img1, (0, 0), fx=scaling, fy=scaling) img1width = img1_resized.shape[0] img1height = img1_resized.shape[1] # Iterate over the hexagonal points and find a match in the second section thedictionary = {} for i in range(len(hexgr)): if i % 1000 == 0 and i > 0: print(i) # Find the tile image where the point from the hexagonal is in the first section img1_ind = get_closest_index_to_point(hexgr[i], tile_centers1tree) if img1_ind is None: continue if not is_point_in_img(ts1[img1_ind], hexgr[i]): continue # Get expected point of hexgr[i] in the second section img1_offset = get_image_top_left(ts1, img1_ind) expected_transform = find_best_mfov_transformation( ts1[img1_ind]["mfov"], best_transformations, mfov_centers1) img1_template = get_blank_template_from_img_and_point( img1width, img1height, template_size, (np.array(hexgr[i]) - img1_offset) * scaling) if img1_template is None: continue startx, starty, w, h, not_on_mesh = img1_template center_point1 = np.array([startx + w / 2, starty + h / 2 ]) / scaling + img1_offset expected_new_center = np.dot(expected_transform, np.append(center_point1, [1]))[0:2] img2_inds = img_matches[img1_ind] img2s = get_images_indices_from_indices_and_point( ts2, img2_inds, expected_new_center) for img2_ind in img2s: # Build dictionary here if img1_ind in thedictionary: newdi = thedictionary[img1_ind] if img2_ind in newdi: newdi[img2_ind].append(hexgr[i]) else: newdi[img2_ind] = [] newdi[img2_ind].append(hexgr[i]) else: newdi = {} newdi[img2_ind] = [] newdi[img2_ind].append(hexgr[i]) thedictionary[img1_ind] = newdi with open(out_fname, 'w') as out: json.dump(thedictionary, out, indent=4) print("Done.")
def view_pre_pmcc_mfov(pre_matches_fname, targeted_mfov, output_fname, scale): # Load the preliminary matches with open(pre_matches_fname, 'r') as data_matches: mfov_pre_matches = json.load(data_matches) if len(mfov_pre_matches["matches"]) == 0: print("No matches were found in pre-matching, aborting") return tiles_fname1 = mfov_pre_matches["tilespec1"] tiles_fname2 = mfov_pre_matches["tilespec2"] # Read the tilespecs ts1 = utils.load_tilespecs(tiles_fname1) ts2 = utils.load_tilespecs(tiles_fname2) indexed_ts1 = utils.index_tilespec(ts1) indexed_ts2 = utils.index_tilespec(ts2) sorted_mfovs1 = sorted(indexed_ts1.keys()) sorted_mfovs2 = sorted(indexed_ts2.keys()) # Get the tiles centers for each section tile_centers1 = get_tile_centers_from_json(ts1) tile_centers1tree = spatial.KDTree(tile_centers1) tile_centers2 = get_tile_centers_from_json(ts2) tile_centers2tree = spatial.KDTree(tile_centers2) mfov_centers1 = get_mfov_centers_from_json(indexed_ts1) mfov_centers2 = get_mfov_centers_from_json(indexed_ts2) best_transformations = get_best_transformations( mfov_pre_matches, tiles_fname1, tiles_fname2, mfov_centers1, mfov_centers2, sorted_mfovs1, sorted_mfovs2) mfov_tiles = indexed_ts1[targeted_mfov] tiles_boundaries1 = [] for tile in mfov_tiles.values(): p1 = np.array([tile["bbox"][0], tile["bbox"][2]]) p2 = np.array([tile["bbox"][0], tile["bbox"][3]]) p3 = np.array([tile["bbox"][1], tile["bbox"][2]]) p4 = np.array([tile["bbox"][1], tile["bbox"][3]]) tiles_boundaries1.extend([p1, p2, p3, p4]) # Create the (lazy) renderers for the two sections img1_renderer = TilespecAffineRenderer(indexed_ts1[targeted_mfov].values()) # Use the mfov exepected transform (from section 1 to section 2) to transform img1 img1_to_img2_transform = np.array( find_best_mfov_transformation(targeted_mfov, best_transformations, mfov_centers1)[:2]) img1_renderer.add_transformation(img1_to_img2_transform) # Find the relevant tiles from section 2 section2_tiles_indices = set() for p in tiles_boundaries1: # Find the tile image where the point from the hexagonal is in the first section img1_ind = get_closest_index_to_point(p, tile_centers1tree) #print(img1_ind) if img1_ind is None: continue if ts1[img1_ind]["mfov"] != targeted_mfov: continue if not is_point_in_img(ts1[img1_ind], p): continue img1_point = p # Find the point on img2 img1_point_on_img2 = np.dot(img1_to_img2_transform[:2, :2], img1_point) + img1_to_img2_transform[:2, 2] # Find the tile that is closest to that point img2_ind = get_closest_index_to_point(img1_point_on_img2, tile_centers2tree) #print("img1_ind {}, img2_ind {}".format(img1_ind, img2_ind)) section2_tiles_indices.add(img2_ind) print("section2 tiles (#tiles={}): {}".format(len(section2_tiles_indices), section2_tiles_indices)) # Scale down the rendered images scale_transformation = np.array([[scale, 0., 0.], [0., scale, 0.]]) img1_renderer.add_transformation(scale_transformation) img2_renderer = TilespecAffineRenderer( [ts2[tile_index] for tile_index in section2_tiles_indices]) img2_renderer.add_transformation(scale_transformation) # render the images start_time = time.time() img1, start_point1 = img1_renderer.render() print("image 1 rendered in {} seconds".format(time.time() - start_time)) start_time = time.time() img2, start_point2 = img2_renderer.render() print("image 2 rendered in {} seconds".format(time.time() - start_time)) end_point1 = start_point1 + np.array([img1.shape[1], img1.shape[0]]) end_point2 = start_point2 + np.array([img2.shape[1], img2.shape[0]]) # merge the 2 images into a single image using 2 channels (red and green) start_point = np.minimum(start_point1, start_point2) end_point = np.maximum(end_point1, end_point2) # out_shape = ((end_point - start_point)[1], (end_point - start_point)[0]) # #img_out = np.zeros(((end_point - start_point)[1], (end_point - start_point)[0], 3), dtype=np.uint8) # #img_out[start_point1[1] - start_point[1]:img1.shape[0] + start_point1[1] - start_point[1], # # start_point1[0] - start_point[0]:img1.shape[1] + start_point1[0] - start_point[0], # # 1] = img1 # #img_out[start_point2[1] - start_point[1]:img2.shape[0] + start_point2[1] - start_point[1], # # start_point2[0] - start_point[0]:img2.shape[1] + start_point2[0] - start_point[0], # # 2] = img2 # img_out = np.zeros(((end_point - start_point)[1], (end_point - start_point)[0]), dtype=np.uint8) # img_out[start_point1[1] - start_point[1]:img1.shape[0] + start_point1[1] - start_point[1], # start_point1[0] - start_point[0]:img1.shape[1] + start_point1[0] - start_point[0]] = img1 # img_out[start_point2[1] - start_point[1]:img2.shape[0] + start_point2[1] - start_point[1], # start_point2[0] - start_point[0]:img2.shape[1] + start_point2[0] - start_point[0]] -= img2 # # cv2.imwrite(output_fname, img_out) save_animated_gif(img1, start_point1, img2, start_point2, output_fname) die
def match_layers_pmcc_matching(tiles_fname1, tiles_fname2, pre_matches_fname, out_fname, conf_fname=None): params = utils.conf_from_file(conf_fname, 'MatchLayersBlockMatching') if params is None: params = {} # Parameters for the matching hex_spacing = params.get("hexspacing", 1500) scaling = params.get("scaling", 0.2) template_size = params.get("template_size", 200) template_size *= scaling print("Actual template size (after scaling): {}".format(template_size)) # Parameters for PMCC filtering min_corr = params.get("min_correlation", 0.2) max_curvature = params.get("maximal_curvature_ratio", 10) max_rod = params.get("maximal_ROD", 0.9) print(params) debug_save_matches = False if "debug_save_matches" in params.keys(): print("Debug mode - on") debug_save_matches = True if debug_save_matches: # Create a debug directory import datetime debug_dir = os.path.join(os.path.dirname(out_fname), 'debug_matches_{}'.format(datetime.datetime.now().isoformat())) os.mkdir(debug_dir) print("Block-Matching+PMCC layers: {} and {}".format(tiles_fname1, tiles_fname2)) # Read the tilespecs ts1 = utils.load_tilespecs(tiles_fname1) ts2 = utils.load_tilespecs(tiles_fname2) indexed_ts1 = utils.index_tilespec(ts1) indexed_ts2 = utils.index_tilespec(ts2) # num_mfovs1 = len(indexed_ts1) # num_mfovs2 = len(indexed_ts2) # Get the tiles centers for each section tile_centers1 = get_tile_centers_from_json(ts1) tile_centers1tree = spatial.KDTree(tile_centers1) tile_centers2 = get_tile_centers_from_json(ts2) mfov_centers1 = get_mfov_centers_from_json(indexed_ts1) # Load the preliminary matches with open(pre_matches_fname, 'r') as data_matches: mfov_pre_matches = json.load(data_matches) out_jsonfile = {} out_jsonfile['tilespec1'] = tiles_fname1 out_jsonfile['tilespec2'] = tiles_fname2 # Generate an hexagonal grid according to the first section's bounding box bb = BoundingBox.read_bbox(tiles_fname1) hexgr = generatehexagonalgrid(bb, hex_spacing) if len(mfov_pre_matches["matches"]) == 0: print("No matches were found in pre-matching, saving an empty matches output file") out_jsonfile['runtime'] = 0 out_jsonfile['mesh'] = hexgr finalpointmatches = [] out_jsonfile['pointmatches'] = finalpointmatches with open(out_fname, 'w') as out: json.dump(out_jsonfile, out, indent=4) return # global datadir # global imgdir # global workdir # global outdir # script, slice1, slice2, conffile = sys.argv # slice1 = int(slice1) # slice2 = int(slice2) # slicestring1 = ("%03d" % slice1) # slicestring2 = ("%03d" % slice2) # with open(conffile) as conf_file: # conf = json.load(conf_file) # datadir = conf["driver_args"]["datadir"] # imgdir = conf["driver_args"]["imgdir"] # workdir = conf["driver_args"]["workdir"] # outdir = conf["driver_args"]["workdir"] starttime = time.clock() # Compute the best transformations for each of the mfovs in section 1 (the transformations to section 2) best_transformations = get_best_transformations(mfov_pre_matches) img_matches = get_img_matches(ts1, tile_centers1, ts2, tile_centers2, best_transformations, mfov_centers1) point_matches = [] actual_matches_num = 0 # Iterate over the hexagonal points and find a match in the second section print("Matching {} points between the two sections".format(len(hexgr))) for i in range(len(hexgr)): if i % 1000 == 0 and i > 0: print(i) # Find the tile image where the point from the hexagonal is in the first section img1_ind = get_closest_index_to_point(hexgr[i], tile_centers1tree) if img1_ind is None: continue if not is_point_in_img(ts1[img1_ind], hexgr[i]): continue # Load the image, and get the template from it img1_url = ts1[img1_ind]["mipmapLevels"]["0"]["imageUrl"] img1_url = img1_url.replace("file://", "") img1 = cv2.imread(img1_url, 0) img1_resized = cv2.resize(img1, (0, 0), fx=scaling, fy=scaling) img1_offset = get_image_top_left(ts1, img1_ind) expected_transform = find_best_mfov_transformation(ts1[img1_ind]["mfov"], best_transformations, mfov_centers1) img1_template = get_template_from_img_and_point(img1_resized, template_size, (np.array(hexgr[i]) - img1_offset) * scaling) if img1_template is None: continue # Find the template coordinates chosen_template, startx, starty, not_on_mesh = img1_template # print("img1_template starts at: {}, {} and original point should have been {}".format(startx, starty, np.array(hexgr[i]) - img1_offset)) w, h = chosen_template.shape center_point1 = np.array([startx + w / 2, starty + h / 2]) / scaling + img1_offset # print("center_point1", center_point1) expected_new_center = np.dot(expected_transform, np.append(center_point1, [1]))[0:2] ro, col = chosen_template.shape rad2deg = -180 / math.pi # TODO - assumes only rigid transformation, should be more general angle_of_rot = rad2deg * math.atan2(expected_transform[1][0], expected_transform[0][0]) rotation_matrix = cv2.getRotationMatrix2D((h / 2, w / 2), angle_of_rot, 1) rotated_temp1 = cv2.warpAffine(chosen_template, rotation_matrix, (col, ro)) xaa = int(w / 2.9) rotated_and_cropped_temp1 = rotated_temp1[(w / 2 - xaa):(w / 2 + xaa), (h / 2 - xaa):(h / 2 + xaa)] neww, newh = rotated_and_cropped_temp1.shape # TODO - assumes a single transformation, but there might be more img1_model = models.Transforms.from_tilespec(ts1[img1_ind]["transforms"][0]) img1_center_point = img1_model.apply(np.array([starty + h / 2, startx + w / 2]) / scaling) # + imgoffset1 # Get the images from section 2 around the expected matching location # (img1ind, img2inds) = imgmatches[findindwithinmatches(imgmatches, img1ind)] img2_inds = img_matches[img1_ind] img2s = get_images_from_indices_and_point(ts2, img2_inds, expected_new_center) actual_matches_num += 1 for (img2, img2_ind) in img2s: img2_resized = cv2.resize(img2, (0, 0), fx=scaling/1, fy=scaling/1) # imgoffset2 = get_image_top_left(slice2, img2mfov, img2num, data2) img2_offset = get_image_top_left(ts2, img2_ind) # template1topleft = np.array([startx, starty]) / scaling + imgoffset1 result, reason = PMCC_filter_example.PMCC_match(img2_resized, rotated_and_cropped_temp1, min_correlation=min_corr, maximal_curvature_ratio=max_curvature, maximal_ROD=max_rod) if result is not None: reasonx, reasony = reason # img1topleft = np.array([startx, starty]) / scaling + imgoffset1 # img2topleft = np.array(reason) / scaling + imgoffset2 # TODO - assumes a single transformation, but there might be more img2_model = models.Transforms.from_tilespec(ts2[img2_ind]["transforms"][0]) img2_center_point = img2_model.apply(np.array([reasony + newh / 2, reasonx + neww / 2]) / scaling) # + imgoffset2 point_matches.append((img1_center_point, img2_center_point, not_on_mesh)) if debug_save_matches: debug_out_fname1 = os.path.join(debug_dir, "debug_match_sec1{}-{}_sec2{}-{}_image1.png".format(hexgr[i][0], hexgr[i][1], reasonx, reasony)) debug_out_fname2 = os.path.join(debug_dir, "debug_match_sec1{}-{}_sec2{}-{}_image2.png".format(hexgr[i][0], hexgr[i][1], reasonx, reasony)) cv2.imwrite(debug_out_fname1, rotated_and_cropped_temp1) temp1_final_sizex = rotated_and_cropped_temp1.shape[0] temp1_final_sizey = rotated_and_cropped_temp1.shape[1] img2_cut_out = img2_resized[reasonx:(reasonx + temp1_final_sizex), reasony:(reasony + temp1_final_sizey)] cv2.imwrite(debug_out_fname2, img2_cut_out) ''' temp1finalsizex = rotatedandcroppedtemp1.shape[0] temp1finalsizey = rotatedandcroppedtemp1.shape[1] imgout = np.zeros((1230,630), np.uint8) pikoo = np.array([startx + w / 2, starty + h / 2]) # cv2.circle(img1resized, (int(pikoo[0]), int(pikoo[1])), 15, (0,0,255), -1) imgout[0:545,0:626] = img1resized # cv2.circle(img2resized, (int(reasony + temp1finalsize / 2), int(reasonx + temp1finalsize / 2)), 15, (0,0,255), -1) imgout[545:1090,0:626] = img2resized imgout[1090:(1090 + temp1finalsizex),0:temp1finalsizey] = rotatedandcroppedtemp1 img2cutout = img2resized[reasonx:(reasonx + temp1finalsizex), reasony:(reasony + temp1finalsizey)] imgout[1090:(1090 + temp1finalsizey), (temp1finalsizey + 10):(temp1finalsizex + 10 + temp1finalsizex)] = img2cutout finalimgout = imgout[1090:(1090 + temp1finalsizex), 0:300] cv2.imwrite("/home/raahilsha/billy/ImageComparison#" + str(i) + ".png",finalimgout) ''' print("Found {} matches out of possible {} points (on section points: {})".format(len(point_matches), len(hexgr), actual_matches_num)) # Save the output print("Saving output to: {}".format(out_fname)) out_jsonfile['runtime'] = time.clock() - starttime out_jsonfile['mesh'] = hexgr final_point_matches = [] for pm in point_matches: p1, p2, nmesh = pm record = {} record['point1'] = p1.tolist() record['point2'] = p2.tolist() record['isvirtualpoint'] = nmesh final_point_matches.append(record) out_jsonfile['pointmatches'] = final_point_matches with open(out_fname, 'w') as out: json.dump(out_jsonfile, out, indent=4) print("Done.")