def updatefig(j): nonlocal rect, rect_ sys.stdout.write('\rFrame: %04d/%04d | FPS: %d | Sequence: [%s]%s' % (j, total_frames, fps, filename, ' ' * 10)) # First frame rect if j == 1: rect, rect_ = init_rect, init_rect # Lucas-Kanade using latest template template = crop(frames[:, :, j - 1], rect) p = LucasKanade(template, frames[:, :, j], rect) rect_temp = (rect.reshape(2, 2) + p).flatten() # Lucas-Kanade using initial template p_star = LucasKanade(init_template, frames[:, :, j], rect_temp, p) rect = (rect.reshape(2, 2) + p_star).flatten() save_rects.append(rect) # Lucas-Kanade wihtout drift correction template_ = crop(frames[:, :, j - 1], rect_) p_ = LucasKanade(template_, frames[:, :, j], rect_) rect_ = (rect_.reshape(2, 2) + p_).flatten() # Update image for display im.set_array(frames[:, :, j]) # Clear patches and draw new boxes for patch in reversed(ax.patches): patch.remove() box = patches.Rectangle((rect[0], rect[1]), rect[2] - rect[0], rect[3] - rect[1], linewidth=2, edgecolor='y', facecolor='none') ax.add_patch(box) box = patches.Rectangle((rect_[0], rect_[1]), rect_[2] - rect_[0], rect_[3] - rect_[1], linewidth=2, edgecolor='g', facecolor='none') ax.add_patch(box) # Save frames if j in [1, 100, 200, 300, 400]: fig.savefig('../writeup/carseqrects-wcrt_%d.png' % j, bbox_inches='tight', pad_inches=0) # Save rects if j == total_frames - 1: # np.save('carseqrects-wcrt', np.asarray(save_rects)) pass return im
def LucasKanadeBasis(It, It1, rect, bases, p0=np.zeros(2), threshold=0.001, iters=20): ''' [input] * It - Template image * It1 - Current image * rect - Current position of the car (top left, bot right coordinates) * bases - [n, m, k] where (n x m) is the size of the template * threshold - Threshold for error convergence (default: 0.001) * iters - Number of iterations for error convergence (default: 20) [output] * p - Movement vector [dp_x, dp_y] ''' # Initial parameters p = p0 bases = bases.reshape(bases.shape[0] * bases.shape[1], bases.shape[2]) # Iterate for i in range(iters): # Step 1 - Warp image warp_img = shift(It1, np.flip(-p)) # Step 2 - Compute error image error_img = It - crop(warp_img, rect) error_img = error_img.flatten() - np.matmul(bases, np.matmul(bases.T, error_img.flatten())) # Step 3 - Compute and warp the gradient gradient = np.dstack(np.gradient(warp_img)[::-1]) gradient = np.dstack([crop(gradient[:, :, 0], rect), crop(gradient[:, :, 1], rect)]) warp_gradient = gradient.reshape(gradient.shape[0] * gradient.shape[1], 2) # Step 4 - Evaluate jacobian jacobian = np.eye(2) # Step 5 - Compute the steepest descent images steepest_descent = np.matmul(warp_gradient, jacobian) steepest_descent = steepest_descent - np.matmul(bases, np.matmul(bases.T, steepest_descent)) # Step 6 - Compute the Hessian matrix hessian = np.matmul(steepest_descent.T, steepest_descent) # Step 7/8 - Compute delta P delta_p = np.matmul(np.linalg.inv(hessian), np.matmul(steepest_descent.T, error_img.flatten())) # Step 9 - Update the parameters p = p + delta_p # Test for convergence if np.linalg.norm(delta_p) <= threshold: break return p
def play(filename): frames = np.load(filename) total_frames = frames.shape[2] fps = 24 # Init figure fig, ax = plt.subplots(1) im = ax.imshow(frames[:, :, 0], animated=True, cmap='gray') # Initial rect init_rect = np.asarray([59, 116, 145, 151]) rect, rect_ = init_rect, init_rect save_rects = [] # Initial template init_template = crop(frames[:, :, 0], init_rect) def updatefig(j): nonlocal rect, rect_ sys.stdout.write('\rFrame: %04d/%04d | FPS: %d | Sequence: [%s]%s' % (j, total_frames, fps, filename, ' ' * 10)) # First frame rect if j == 1: rect, rect_ = init_rect, init_rect # Lucas-Kanade using latest template template = crop(frames[:, :, j - 1], rect) p = LucasKanade(template, frames[:, :, j], rect) rect_temp = (rect.reshape(2, 2) + p).flatten() # Lucas-Kanade using initial template p_star = LucasKanade(init_template, frames[:, :, j], rect_temp, p) rect = (rect.reshape(2, 2) + p_star).flatten() save_rects.append(rect) # Lucas-Kanade wihtout drift correction template_ = crop(frames[:, :, j - 1], rect_) p_ = LucasKanade(template_, frames[:, :, j], rect_) rect_ = (rect_.reshape(2, 2) + p_).flatten() # Update image for display im.set_array(frames[:, :, j]) # Clear patches and draw new boxes for patch in reversed(ax.patches): patch.remove() box = patches.Rectangle((rect[0], rect[1]), rect[2] - rect[0], rect[3] - rect[1], linewidth=2, edgecolor='y', facecolor='none') ax.add_patch(box) box = patches.Rectangle((rect_[0], rect_[1]), rect_[2] - rect_[0], rect_[3] - rect_[1], linewidth=2, edgecolor='g', facecolor='none') ax.add_patch(box) # Save frames if j in [1, 100, 200, 300, 400]: fig.savefig('../writeup/carseqrects-wcrt_%d.png' % j, bbox_inches='tight', pad_inches=0) # Save rects if j == total_frames - 1: # np.save('carseqrects-wcrt', np.asarray(save_rects)) pass return im # Run animation and display window ani = animation.FuncAnimation(fig, updatefig, frames=range(1, total_frames), interval=1000 // fps) plt.show()
gradient = np.dstack(np.gradient(warp_img)[::-1]) gradient = np.dstack([crop(gradient[:, :, 0], rect), crop(gradient[:, :, 1], rect)]) warp_gradient = gradient.reshape(gradient.shape[0] * gradient.shape[1], 2) # Step 4 - Evaluate jacobian jacobian = np.eye(2) # Step 5 - Compute the steepest descent images steepest_descent = np.matmul(warp_gradient, jacobian) steepest_descent = steepest_descent - np.matmul(bases, np.matmul(bases.T, steepest_descent)) # Step 6 - Compute the Hessian matrix hessian = np.matmul(steepest_descent.T, steepest_descent) # Step 7/8 - Compute delta P delta_p = np.matmul(np.linalg.inv(hessian), np.matmul(steepest_descent.T, error_img.flatten())) # Step 9 - Update the parameters p = p + delta_p # Test for convergence if np.linalg.norm(delta_p) <= threshold: break return p if __name__ == '__main__': frames = np.load('../data/sylvseq.npy') bases = np.load('../data/sylvbases.npy') rect = np.asarray([101, 61, 155, 107]) LucasKanadeBasis(crop(frames[:, :, 0], rect), frames[:, :, 1], rect, bases)