def test_disparity_random_stereogram(): """ Checks the disparity map for random stereogram """ H = 51 W = 51 disparity = 4 im_left, im_right = generate_random_stereogram( im_size=(H, W, 3), disparity=4) block_size = 5 disp_map = calculate_disparity_map( im_left, im_right, block_size, ssd_similarity_measure) # define the limits where we will encounter non-zero disparity maps x_lims = torch.tensor([H//2 - H//4 - block_size//2-1, H//2 + H//4 + block_size//2-1], dtype=torch.long) y_lims = torch.tensor([W//2 - W//4 - block_size//2 - disparity-1, W//2 + W//4 + block_size//2-1], dtype=torch.long) # get the points where disparity map is greater than zero nonzero_idx = torch.nonzero(disp_map) # we will see the effect of stereo outside this region too, depending on the block size falsevals = torch.nonzero(~( (nonzero_idx[:, 0] >= x_lims[0]) & (nonzero_idx[:, 0] <= x_lims[1]) & (nonzero_idx[:, 1] >= y_lims[0]) & (nonzero_idx[:, 1] <= y_lims[1]) )) assert ~falsevals.shape[0]
def test_disparity_map_size(): """ Checks the size of the disparity map """ im_left = torch.randn((15, 15, 1)) im_right = torch.randn_like(im_left) for block_size in (3, 5, 7, 9, 13): disp_map = calculate_disparity_map( im_left, im_right, block_size, ssd_similarity_measure) assert disp_map.size() == (max(0, 15-block_size+1), max(0, 15-block_size+1))
def test_disparity_deltafn_success(): """ Tests the disparity map giving inputs which just have a single pixel value """ im_dim = 51 block_size = 1 im_left, im_right = generate_delta_fn_images((im_dim, im_dim)) # calculate the disparity manually left_idx = torch.argmax(im_left[:, :, 1]).item() left_r = left_idx//im_dim left_c = left_idx - left_r*im_dim right_idx = torch.argmax(im_right[:, :, 1]).item() right_r = right_idx // im_dim right_c = right_idx - right_r*im_dim disparity_expected = left_c - right_c # get the disparity map from the function disp_map = calculate_disparity_map(im_left, im_right, block_size, ssd_similarity_measure, max_search_bound=disparity_expected+3 ) # we should get two non-zero values in the disparity map nonzero_disp = torch.nonzero(disp_map).data print(nonzero_disp) # check the size assert nonzero_disp.size() == (2, 2) # check that the ows are same assert nonzero_disp[0, 0].item() == nonzero_disp[1, 0].item() assert nonzero_disp[0, 1].item() + nonzero_disp[1, 1].item() == left_c + right_c assert abs(nonzero_disp[0, 1].item() - nonzero_disp[1, 1].item()) == abs(left_c - right_c) val1 = disp_map[left_r, left_c].item() val2 = disp_map[right_r, right_c].item() assert val1 == disparity_expected assert val2 == block_size
def test_disparity_translation_shift(): """ Test where we generate the 2nd image by just horizonataly shifting the 1st image """ H, W = (21, 21) shift_val = 4 im1 = torch.randn(H, W, 2) W = W - shift_val im2 = im1[:, shift_val:, :].clone() im1 = im1[:, :-shift_val, :].clone() block_size = 3 disp_map = calculate_disparity_map( im1, im2, block_size, ssd_similarity_measure) assert disp_map.shape[0] == H-2*(block_size//2) assert disp_map.shape[1] == W-2*(block_size//2) assert torch.nonzero(disp_map[:, shift_val+1:] != shift_val).shape[0] == 0
def test_disparity_deltafn_failure(): """ Tests the disparity map giving inputs which just have a single pixel value The bounds for search will be smaller and result in a failure """ im_dim = 51 block_size = 1 im_left, im_right = generate_delta_fn_images((im_dim, im_dim)) # calculate the disparity manually left_idx = torch.argmax(im_left[:, :, 1]).item() left_r = left_idx//im_dim left_c = left_idx - left_r*im_dim right_idx = torch.argmax(im_right[:, :, 1]).item() right_r = right_idx // im_dim right_c = right_idx - right_r*im_dim disparity_expected = left_c - right_c # get the disparity map from the function disp_map = calculate_disparity_map(im_left, im_right, block_size, ssd_similarity_measure, max_search_bound=disparity_expected-1 ) # we should get two non-zero values in the disparity map nonzero_disp = torch.nonzero(disp_map).data print(nonzero_disp) # check the size assert nonzero_disp.size() != (2, 2) val1 = disp_map[left_r, left_c].item() val2 = disp_map[right_r, right_c].item() assert val1 == 0
def stereo_helper_fn(im_left, im_right, block_size=[5, 9, 13], max_search_bound=15): ''' This helper function will help us in calculating disparity maps for different parameters. It also plots the image. Please tune the parameters and see the effect of them for different inputs. Args: - im_left: the left image - im_right: the right image - block_size: list of different block sizes to be used - max_search_bound: the max horizontal displacement to look for the most similar patch (Refer to the project webpage for more details) ''' fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 10)) ax1.imshow(im_left, interpolation=None) ax1.title.set_text('Left image') ax1.autoscale(False) ax1.set_axis_off() ax2.imshow(im_right, interpolation=None) ax2.title.set_text('Right image') ax2.autoscale(False) ax2.set_axis_off() plt.show() # fig, ax = plt.subplots(len(block_size),2, figsize=(15, 10*len(block_size))) for idx, block in enumerate(block_size): fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 20)) # **calculate the disparity maps** # Using SAD similarity function disp_map_sad = calculate_disparity_map( im_left, im_right, block_size=block, sim_measure_function=sad_similarity_measure, max_search_bound=max_search_bound) # Using SSD similarity function disp_map_ssd = calculate_disparity_map( im_left, im_right, block_size=block, sim_measure_function=ssd_similarity_measure, max_search_bound=max_search_bound) im = ax1.imshow(disp_map_sad, cmap='jet') ax1.set_title('Disparity Map - SAD ({}x{} patch)'.format(block, block)) ax1.autoscale(True) ax1.set_axis_off() cbar = fig.colorbar(im, ax=ax1, cmap='jet', shrink=0.3) im = ax2.imshow(disp_map_ssd, cmap='jet') ax2.set_title('Disparity Map - SSD ({}x{} patch)'.format(block, block)) ax2.autoscale(True) ax2.set_axis_off() cbar = fig.colorbar(im, ax=ax2, cmap='jet', shrink=0.3) plt.show()