def matches(im1, im2, matches, dist=None, options={}): """ show a figure with lines joining the accepted matches in im1 and im2 input: im1,im2 (images as arrays), locs1,locs2 (location of features), matchscores (as output from 'match'). """ scale = options.get("scale", 1) filename = options.get("filename", None) max_dist = options.get("max_dist", 100) line_width = options.get("line_width", 0.8) size = options.get("size", (12, 8)) separation = options.get("separation", 20) if scale != 1: s = numpy.array([scale, scale]) im1_size = numpy.array(im1.shape[1::-1] * s, dtype=numpy.uint16) im2_size = numpy.array(im2.shape[1::-1] * s, dtype=numpy.uint16) if scale < 0.5: im1_scaled = imaging.get_thumbnail(im1, size=im1_size) im2_scaled = imaging.get_thumbnail(im2, size=im2_size) else: im1_scaled = imaging.open_img(im1, size=im1_size) im2_scaled = imaging.open_img(im2, size=im2_size) im3 = append_images(im1_scaled, im2_scaled, separation) matches = [(m[0] * s, m[1] * s) for m in matches] else: im3 = append_images(im1, im2, separation) im1_scaled = im1 # Create figure fig = pylab.figure(frameon=False, figsize=size) ax = pylab.Axes(fig, [0., 0., 1., 1.]) ax.set_axis_off() fig.add_axes(ax) # Display image ax.imshow(im3) # Get colors if dist != None and len(dist) == len(matches): cs = [ getRedGreen(numpy.log(d + 1) / numpy.log(max_dist)) for d in dist ] else: cs = ['#00aaff' for m in matches] # Plot all lines offset_x = im1_scaled.shape[1] for i, ((x1, y1), (x2, y2)) in enumerate(matches): ax.plot([x1, x2 + offset_x + separation], [y1, y2], color=cs[i], lw=line_width) pylab.xlim(0, im3.shape[1]) pylab.ylim(im3.shape[0], 0) if filename != None: fig.savefig(filename, bbox_inches='tight', dpi=72)
def visualize_log(log, im1, im2, stop_at=None, scale=None, size=(14, 8)): # Prepare images if scale == None: scale = min(1.0, 600 / float(im1.shape[1])) s = numpy.array([scale, scale]) im1_size = numpy.array(im1.shape[1::-1] * s, dtype=numpy.uint16) im2_size = numpy.array(im2.shape[1::-1] * s, dtype=numpy.uint16) im1_scaled = imaging.get_thumbnail(im1, size=im1_size) im2_scaled = imaging.get_thumbnail(im2, size=im2_size) separation = 20 offset_x = im1_size[0] + separation im3 = append_images(im1_scaled, im2_scaled, separation) def translate_point(point, image="im1"): x, y = numpy.array(point) * s if image == "im1": return x, y else: return (x + offset_x, y) # Create figure fig = pylab.figure(frameon=False, figsize=size) ax = pylab.Axes(fig, [0., 0., 1., 1.]) ax.set_axis_off() fig.add_axes(ax) # Display image ax.imshow(im3) # Plot log data for i, d in enumerate(log): # Enough? if stop_at != None and i > stop_at: break # Plot target grid ((x_min, x_max), (y_min, y_max)) = d["target_grid"] margin = d["margin"] # Add square ax.add_patch( pylab.Rectangle(translate_point((x_min + margin, y_min + margin), "im2"), (x_max - x_min - 2 * margin) * scale, (y_max - y_min - 2 * margin) * scale, fill=False)) # Add circle ax.add_patch( pylab.Circle(translate_point(d["query_pos"], "im1"), d["radius"] * scale, fill=False, linewidth=0.5)) # Add matches for pos_q, pos_t in d["matches"]: x1, x2 = numpy.array([pos_q[0], pos_t[0]]) * s y1, y2 = numpy.array([pos_q[1], pos_t[1]]) * s ax.plot([x1, x2 + offset_x], [y1, y2], color="#2595e3", lw=1) # Limit figure to area around im3 pylab.xlim(0, im3.shape[1]) pylab.ylim(im3.shape[0], 0)
def matches(im1, im2, matches, dist = None, options = {}) : """ show a figure with lines joining the accepted matches in im1 and im2 input: im1,im2 (images as arrays), locs1,locs2 (location of features), matchscores (as output from 'match'). """ scale = options.get("scale", 1) filename = options.get("filename", None) max_dist = options.get("max_dist", 100) line_width = options.get("line_width", 0.8) size = options.get("size", (12, 8)) separation = options.get("separation", 20) if scale != 1 : s = numpy.array([scale, scale]) im1_size = numpy.array(im1.shape[1::-1] * s, dtype=numpy.uint16) im2_size = numpy.array(im2.shape[1::-1] * s, dtype=numpy.uint16) if scale < 0.5 : im1_scaled = imaging.get_thumbnail(im1, size = im1_size) im2_scaled = imaging.get_thumbnail(im2, size = im2_size) else : im1_scaled = imaging.open_img(im1, size = im1_size) im2_scaled = imaging.open_img(im2, size = im2_size) im3 = append_images(im1_scaled, im2_scaled, separation) matches = [(m[0] * s, m[1] * s) for m in matches] else : im3 = append_images(im1,im2, separation) im1_scaled = im1 # Create figure fig = pylab.figure(frameon=False, figsize=size) ax = pylab.Axes(fig, [0., 0., 1., 1.]) ax.set_axis_off() fig.add_axes(ax) # Display image ax.imshow(im3) # Get colors if dist != None and len(dist) == len(matches) : cs = [getRedGreen(numpy.log(d+1)/numpy.log(max_dist)) for d in dist] else : cs = ['#00aaff' for m in matches] # Plot all lines offset_x = im1_scaled.shape[1] for i,((x1,y1),(x2,y2)) in enumerate(matches) : ax.plot([x1, x2+offset_x + separation], [y1,y2], color=cs[i], lw=line_width) pylab.xlim(0,im3.shape[1]) pylab.ylim(im3.shape[0],0) if filename != None : fig.savefig(filename, bbox_inches='tight', dpi=72)
def visualize_log(log, im1, im2, stop_at = None, scale = None, size = (14, 8)) : # Prepare images if scale == None : scale = min(1.0, 600 / float(im1.shape[1])) s = numpy.array([scale, scale]) im1_size = numpy.array(im1.shape[1::-1] * s, dtype=numpy.uint16) im2_size = numpy.array(im2.shape[1::-1] * s, dtype=numpy.uint16) im1_scaled = imaging.get_thumbnail(im1, size = im1_size) im2_scaled = imaging.get_thumbnail(im2, size = im2_size) separation = 20 offset_x = im1_size[0] + separation im3 = append_images(im1_scaled, im2_scaled, separation) def translate_point(point, image = "im1") : x, y = numpy.array(point) * s if image == "im1" : return x, y else : return (x + offset_x, y) # Create figure fig = pylab.figure(frameon=False, figsize=size) ax = pylab.Axes(fig, [0., 0., 1., 1.]) ax.set_axis_off() fig.add_axes(ax) # Display image ax.imshow(im3) # Plot log data for i, d in enumerate(log) : # Enough? if stop_at != None and i > stop_at : break # Plot target grid ((x_min, x_max), (y_min, y_max)) = d["target_grid"] margin = d["margin"] # Add square ax.add_patch(pylab.Rectangle( translate_point((x_min + margin, y_min + margin), "im2"), (x_max-x_min - 2*margin) * scale, (y_max-y_min - 2*margin) * scale, fill = False)) # Add circle ax.add_patch(pylab.Circle( translate_point(d["query_pos"], "im1"), d["radius"] * scale, fill = False, linewidth = 0.5)) # Add matches for pos_q, pos_t in d["matches"] : x1, x2 = numpy.array([pos_q[0], pos_t[0]]) * s y1, y2 = numpy.array([pos_q[1], pos_t[1]]) * s ax.plot([x1, x2+offset_x], [y1,y2], color="#2595e3", lw=1) # Limit figure to area around im3 pylab.xlim(0,im3.shape[1]) pylab.ylim(im3.shape[0],0)
def match_thumbs(img, cache, thumb_size = (400, 400)) : # Load target and find descriptors and size target = get_thumbnail(img, thumb_size) t_orig_size = get_size(img) get_features(target) t_keypoints, t_descriptors = get_features(target) # Similar for query q_descriptors = cache.thumb["descriptors"] q_distances = cache.thumb["distances"] q_pos = cache.thumb["positions"] # match thumbnails and find ratio matcher = cv2.BFMatcher(cv2.NORM_L2, crossCheck=True) matches = [m for m in matcher.knnMatch(q_descriptors, t_descriptors, k=1) if len(m) > 0] ratios = numpy.array([m[0].distance / q_distances[m[0].queryIdx] for m in matches]) # Get positions of points and their scaling factor t_pos = [t_keypoints[m[0].trainIdx].pt for m in matches] t_ratio_x = t_orig_size[0]/float(target.shape[1]) t_ratio_y = t_orig_size[1]/float(target.shape[0]) t_ratio = numpy.array([t_ratio_x, t_ratio_y]) q_pos = numpy.array([cache.thumb["positions"][m[0].queryIdx] for m in matches]) q_ratio_x = cache.original["size"][0]/float(cache.thumb["size"][0]) q_ratio_y = cache.original["size"][1]/float(cache.thumb["size"][1]) q_ratio = numpy.array([q_ratio_x, q_ratio_y]) # Sort ratios and scale positions indices = numpy.argsort(ratios) pos_scaled = numpy.array([(q_p * q_ratio, t_p * t_ratio) for q_p, t_p in zip(q_pos, t_pos)]) return pos_scaled[indices], ratios[indices]
def create_thumbnail(self, path, max_size): """ Get relevant data for thumbnail """ # Create thumbnail thumbnail = imaging.get_thumbnail(path, max_size) # Get thumbnail features keypoints, descriptors = matchutil.get_features(thumbnail) # Get nearest neighbor within image (vector with touples of feature points and distances) matches = matchutil.bf_match(descriptors, descriptors, k=2) # Distances to nearest neighbor and positions nn_distances = [r[1].distance for r in matches] positions = [k.pt for k in keypoints] # Collect data self.thumb = { "descriptors": descriptors, "positions": positions, "distances": nn_distances, "size": thumbnail.shape }
def create_thumbnail(self, path, max_size) : """ Get relevant data for thumbnail """ # Create thumbnail thumbnail = imaging.get_thumbnail(path, max_size) # Get thumbnail features keypoints, descriptors = matchutil.get_features(thumbnail) # Get nearest neighbor within image (vector with touples of feature points and distances) matches = matchutil.bf_match(descriptors, descriptors, k = 2) # Distances to nearest neighbor and positions nn_distances = [r[1].distance for r in matches] positions = [k.pt for k in keypoints] # Collect data self.thumb = { "descriptors" : descriptors, "positions" : positions, "distances" : nn_distances, "size" : thumbnail.shape }
def match_thumbs(img, cache, thumb_size=(400, 400)): # Load target and find descriptors and size target = get_thumbnail(img, thumb_size) t_orig_size = get_size(img) get_features(target) t_keypoints, t_descriptors = get_features(target) # Similar for query q_descriptors = cache.thumb["descriptors"] q_distances = cache.thumb["distances"] q_pos = cache.thumb["positions"] # match thumbnails and find ratio matcher = cv2.BFMatcher(cv2.NORM_L2, crossCheck=True) matches = [ m for m in matcher.knnMatch(q_descriptors, t_descriptors, k=1) if len(m) > 0 ] ratios = numpy.array( [m[0].distance / q_distances[m[0].queryIdx] for m in matches]) # Get positions of points and their scaling factor t_pos = [t_keypoints[m[0].trainIdx].pt for m in matches] t_ratio_x = t_orig_size[0] / float(target.shape[1]) t_ratio_y = t_orig_size[1] / float(target.shape[0]) t_ratio = numpy.array([t_ratio_x, t_ratio_y]) q_pos = numpy.array( [cache.thumb["positions"][m[0].queryIdx] for m in matches]) q_ratio_x = cache.original["size"][0] / float(cache.thumb["size"][0]) q_ratio_y = cache.original["size"][1] / float(cache.thumb["size"][1]) q_ratio = numpy.array([q_ratio_x, q_ratio_y]) # Sort ratios and scale positions indices = numpy.argsort(ratios) pos_scaled = numpy.array([(q_p * q_ratio, t_p * t_ratio) for q_p, t_p in zip(q_pos, t_pos)]) return pos_scaled[indices], ratios[indices]