def test_multi_pass_circ(): """ test fot the multipass """ settings.windowsizes = (64, 64, 16) settings.overlap = (32, 32, 8) settings.num_iterations = 2 settings.interpolation_order = 3 settings.validation_first_pass = True settings.sig2noise_validate = False # ettings.show_all_plots = True x, y, u, v, s2n = windef.first_pass( frame_a, frame_b, settings, ) print("first pass\n") print("\n", x, y, u, v, s2n) assert np.allclose(u, shift_u, atol = threshold) assert np.allclose(v, shift_v, atol = threshold) 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) for i in range(1,settings.num_iterations): x, y, u, v, s2n, _ = windef.multipass_img_deform( frame_a, frame_b, i, x, y, u, v, settings ) print(f"Pass {i}\n") print(x) print(y) print(u) print(v) print(s2n) assert np.mean(np.abs(u - shift_u)) < threshold assert np.mean(np.abs(v - shift_v)) < threshold
def test_multi_pass_circ(): """ test fot the multipass """ window_size = (128, 64, 32) overlap = (64, 32, 16) iterations = 3 frame_a = np.zeros((1024, 1024)) frame_a = random_noise(frame_a) with warnings.catch_warnings(): warnings.simplefilter("ignore") frame_a = img_as_ubyte(frame_a) frame_b = np.roll(np.roll(frame_a, 3, axis=1), 2, axis=0) x, y, u, v, sig2noise_ratio = windef.first_pass( frame_a, frame_b, window_size[0], overlap[0], iterations, correlation_method='circular', subpixel_method='gaussian', do_sig2noise=True, sig2noise_method='peak2peak', sig2noise_mask=2) u_old = u v_old = v i = 1 for i in range(2, iterations + 1): x, y, u, v, sig2noise_ratio, mask = windef.multipass_img_deform( frame_a, frame_b, window_size[i - 1], overlap[i - 1], iterations, i, x, y, u, v, correlation_method='circular', subpixel_method='gaussian', do_sig2noise=False, sig2noise_method='peak2peak', sig2noise_mask=2, MinMaxU=(-100, 50), MinMaxV=(-50, 50), std_threshold=1000000, median_threshold=200000, median_size=1, filter_method='localmean', max_filter_iteration=10, filter_kernel_size=2, interpolation_order=3) assert (np.max(np.abs(u - 3)) < 0.1 and np.any(u != u_old)) assert (np.max(np.abs(v - 2)) < 0.1 and np.any(v != v_old))
def test_multi_pass_lin(): """ test fot the multipass """ window_size = (128, 64, 32) overlap = (64, 32, 16) iterations = 3 x, y, u, v, s2n = windef.first_pass(frame_a, frame_b, window_size[0], overlap[0], iterations, correlation_method='linear', subpixel_method='gaussian', do_sig2noise=True, sig2noise_method='peak2peak', sig2noise_mask=2) u_old = u.copy() v_old = v.copy() i = 1 for i in range(2, iterations + 1): x, y,\ u, v,\ sn, m = windef.multipass_img_deform(frame_a, frame_b, window_size[i-1], overlap[i-1], iterations, i, x, y, u, v, correlation_method='linear', subpixel_method='gaussian', do_sig2noise=False, sig2noise_method='peak2peak', sig2noise_mask=2, MinMaxU=(-100, 50), MinMaxV=(-50, 50), std_threshold=1000000, median_threshold=200000, median_size=1, filter_method='localmean', max_filter_iteration=10, filter_kernel_size=2, interpolation_order=3) assert (np.max(np.abs(u - 3)) < 0.1 and np.any(u != u_old)) assert (np.max(np.abs(v + 2)) < 0.1 and np.any(v != v_old))
def test_multi_pass_lin(): """ test fot the multipass """ settings.windowsizes = (64, 32, 16) settings.overlap = (32, 16, 8) settings.num_iterations = 1 settings.sig2noise_validate = True settings.correlation_method = 'linear' settings.normalized_correlation = True settings.sig2noise_threshold = 1.0 # note the value for linear/normalized x, y, u, v, s2n = windef.first_pass( frame_a, frame_b, settings, ) print("\n", x, y, u, v, s2n) assert np.mean(np.abs(u - shift_u)) < threshold assert np.mean(np.abs(v - shift_v)) < threshold mask_coords = [] u = np.ma.masked_array(u, mask=np.ma.nomask) v = np.ma.masked_array(v, mask=np.ma.nomask) for i in range(1, settings.num_iterations): x, y, u, v, s2n, _ = windef.multipass_img_deform( frame_a, frame_b, i, x, y, u, v, settings, ) print(f"Iteration {i}") print("\n", x, y, u, v, s2n) assert np.allclose(u, shift_u, atol=threshold) assert np.allclose(v, shift_v, atol=threshold)
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 ' 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)) ' 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 = windef.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: #print('Hello I am running') u,dummy_u1,dummy_u2,dummy_u3=smoothn(u,s=settings.smoothn_p) v,dummy_v1,dummy_v2,dummy_v3=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: #print('Hello I am running') 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(u,s=settings.smoothn_p) v,dummy_v1,dummy_v2,dummy_v3=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 = windef.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: #print('Hello I am running') u,dummy_u1,dummy_u2,dummy_u3=smoothn(u,s=settings.smoothn_p) v,dummy_v1,dummy_v2,dummy_v3=smoothn(v,s=settings.smoothn_p) # if settings.smoothn==True # u,dummy_u1,dummy_u2,dummy_u3=smoothn(u,s=settings.smoothn_p) # v,dummy_v1,dummy_v2,dummy_v3=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' tools_patch.save_windef(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') fig, ax = tools_patch.display_vector_field_windef(os.path.join(save_path, 'field_A%03d.txt' % counter), scaling_factor=settings.scale_plot) Name = os.path.join(save_path, 'Image_A%03d.png' % (counter-1)) #Name = os.path.join(save_path, settings.field_name) if settings.save_plot==True: fig.savefig(Name, dpi=100) if settings.show_plot==True: plt.show() print('Image Pair ' + str(counter))
# In[38]: for i in range(1, settings.iterations): ## all other passes x, y, u, v, sig2noise_ratio = windef.multipass_img_deform( frame_a, frame_b, settings.windowsizes[i], settings.overlap[i], settings.iterations, i, x, y, u, v, correlation_method=settings.correlation_method, subpixel_method=settings.subpixel_method, deformation_method=settings.deformation_method, do_sig2noise=settings.extract_sig2noise, sig2noise_method=settings.sig2noise_method, sig2noise_mask=settings.sig2noise_mask, interpolation_order=settings.interpolation_order, normalized_correlation=settings.normalized_correlation, mask_coords=mask_coords, ) mask = u.mask # Now we can first validate, filter out, interpolate # and then smooth the data for this pass:
def process(self, args): """ Process chain as configured in the GUI. Parameters ---------- args : tuple Tuple as expected by the inherited run method: file_a (str) -- image file a file_b (str) -- image file b counter (int) -- index pointing to an element of the filename list """ file_a, file_b, counter = args frame_a = piv_tls.imread(file_a) frame_b = piv_tls.imread(file_b) # Smoothning script borrowed from openpiv.windef s = self.p['smoothn_val'] def smoothn(u, s): s = s u, _, _, _ = piv_smt.smoothn(u, s=s, isrobust=self.p['robust']) return (u) # delimiters placed here for safety delimiter = self.p['separator'] if delimiter == 'tab': delimiter = '\t' if delimiter == 'space': delimiter = ' ' # preprocessing print('\nPre-pocessing image pair: {}'.format(counter + 1)) if self.p['background_subtract'] \ and self.p['background_type'] == 'minA - minB': self.background = gen_background(self.p, frame_a, frame_b) frame_a = frame_a.astype(np.int32) frame_a = process_images(self, frame_a, self.GUI.preprocessing_methods, background=self.background) frame_b = frame_b.astype(np.int32) frame_b = process_images(self, frame_b, self.GUI.preprocessing_methods, background=self.background) print('Evaluating image pair: {}'.format(counter + 1)) # evaluation first pass start = time.time() passes = 1 # setup custom windowing if selected if self.parameter['custom_windowing']: corr_window_0 = self.parameter['corr_window_1'] overlap_0 = self.parameter['overlap_1'] for i in range(2, 8): if self.parameter['pass_%1d' % i]: passes += 1 else: break else: passes = self.parameter['coarse_factor'] if self.parameter['grid_refinement'] == 'all passes' \ and self.parameter['coarse_factor'] != 1: corr_window_0 = self.parameter['corr_window'] * \ 2**(self.parameter['coarse_factor'] - 1) overlap_0 = self.parameter['overlap'] * \ 2**(self.parameter['coarse_factor'] - 1) # Refine all passes after first when there are more than 1 pass. elif self.parameter['grid_refinement'] == '2nd pass on' \ and self.parameter['coarse_factor'] != 1: corr_window_0 = self.parameter['corr_window'] * \ 2**(self.parameter['coarse_factor'] - 2) overlap_0 = self.parameter['overlap'] * \ 2**(self.parameter['coarse_factor'] - 2) # If >>none<< is selected or something goes wrong, the window # size would remain the same. else: corr_window_0 = self.parameter['corr_window'] overlap_0 = self.parameter['overlap'] overlap_percent = overlap_0 / corr_window_0 sizeX = corr_window_0 u, v, sig2noise = piv_wdf.extended_search_area_piv( frame_a.astype(np.int32), frame_b.astype(np.int32), window_size=corr_window_0, overlap=overlap_0, search_area_size=corr_window_0, width=self.parameter['s2n_mask'], subpixel_method=self.parameter['subpixel_method'], sig2noise_method=self.parameter['sig2noise_method'], correlation_method=self.parameter['corr_method'], normalized_correlation=self.parameter['normalize_correlation']) x, y = piv_prc.get_coordinates(frame_a.shape, corr_window_0, overlap_0) # validating first pass mask = np.full_like(x, 0) if self.parameter['fp_vld_global_threshold']: u, v, Mask = piv_vld.global_val( u, v, u_thresholds=(self.parameter['fp_MinU'], self.parameter['fp_MaxU']), v_thresholds=(self.parameter['fp_MinV'], self.parameter['fp_MaxV'])) # consolidate effects of mask mask += Mask if self.parameter['fp_local_med']: u, v, Mask = piv_vld.local_median_val( u, v, u_threshold=self.parameter['fp_local_med'], v_threshold=self.parameter['fp_local_med'], size=self.parameter['fp_local_med_size']) mask += Mask if self.parameter['adv_repl']: u, v = piv_flt.replace_outliers( u, v, method=self.parameter['adv_repl_method'], max_iter=self.parameter['adv_repl_iter'], kernel_size=self.parameter['adv_repl_kernel']) print('Validated first pass result of image pair: {}.'.format(counter + 1)) # smoothning before deformation if 'each pass' is selected if self.parameter['smoothn_each_pass']: if self.parameter['smoothn_first_more']: s *= 2 u = smoothn(u, s) v = smoothn(v, s) print('Smoothned pass 1 for image pair: {}.'.format(counter + 1)) s = self.parameter['smoothn_val1'] print('Finished pass 1 for image pair: {}.'.format(counter + 1)) print("window size: " + str(corr_window_0)) print('overlap: ' + str(overlap_0), '\n') # evaluation of all other passes if passes != 1: iterations = passes - 1 for i in range(2, passes + 1): # setting up the windowing of each pass if self.parameter['custom_windowing']: corr_window = self.parameter['corr_window_%1d' % i] overlap = int(corr_window * overlap_percent) else: if self.parameter['grid_refinement'] == 'all passes' or \ self.parameter['grid_refinement'] == '2nd pass on': corr_window = self.parameter['corr_window'] * \ 2**(iterations - 1) overlap = self.parameter['overlap'] * \ 2**(iterations - 1) else: corr_window = self.parameter['corr_window'] overlap = self.parameter['overlap'] sizeX = corr_window # translate settings to windef settings object piv_wdf_settings = piv_wdf.Settings() piv_wdf_settings.correlation_method = \ self.parameter['corr_method'] piv_wdf_settings.normalized_correlation = \ self.parameter['normalize_correlation'] piv_wdf_settings.windowsizes = (corr_window, ) * (passes + 1) piv_wdf_settings.overlap = (overlap, ) * (passes + 1) piv_wdf_settings.num_iterations = passes piv_wdf_settings.subpixel_method = \ self.parameter['subpixel_method'] piv_wdf_settings.deformation_method = \ self.parameter['deformation_method'] piv_wdf_settings.interpolation_order = \ self.parameter['interpolation_order'] piv_wdf_settings.sig2noise_validate = True, piv_wdf_settings.sig2noise_method = \ self.parameter['sig2noise_method'] piv_wdf_settings.sig2noise_mask = self.parameter['s2n_mask'] # do the correlation x, y, u, v, sig2noise, mask = piv_wdf.multipass_img_deform( frame_a.astype(np.int32), frame_b.astype(np.int32), i, # current iteration x, y, u, v, piv_wdf_settings) # validate other passes if self.parameter['sp_vld_global_threshold']: u, v, Mask = piv_vld.global_val( u, v, u_thresholds=(self.parameter['sp_MinU'], self.parameter['sp_MaxU']), v_thresholds=(self.parameter['sp_MinV'], self.parameter['sp_MaxV'])) mask += Mask # consolidate effects of mask if self.parameter['sp_vld_global_threshold']: u, v, Mask = piv_vld.global_std( u, v, std_threshold=self.parameter['sp_std_threshold']) mask += Mask if self.parameter['sp_local_med_validation']: u, v, Mask = piv_vld.local_median_val( u, v, u_threshold=self.parameter['sp_local_med'], v_threshold=self.parameter['sp_local_med'], size=self.parameter['sp_local_med_size']) mask += Mask if self.parameter['adv_repl']: u, v = piv_flt.replace_outliers( u, v, method=self.parameter['adv_repl_method'], max_iter=self.parameter['adv_repl_iter'], kernel_size=self.parameter['adv_repl_kernel']) print('Validated pass {} of image pair: {}.'.format( i, counter + 1)) # smoothning each individual pass if 'each pass' is selected if self.parameter['smoothn_each_pass']: u = smoothn(u, s) v = smoothn(v, s) print('Smoothned pass {} for image pair: {}.'.format( i, counter + 1)) print('Finished pass {} for image pair: {}.'.format( i, counter + 1)) print("window size: " + str(corr_window)) print('overlap: ' + str(overlap), '\n') iterations -= 1 if self.p['flip_u']: u = np.flipud(u) if self.p['flip_v']: v = np.flipud(v) if self.p['invert_u']: u *= -1 if self.p['invert_v']: v *= -1 # scaling u = u / self.parameter['dt'] v = v / self.parameter['dt'] x, y, u, v = piv_scl.uniform(x, y, u, v, scaling_factor=self.parameter['scale']) end = time.time() # save data to file. out = np.vstack([m.ravel() for m in [x, y, u, v, mask, sig2noise]]) np.savetxt(self.save_fnames[counter], out.T, fmt='%8.4f', delimiter=delimiter) print('Processed image pair: {}'.format(counter + 1)) sizeY = sizeX sizeX = ((int(frame_a.shape[0] - sizeX) // (sizeX - (sizeX * overlap_percent))) + 1) sizeY = ((int(frame_a.shape[1] - sizeY) // (sizeY - (sizeY * overlap_percent))) + 1) time_per_vec = _round((((end - start) * 1000) / ((sizeX * sizeY) - 1)), 3) print('Process time: {} second(s)'.format((_round((end - start), 3)))) print('Number of vectors: {}'.format(int((sizeX * sizeY) - 1))) print('Time per vector: {} millisecond(s)'.format(time_per_vec))