def PIV1(I0, I1, winsize, overlap, dt, smooth=True): u0, v0 = pyprocess.extended_search_area_piv(I0.astype(np.int32), I1.astype(np.int32), window_size=winsize, overlap=overlap, dt=dt, search_area_size=winsize) x, y = pyprocess.get_coordinates(image_size=I0.shape, search_area_size=winsize, window_size=winsize, overlap=overlap) if smooth == True: u1 = smoothn(u0)[0] v1 = smoothn(v0)[0] frame_data = pd.DataFrame(data=np.array( [x.flatten(), y.flatten(), u1.flatten(), v1.flatten()]).T, columns=['x', 'y', 'u', 'v']) else: frame_data = pd.DataFrame(data=np.array( [x.flatten(), y.flatten(), u0.flatten(), v0.flatten()]).T, columns=['x', 'y', 'u', 'v']) return frame_data
def process(args, bga, bgb, reflection): file_a, file_b, counter = args # read images into numpy arrays frame_a = tools.imread(file_a) frame_b = tools.imread(file_b) # removing background and reflections frame_a = frame_a - bga frame_b = frame_b - bgb frame_a[reflection == 255] = 0 frame_b[reflection == 255] = 0 #applying a static mask (taking out the regions where we have walls) yp = [580, 435, 0, 0, 580, 580, 0, 0, 435, 580] xp = [570, 570, 680, 780, 780, 0, 0, 105, 230, 230] pnts = draw.polygon(yp, xp, frame_a.shape) frame_a[pnts] = 0 frame_b[pnts] = 0 # checking the resulting frame #fig, ax = plt.subplots(2,2) #ax[0,0].imshow(frame_a_org, cmap='gray') #ax[0,1].imshow(frame_a, cmap='gray') #ax[1,0].imshow(frame_b_org, cmap='gray') #ax[1,1].imshow(frame_b, cmap='gray') #plt.tight_layout() #plt.show() # main piv processing u, v, sig2noise = pyprocess.extended_search_area_piv( frame_a, frame_b, \ window_size=48, overlap=16, dt=0.001094, search_area_size=64, sig2noise_method='peak2peak') x, y = pyprocess.get_coordinates(image_size=frame_a.shape, window_size=48, overlap=16) u, v, mask = validation.local_median_val(u, v, 2000, 2000, size=2) u, v = filters.replace_outliers(u, v, method='localmean', max_iter=10, kernel_size=2) u, *_ = smoothn(u, s=1.0) v, *_ = smoothn(v, s=1.0) # saving the results save_file = tools.create_path(file_a, 'Analysis') tools.save(x, y, u, v, mask, save_file + '.dat')
def ProcessPIV(args, bga, bgb, reflection, stg): # read images into numpy arrays file_a, file_b, counter = args frame_a = tools.imread(file_a) frame_b = tools.imread(file_b) # removing background and reflections if bgb is not None: frame_a = frame_a - bga frame_b = frame_b - bgb frame_a[reflection == 255] = 0 frame_b[reflection == 255] = 0 #plt.imshow(frame_a, cmap='gray') #plt.show() # main piv processing u, v, s2n = pyprocess.extended_search_area_piv( frame_a, frame_b, \ window_size=stg['WS'], overlap=stg['OL'], dt=stg['DT'], search_area_size=stg['SA'], sig2noise_method='peak2peak') x, y = pyprocess.get_coordinates(image_size=frame_a.shape, window_size=stg['WS'], overlap=stg['OL']) if stg['BVR'] == 'on': u, v, mask = validation.local_median_val(u, v, stg['MF'][0], stg['MF'][1], size=2) u, v, mask = validation.global_val(u, v, u_thresholds=stg['GF'][0], v_thresholds=stg['GF'][1]) u, v = filters.replace_outliers(u, v, method='localmean', max_iter=10, kernel_size=2) u, *_ = smoothn(u, s=0.5) v, *_ = smoothn(v, s=0.5) x, y, u, v = scaling.uniform(x, y, u, v, stg['SC']) # saving the results save_file = tools.create_path(file_a, 'Analysis') tools.save(x, y, u, v, s2n, save_file + '.dat')
def smoothn_r(self): """Smoothn postprocessing results.""" result_fnames = [] for i, f in enumerate(self.p['fnames']): data = np.loadtxt(f) u, _, _, _ = piv_smt.smoothn( data[:, 2], s=self.p['smoothn_val'], isrobust=self.p['robust']) v, _, _, _ = piv_smt.smoothn( data[:, 3], s=self.p['smoothn_val'], isrobust=self.p['robust']) save_fname = create_save_vec_fname( path=f, postfix='_smthn') save(data[:, 0], data[:, 1], u, v, data[:, 4], data[:, 5], save_fname, delimiter=self.delimiter) result_fnames.append(save_fname) return result_fnames
def func(args): """A function to process each image pair.""" # this line is REQUIRED for multiprocessing to work # always use it in your custom function file_a, file_b, counter = args # counter2=str(counter2) ##################### # Here goes you code ##################### " read images into numpy arrays" frame_a = imread(os.path.join(settings.filepath_images, file_a)) frame_b = imread(os.path.join(settings.filepath_images, file_b)) # Miguel: I just had a quick look, and I do not understand the reason # for this step. # I propose to remove it. # frame_a = (frame_a*1024).astype(np.int32) # frame_b = (frame_b*1024).astype(np.int32) " crop to ROI" if settings.ROI == "full": frame_a = frame_a frame_b = frame_b else: frame_a = frame_a[settings.ROI[0]:settings.ROI[1], settings.ROI[2]:settings.ROI[3]] frame_b = frame_b[settings.ROI[0]:settings.ROI[1], settings.ROI[2]:settings.ROI[3]] if settings.invert is True: frame_a = invert(frame_a) frame_b = invert(frame_b) if settings.show_all_plots: fig, ax = plt.subplots(1, 1) ax.imshow(frame_a, cmap=plt.get_cmap('Reds')) ax.imshow(frame_b, cmap=plt.get_cmap('Blues'), alpha=.5) plt.show() if settings.dynamic_masking_method in ("edge", "intensity"): frame_a, mask_a = preprocess.dynamic_masking( frame_a, method=settings.dynamic_masking_method, filter_size=settings.dynamic_masking_filter_size, threshold=settings.dynamic_masking_threshold, ) frame_b, mask_b = preprocess.dynamic_masking( frame_b, method=settings.dynamic_masking_method, filter_size=settings.dynamic_masking_filter_size, threshold=settings.dynamic_masking_threshold, ) # "first pass" x, y, u, v, s2n = first_pass(frame_a, frame_b, settings) if settings.show_all_plots: plt.figure() plt.quiver(x, y, u, -v, color='b') # plt.gca().invert_yaxis() # plt.gca().set_aspect(1.) # plt.title('after first pass, invert') # plt.show() # " Image masking " if settings.image_mask: image_mask = np.logical_and(mask_a, mask_b) mask_coords = preprocess.mask_coordinates(image_mask) # mark those points on the grid of PIV inside the mask grid_mask = preprocess.prepare_mask_on_grid(x, y, mask_coords) # mask the velocity u = np.ma.masked_array(u, mask=grid_mask) v = np.ma.masked_array(v, mask=grid_mask) else: mask_coords = [] u = np.ma.masked_array(u, mask=np.ma.nomask) v = np.ma.masked_array(v, mask=np.ma.nomask) if settings.validation_first_pass: u, v, mask = validation.typical_validation(u, v, s2n, settings) if settings.show_all_plots: # plt.figure() plt.quiver(x, y, u, -v, color='r') plt.gca().invert_yaxis() plt.gca().set_aspect(1.) plt.title('after first pass validation new, inverted') plt.show() # "filter to replace the values that where marked by the validation" if settings.num_iterations == 1 and settings.replace_vectors: # for multi-pass we cannot have holes in the data # after the first pass u, v = filters.replace_outliers( u, v, method=settings.filter_method, max_iter=settings.max_filter_iteration, kernel_size=settings.filter_kernel_size, ) # don't even check if it's true or false elif settings.num_iterations > 1: u, v = filters.replace_outliers( u, v, method=settings.filter_method, max_iter=settings.max_filter_iteration, kernel_size=settings.filter_kernel_size, ) # "adding masks to add the effect of all the validations" if settings.smoothn: u, dummy_u1, dummy_u2, dummy_u3 = smoothn.smoothn( u, s=settings.smoothn_p) v, dummy_v1, dummy_v2, dummy_v3 = smoothn.smoothn( v, s=settings.smoothn_p) if settings.image_mask: grid_mask = preprocess.prepare_mask_on_grid(x, y, mask_coords) u = np.ma.masked_array(u, mask=grid_mask) v = np.ma.masked_array(v, mask=grid_mask) else: u = np.ma.masked_array(u, np.ma.nomask) v = np.ma.masked_array(v, np.ma.nomask) if settings.show_all_plots: plt.figure() plt.quiver(x, y, u, -v) plt.gca().invert_yaxis() plt.gca().set_aspect(1.) plt.title('before multi pass, inverted') plt.show() if not isinstance(u, np.ma.MaskedArray): raise ValueError("Expected masked array") """ Multi pass """ for i in range(1, settings.num_iterations): if not isinstance(u, np.ma.MaskedArray): raise ValueError("Expected masked array") x, y, u, v, s2n, mask = multipass_img_deform( frame_a, frame_b, i, x, y, u, v, settings, mask_coords=mask_coords) # If the smoothing is active, we do it at each pass # but not the last one if settings.smoothn is True and i < settings.num_iterations - 1: u, dummy_u1, dummy_u2, dummy_u3 = smoothn.smoothn( u, s=settings.smoothn_p) v, dummy_v1, dummy_v2, dummy_v3 = smoothn.smoothn( v, s=settings.smoothn_p) if not isinstance(u, np.ma.MaskedArray): raise ValueError('not a masked array anymore') if hasattr(settings, 'image_mask') and settings.image_mask: grid_mask = preprocess.prepare_mask_on_grid(x, y, mask_coords) u = np.ma.masked_array(u, mask=grid_mask) v = np.ma.masked_array(v, mask=grid_mask) else: u = np.ma.masked_array(u, np.ma.nomask) v = np.ma.masked_array(v, np.ma.nomask) if settings.show_all_plots: plt.figure() plt.quiver(x, y, u, -1 * v, color='r') plt.gca().set_aspect(1.) plt.gca().invert_yaxis() plt.title('end of the multipass, invert') plt.show() if settings.show_all_plots and settings.num_iterations > 1: plt.figure() plt.quiver(x, y, u, -v) plt.gca().invert_yaxis() plt.gca().set_aspect(1.) plt.title('after multi pass, before saving, inverted') plt.show() # we now use only 0s instead of the image # masked regions. # we could do Nan, not sure what is best u = u.filled(0.) v = v.filled(0.) # "scales the results pixel-> meter" x, y, u, v = scaling.uniform(x, y, u, v, scaling_factor=settings.scaling_factor) if settings.image_mask: grid_mask = preprocess.prepare_mask_on_grid(x, y, mask_coords) u = np.ma.masked_array(u, mask=grid_mask) v = np.ma.masked_array(v, mask=grid_mask) else: u = np.ma.masked_array(u, np.ma.nomask) v = np.ma.masked_array(v, np.ma.nomask) # before saving we conver to the "physically relevant" # right-hand coordinate system with 0,0 at the bottom left # x to the right, y upwards # and so u,v x, y, u, v = transform_coordinates(x, y, u, v) # import pdb; pdb.set_trace() # "save to a file" tools.save(x, y, u, v, mask, os.path.join(save_path, "field_A%03d.txt" % counter), delimiter="\t") # "some other stuff that one might want to use" if settings.show_plot or settings.save_plot: Name = os.path.join(save_path, "Image_A%03d.png" % counter) fig, _ = display_vector_field( os.path.join(save_path, "field_A%03d.txt" % counter), scale=settings.scale_plot, ) if settings.save_plot is True: fig.savefig(Name) if settings.show_plot is True: plt.show() print(f"Image Pair {counter + 1}") print(file_a.rsplit('/')[-1], file_b.rsplit('/')[-1])
def func(args): """A function to process each image pair.""" # this line is REQUIRED for multiprocessing to work # always use it in your custom function file_a, file_b, counter = args # counter2=str(counter2) ##################### # Here goes you code ##################### ' read images into numpy arrays' frame_a = tools.imread(os.path.join(settings.filepath_images, file_a)) frame_b = tools.imread(os.path.join(settings.filepath_images, file_b)) ## Miguel: I just had a quick look, and I do not understand the reason for this step. # I propose to remove it. #frame_a = (frame_a*1024).astype(np.int32) #frame_b = (frame_b*1024).astype(np.int32) ' crop to ROI' if settings.ROI == 'full': frame_a = frame_a frame_b = frame_b else: frame_a = frame_a[settings.ROI[0]:settings.ROI[1], settings.ROI[2]:settings.ROI[3]] frame_b = frame_b[settings.ROI[0]:settings.ROI[1], settings.ROI[2]:settings.ROI[3]] if settings.dynamic_masking_method == 'edge' or 'intensity': frame_a = preprocess.dynamic_masking( frame_a, method=settings.dynamic_masking_method, filter_size=settings.dynamic_masking_filter_size, threshold=settings.dynamic_masking_threshold) frame_b = preprocess.dynamic_masking( frame_b, method=settings.dynamic_masking_method, filter_size=settings.dynamic_masking_filter_size, threshold=settings.dynamic_masking_threshold) '''%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%''' 'first pass' x, y, u, v, sig2noise_ratio = first_pass( frame_a, frame_b, settings.windowsizes[0], settings.overlap[0], settings.iterations, correlation_method=settings.correlation_method, subpixel_method=settings.subpixel_method, do_sig2noise=settings.extract_sig2noise, sig2noise_method=settings.sig2noise_method, sig2noise_mask=settings.sig2noise_mask, ) 'validation using gloabl limits and std and local median' '''MinMaxU : two elements tuple sets the limits of the u displacment component Used for validation. MinMaxV : two elements tuple sets the limits of the v displacment component Used for validation. std_threshold : float sets the threshold for the std validation median_threshold : float sets the threshold for the median validation filter_method : string the method used to replace the non-valid vectors Methods: 'localmean', 'disk', 'distance', max_filter_iteration : int maximum of filter iterations to replace nans filter_kernel_size : int size of the kernel used for the filtering''' mask = np.full_like(x, False) if settings.validation_first_pass == True: u, v, mask_g = validation.global_val(u, v, settings.MinMax_U_disp, settings.MinMax_V_disp) u, v, mask_s = validation.global_std( u, v, std_threshold=settings.std_threshold) u, v, mask_m = validation.local_median_val( u, v, u_threshold=settings.median_threshold, v_threshold=settings.median_threshold, size=settings.median_size) if settings.extract_sig2noise == True and settings.iterations == 1 and settings.do_sig2noise_validation == True: u, v, mask_s2n = validation.sig2noise_val( u, v, sig2noise_ratio, threshold=settings.sig2noise_threshold) mask = mask + mask_g + mask_m + mask_s + mask_s2n else: mask = mask + mask_g + mask_m + mask_s 'filter to replace the values that where marked by the validation' if settings.iterations > 1: u, v = filters.replace_outliers( u, v, method=settings.filter_method, max_iter=settings.max_filter_iteration, kernel_size=settings.filter_kernel_size) 'adding masks to add the effect of all the validations' if settings.smoothn == True: u, dummy_u1, dummy_u2, dummy_u3 = smoothn.smoothn( u, s=settings.smoothn_p) v, dummy_v1, dummy_v2, dummy_v3 = smoothn.smoothn( v, s=settings.smoothn_p) elif settings.iterations == 1 and settings.replace_vectors == True: u, v = filters.replace_outliers( u, v, method=settings.filter_method, max_iter=settings.max_filter_iteration, kernel_size=settings.filter_kernel_size) 'adding masks to add the effect of all the validations' if settings.smoothn == True: u, v = filters.replace_outliers( u, v, method=settings.filter_method, max_iter=settings.max_filter_iteration, kernel_size=settings.filter_kernel_size) u, dummy_u1, dummy_u2, dummy_u3 = smoothn.smoothn( u, s=settings.smoothn_p) v, dummy_v1, dummy_v2, dummy_v3 = smoothn.smoothn( v, s=settings.smoothn_p) i = 1 'all the following passes' for i in range(2, settings.iterations + 1): x, y, u, v, sig2noise_ratio, mask = multipass_img_deform( frame_a, frame_b, settings.windowsizes[i - 1], settings.overlap[i - 1], settings.iterations, i, x, y, u, v, correlation_method=settings.correlation_method, subpixel_method=settings.subpixel_method, do_sig2noise=settings.extract_sig2noise, sig2noise_method=settings.sig2noise_method, sig2noise_mask=settings.sig2noise_mask, MinMaxU=settings.MinMax_U_disp, MinMaxV=settings.MinMax_V_disp, std_threshold=settings.std_threshold, median_threshold=settings.median_threshold, median_size=settings.median_size, filter_method=settings.filter_method, max_filter_iteration=settings.max_filter_iteration, filter_kernel_size=settings.filter_kernel_size, interpolation_order=settings.interpolation_order) # If the smoothing is active, we do it at each pass if settings.smoothn == True: u, dummy_u1, dummy_u2, dummy_u3 = smoothn.smoothn( u, s=settings.smoothn_p) v, dummy_v1, dummy_v2, dummy_v3 = smoothn.smoothn( v, s=settings.smoothn_p) '''%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%''' if settings.extract_sig2noise == True and i == settings.iterations and settings.iterations != 1 and settings.do_sig2noise_validation == True: u, v, mask_s2n = validation.sig2noise_val( u, v, sig2noise_ratio, threshold=settings.sig2noise_threshold) mask = mask + mask_s2n if settings.replace_vectors == True: u, v = filters.replace_outliers( u, v, method=settings.filter_method, max_iter=settings.max_filter_iteration, kernel_size=settings.filter_kernel_size) 'pixel/frame->pixel/sec' u = u / settings.dt v = v / settings.dt 'scales the results pixel-> meter' x, y, u, v = scaling.uniform(x, y, u, v, scaling_factor=settings.scaling_factor) 'save to a file' save(x, y, u, v, sig2noise_ratio, mask, os.path.join(save_path, 'field_A%03d.txt' % counter), delimiter='\t') 'some messages to check if it is still alive' 'some other stuff that one might want to use' if settings.show_plot == True or settings.save_plot == True: plt.close('all') plt.ioff() Name = os.path.join(save_path, 'Image_A%03d.png' % counter) display_vector_field(os.path.join(save_path, 'field_A%03d.txt' % counter), scale=settings.scale_plot) if settings.save_plot == True: plt.savefig(Name) if settings.show_plot == True: plt.show() print('Image Pair ' + str(counter + 1))
def func(args): file_a, file_b, counter = args # read the iamges frame_a = tools.imread(os.path.join(settings.filepath_images, file_a)) frame_b = tools.imread(os.path.join(settings.filepath_images, file_b)) if counter == settings.fall_start: settings.ROI[1] = frame_a.shape[0] """Here we check if the interface has reached the top of the roi yet by comparing it to the index in the observation_periods file. If it has not reached the roi yet we skip this part, if it did then we shift the roi for each pair after the initial one """ if counter >= settings.roi_shift_start: # set the roi to the image height for the first frame # if counter == settings.roi_shift_start : # settings.current_pos = 0 # shift the roi for each pair (this is not done for the first one) settings.ROI[0] = int(settings.current_pos) # crop to roi if settings.ROI == 'full': frame_a = frame_a frame_b = frame_b else: frame_a = frame_a[settings.ROI[0]:settings.ROI[1], settings.ROI[2]:settings.ROI[3]] frame_b = frame_b[settings.ROI[0]:settings.ROI[1], settings.ROI[2]:settings.ROI[3]] if settings.dynamic_masking_method == 'edge' or settings.dynamic_masking_method == 'intensity': frame_a = preprocess.dynamic_masking( frame_a, method=settings.dynamic_masking_method, filter_size=settings.dynamic_masking_filter_size, threshold=settings.dynamic_masking_threshold) frame_b = preprocess.dynamic_masking( frame_b, method=settings.dynamic_masking_method, filter_size=settings.dynamic_masking_filter_size, threshold=settings.dynamic_masking_threshold) #%% """ Here we do the first pass of the piv interrogation """ x, y, u, v, sig2noise_ratio = first_pass( frame_a, frame_b, settings.window_width[0], settings.window_height[0], settings.overlap_width[0], settings.overlap_height[0], settings.iterations, correlation_method=settings.correlation_method, subpixel_method=settings.subpixel_method, do_sig2noise=settings.extract_sig2noise, sig2noise_method=settings.sig2noise_method, sig2noise_mask=settings.sig2noise_mask, ) mask = np.full_like(x, False) if settings.validation_first_pass == True: u, v, mask_g = validation.global_val(u, v, settings.MinMax_U_disp, settings.MinMax_V_disp) u, v, mask_s = validation.global_std( u, v, std_threshold=settings.std_threshold) u, v, mask_m = validation.local_median_val( u, v, u_threshold=settings.median_threshold, v_threshold=settings.median_threshold, size=settings.median_size) if settings.extract_sig2noise == True and settings.iterations == 1 and settings.do_sig2noise_validation == True: u, v, mask_s2n = validation.sig2noise_val( u, v, sig2noise_ratio, threshold=settings.sig2noise_threshold) mask = mask + mask_g + mask_m + mask_s + mask_s2n else: mask = mask + mask_g + mask_m + mask_s 'filter to replace the values that where marked by the validation' if settings.iterations > 1: u, v = filters.replace_outliers( u, v, method=settings.filter_method, max_iter=settings.max_filter_iteration, kernel_size=settings.filter_kernel_size) 'adding masks to add the effect of all the validations' if settings.smoothn == True: u, dummy_u1, dummy_u2, dummy_u3 = smoothn.smoothn( u, s=settings.smoothn_p) v, dummy_v1, dummy_v2, dummy_v3 = smoothn.smoothn( v, s=settings.smoothn_p) elif settings.iterations == 1 and settings.replace_vectors == True: u, v = filters.replace_outliers( u, v, method=settings.filter_method, max_iter=settings.max_filter_iteration, kernel_size=settings.filter_kernel_size) 'adding masks to add the effect of all the validations' if settings.smoothn == True: u, v = filters.replace_outliers( u, v, method=settings.filter_method, max_iter=settings.max_filter_iteration, kernel_size=settings.filter_kernel_size) u, dummy_u1, dummy_u2, dummy_u3 = smoothn.smoothn( u, s=settings.smoothn_p) v, dummy_v1, dummy_v2, dummy_v3 = smoothn.smoothn( v, s=settings.smoothn_p) #%% i = 1 """ Do the multipass until the maximum iterations are reached """ for i in range(2, settings.iterations + 1): x, y, u, v, sig2noise_ratio, mask = multipass_img_deform( frame_a, frame_b, settings.window_width[i - 1], settings.window_height[i - 1], settings.overlap_width[i - 1], settings.overlap_height[i - 1], settings.iterations, i, x, y, u, v, correlation_method=settings.correlation_method, subpixel_method=settings.subpixel_method, do_sig2noise=settings.extract_sig2noise, sig2noise_method=settings.sig2noise_method, sig2noise_mask=settings.sig2noise_mask, MinMaxU=settings.MinMax_U_disp, MinMaxV=settings.MinMax_V_disp, std_threshold=settings.std_threshold, median_threshold=settings.median_threshold, median_size=settings.median_size, filter_method=settings.filter_method, max_filter_iteration=settings.max_filter_iteration, filter_kernel_size=settings.filter_kernel_size, interpolation_order=settings.interpolation_order) # smooth on each pass in case this is wanted if settings.smoothn == True: u, dummy_u1, dummy_u2, dummy_u3 = smoothn.smoothn( u, s=settings.smoothn_p) v, dummy_v1, dummy_v2, dummy_v3 = smoothn.smoothn( v, s=settings.smoothn_p) # extract the sig2noise ratio in case it is desired and replace the vectors if settings.extract_sig2noise == True and i == settings.iterations and settings.iterations != 1 and settings.do_sig2noise_validation == True: u, v, mask_s2n = validation_patch.sig2noise_val( u, v, sig2noise_ratio, threshold_low=settings.sig2noise_threshold) mask = mask + mask_s2n if settings.replace_vectors == True: u, v = filters.replace_outliers( u, v, method=settings.filter_method, max_iter=settings.max_filter_iteration, kernel_size=settings.filter_kernel_size) if counter >= settings.roi_shift_start: settings.current_pos = settings.current_pos - calc_disp( x, v, frame_b.shape[1]) if ((settings.ROI[1] - settings.current_pos) < 300): return settings.current_pos, True # scale the result timewise and lengthwise u = u / settings.dt v = v / settings.dt x, y, u, v = scaling.uniform(x, y, u, v, scaling_factor=settings.scaling_factor) # save the result save(x, y, u, v, sig2noise_ratio, mask, os.path.join(save_path_txts, 'field_%06d.txt' % (counter)), delimiter='\t') # disable the grid in the rcParams file plt.rcParams['axes.grid'] = False # show and save the plot if it is desired if settings.show_plot == True or settings.save_plot == True: plt.ioff() Name = os.path.join(save_path_images, 'Image_%06d.png' % (counter)) display_vector_field(os.path.join(save_path_txts, 'field_%06d.txt' % (counter)), scale=settings.scale_plot) if settings.save_plot == True: plt.savefig(Name, dpi=100) if settings.show_plot == True: plt.show() plt.close('all') print('Image Pair ' + str(counter) + ' of ' + settings.save_folder_suffix) if settings.current_pos == np.nan: return settings.current_pos, True return settings.current_pos, False
# In[35]: quick_quiver() # In[36]: # Smoothing after the first pass settings.smoothn=True #Enables smoothing of the displacemenet field settings.smoothn_p=0.5 # This is a smoothing parameter u, dummy_u1, dummy_u2, dummy_u3 = smoothn.smoothn( u, s=settings.smoothn_p ) v, dummy_v1, dummy_v2, dummy_v3 = smoothn.smoothn( v, s=settings.smoothn_p ) # mask the velocity maps tmp = np.zeros_like(x,dtype=bool) tmp.flat[xymask] = 1 u = np.ma.masked_array(u, mask = tmp) v = np.ma.masked_array(v, mask = tmp) # In[37]:
def smoothn(u, s): s = s u, _, _, _ = piv_smt.smoothn(u, s=s, isrobust=self.p['robust']) return (u)
def vacf(self, mode="direct", smooth_method="gaussian", smooth_window=3, xlim=None, plot=False): """Compute averaged vacf from PIV data. This is a wrapper of function autocorr1d(), adding the averaging over all the velocity spots. Args: mode -- the averaging method, can be "direct" or "weighted". "weighted" will use mean velocity as the averaging weight, whereas "direct" uses 1. smooth_window -- window size for gaussian smoothing in time xlim -- xlim for plotting the VACF, does not affect the return value Returns: corrData -- DataFrame of (t, corrx, corry) Edit: Mar 23, 2022 -- add smoothn smoothing option """ # rearrange vstack from (f, h, w) to (f, h*w), then transpose corr_components = [] for name, stack in zip(["corrx", "corry"], self.stack): stack_r = stack.reshape((stack.shape[0], -1)).T stack_r = stack_r[~np.isnan(stack_r).any(axis=1)] if smooth_method == "gaussian": stack_r = scipy.ndimage.gaussian_filter( stack_r, (0, smooth_window / 4)) elif smooth_method == "smoothn": stack_r = smoothn(stack_r, axis=1)[0] # compute autocorrelation corr_list = [] weight = 1 normalizer = 0 for x in stack_r: if np.isnan( x[0] ) == False: # masked out part has velocity as nan, which cannot be used for correlation computation if mode == "weighted": weight = abs(x).mean() corr = autocorr1d(x) * weight if np.isnan(corr.sum()) == False: normalizer += weight corr_list.append(corr) corr_mean = np.nansum(np.stack(corr_list, axis=0), axis=0) / normalizer corr_components.append( pd.DataFrame({ "c": corr_mean, "t": np.arange(len(corr_mean)) * self.dt }).set_index("t").rename(columns={"c": name})) ac = pd.concat(corr_components, axis=1) # plot autocorrelation functions if plot == True: fig, ax = plt.subplots(figsize=(3.5, 3), dpi=100) ax.plot(ac.index, ac.corrx, label="$C_x$") ax.plot(ac.index, ac.corry, label="$C_y$") ax.plot(ac.index, ac.mean(axis=1), label="mean", color="black") ax.set_xlabel("time (s)") ax.set_ylabel("VACF") ax.legend(frameon=False) ax.set_xlim([0, ac.index.max()]) if xlim is not None: ax.set_xlim(xlim) return ac