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 ##################### # Here goes you code ##################### # read images into numpy arrays frame_a = tools.imread(os.path.join(path, file_a)) frame_b = tools.imread(os.path.join(path, file_b)) frame_a = (frame_a * 1024).astype(np.int32) frame_b = (frame_b * 1024).astype(np.int32) # process image pair with extended search area piv algorithm. u, v, sig2noise = pyprocess.extended_search_area_piv( frame_a, frame_b, \ window_size=64, overlap=32, dt=0.02, search_area_size=128, sig2noise_method='peak2peak') u, v, mask = validation.sig2noise_val(u, v, sig2noise, threshold=1.5) u, v = filters.replace_outliers(u, v, method='localmean', max_iter=10, kernel_size=2) # get window centers coordinates x, y = pyprocess.get_coordinates(image_size=frame_a.shape, search_area_size=128, overlap=32) # save to a file tools.save(x, y, u, v, mask, 'test2_%03d.txt' % counter) tools.display_vector_field('test2_%03d.txt' % counter)
def openpiv_default_run(im1, im2): """ default settings for OpenPIV analysis using extended_search_area_piv algorithm for two images Inputs: im1,im2 : str,str = path of two image """ frame_a = tools.imread(im1) frame_b = tools.imread(im2) u, v, sig2noise = process.extended_search_area_piv( frame_a.astype(np.int32), frame_b.astype(np.int32), window_size=32, overlap=8, dt=1, search_area_size=64, sig2noise_method='peak2peak') x, y = process.get_coordinates(image_size=frame_a.shape, window_size=32, overlap=8) u, v, mask = validation.sig2noise_val(u, v, sig2noise, threshold=1.3) u, v = filters.replace_outliers(u, v, method='localmean', max_iter=10, kernel_size=2) x, y, u, v = scaling.uniform(x, y, u, v, scaling_factor=1) tools.save(x, y, u, v, mask, list_of_images[0] + '.txt') fig, ax = tools.display_vector_field(list_of_images[0] + '.txt', on_img=True, image_name=list_of_images[0], scaling_factor=1, ax=None)
def gen_min_background(img_list, resize=255): """ Generate a background by averaging the minimum intensity of all images in an image list. Apply by subtracting generated background image. Parameters ---------- img_list: list list of image directories resize: int or float disabled by default, normalize array and set value to user selected max pixel intensity Returns ------- img: image a mean of all images """ background = imread(img_list[0]) if resize != None: background = normalize_array(background) * resize for img in img_list: if img == img_list: # the original image is already included, so skip it in the for loop pass else: img = imread(img) if resize != None: img = normalize_array(img) * resize background = np.min(np.array([background, img]), axis=0) return (background)
def gen_lowpass_background(img_list, sigma=3, resize=None): """ Generate a background by averaging a low pass of all images in an image list. Apply by subtracting generated background image. Parameters ---------- img_list: list list of image directories sigma: float sigma of the gaussian filter resize: int or float disabled by default, normalize array and set value to user selected max pixel intensity Returns ------- img: image a mean of all low-passed images """ for img_file in img_list: if resize != None: img = normalize_array(imread(img_file)) * resize else: img = imread(img_file) img = gaussian_filter(img, sigma=sigma) if img_file == img_list[0]: background = img else: background += img return (background / len(img_list))
def process_node(i): DeltaFrame = 1 winsize = 50 # pixels searchsize = 50 #pixels overlap = 25 # piexels dt = DeltaFrame * 1. / fps # piexels frame_a = tools.imread(fileNameList[i]) frame_b = tools.imread(fileNameList[i + DeltaFrame]) u0, v0, sig2noise = process.extended_search_area_piv( frame_a.astype(np.int32), frame_b.astype(np.int32), window_size=winsize, overlap=overlap, dt=dt, search_area_size=searchsize, sig2noise_method='peak2peak') x, y = process.get_coordinates(image_size=frame_a.shape, window_size=winsize, overlap=overlap) u1, v1, mask = validation.sig2noise_val(u0, v0, sig2noise, threshold=1.3) u2, v2 = filters.replace_outliers(u1, v1, method='localmean', max_iter=5, kernel_size=5) tools.save(x, y, u2, v2, mask, '../muscle10fpsbotleft_results/' + str(i) + '.txt')
def test_display_vector_field(file_a=_file_a, file_b=_file_b, test_file=_test_file): a = imread(file_a) b = imread(file_b) window_size = 32 overlap = 16 search_area_size = 40 u, v, s2n = extended_search_area_piv(a, b, window_size, search_area_size=search_area_size, overlap=overlap, correlation_method='circular', normalized_correlation=False) x, y = get_coordinates(a.shape, search_area_size=search_area_size, overlap=overlap) x, y, u, v = transform_coordinates(x, y, u, v) mask = np.zeros_like(x) mask[-1,1] = 1 # test of invalid vector plot save(x, y, u, v, mask, 'tmp.txt') fig, ax = plt.subplots(figsize=(6, 6)) display_vector_field('tmp.txt', on_img=True, image_name=file_a, ax=ax) decorators.remove_ticks_and_titles(fig) fig.savefig('./tmp.png') res = compare.compare_images('./tmp.png', test_file, 0.001) assert res is None
def piv_example(): """ PIV example uses examples/test5 vortex PIV data to show the main principles piv(im1,im2) will create a tmp.vec file with the vector filed in pix/dt (dt=1) from two images, im1,im2 provided as full path filenames (TIF is preferable) """ # if im1 is None and im2 is None: im1 = pkg.resource_filename("openpiv", "examples/test5/frame_a.tif") im2 = pkg.resource_filename("openpiv", "examples/test5/frame_b.tif") frame_a = tools.imread(im1) frame_b = tools.imread(im2) frame_a[0:32, 512 - 32:] = 255 images = [] images.extend([frame_a, frame_b]) fig, ax = plt.subplots() # ims is a list of lists, each row is a list of artists to draw in the # current frame; here we are just animating one artist, the image, in # each frame ims = [] for i in range(2): im = ax.imshow(images[i % 2], animated=True, cmap=plt.cm.gray) ims.append([im]) _ = animation.ArtistAnimation(fig, ims, interval=500, blit=False, repeat_delay=0) plt.show() # import os vel = pyprocess.extended_search_area_piv(frame_a.astype(np.int32), frame_b.astype(np.int32), window_size=32, search_area_size=64, overlap=8) x, y = pyprocess.get_coordinates(image_size=frame_a.shape, search_area_size=64, overlap=8) fig, ax = plt.subplots(1, 2, figsize=(11, 8)) ax[0].imshow(frame_a, cmap=plt.get_cmap("gray"), alpha=0.8) ax[0].quiver(x, y, vel[0], -vel[1], scale=50, color="r") ax[1].quiver(x, y[::-1, :], vel[0], -vel[1], scale=50, color="b") ax[1].set_aspect(1) # ax[1].invert_yaxis() plt.show() return x, y, vel[0], vel[1]
def gen_background(self, image1=None, image2=None): self.p = self images = self.p['fnames'][self.p['starting_frame']:self.p['ending_frame']] # This needs more testing. It creates artifacts in the correlation # for images not selected in the background. if self.p['background_type'] == 'global min': background = piv_tls.imread(self.p['fnames'][self.p['starting_frame']]) maximum = background.max() background = background / maximum background *= 255 for im in images: # the original image is already included, so skip it in the # for loop if im == self.p['fnames'][self.p['starting_frame']]: pass else: image = piv_tls.imread(im) maximum = image.max() image = image / maximum image *= 255 background = np.min(np.array([background, image]), axis=0) return background elif self.p['background_type'] == 'global mean': images = self.p['fnames'][self.p['starting_frame']:self. p['ending_frame']] background = piv_tls.imread(self.p['fnames'][self.p['starting_frame']]) maximum = background.max() background = background / maximum background *= 255 for im in images: # the original image is already included, so skip it in the # for loop if im == self.p['fnames'][self.p['starting_frame']]: pass else: image = piv_tls.imread(im) maximum = image.max() image = image / maximum image *= 255 background += image background /= (self.p['ending_frame'] - self.p['starting_frame']) return background elif self.p['background_type'] == 'minA - minB': # normalize image1 and image2 intensities to [0,255] maximum1 = image1.max() maximum2 = image2.max() image1 = image1 / maximum1 image2 = image2 / maximum2 image1 *= 255 image2 *= 255 background = np.min(np.array([image2, image1]), axis=0) return background else: print('Background algorithm not implemented.')
def two_images(image_1, image_2, search_area_size=64, window_size=32, overlap=16, dt=0.02): with open("image_1.bmp", "wb") as fh1: fh1.write(base64.b64decode(image_1)) with open("image_2.bmp", "wb") as fh2: fh2.write(base64.b64decode(image_2)) frame_a = tools.imread( 'image_1.bmp' ) frame_b = tools.imread( 'image_2.bmp' ) frame_a = (frame_a*1024).astype(np.int32) frame_b = (frame_b*1024).astype(np.int32) if not search_area_size: search_area_size = 64 if not window_size: window_size = 32 if not overlap: overlap = 16 if not dt: dt = 0.02 u, v, sig2noise = process.extended_search_area_piv( frame_a, frame_b, window_size=window_size, overlap=overlap, dt=dt, search_area_size=search_area_size, sig2noise_method='peak2peak' ) x, y = process.get_coordinates( image_size=frame_a.shape, window_size=window_size, overlap=overlap ) u, v, mask = validation.sig2noise_val( u, v, sig2noise, threshold = 1.3 ) u, v, mask = validation.global_val( u, v, (-1000, 2000), (-1000, 1000) ) u, v = filters.replace_outliers( u, v, method='localmean', max_iter=10, kernel_size=2) x, y, u, v = scaling.uniform(x, y, u, v, scaling_factor = 96.52 ) file_name_text = 'result.txt' file_name_png = 'result.png' if os.path.isfile(file_name_text): os.remove(file_name_text) if os.path.isfile(file_name_png): os.remove(file_name_png) tools.save(x, y, u, v, mask, file_name_text) a = np.loadtxt(file_name_text) fig = plt.figure() invalid = a[:,4].astype('bool') fig.canvas.set_window_title('Vector field, '+str(np.count_nonzero(invalid))+' wrong vectors') valid = ~invalid plt.quiver(a[invalid,0],a[invalid,1],a[invalid,2],a[invalid,3],color='r',scale=100, width=0.0025) plt.quiver(a[valid,0],a[valid,1],a[valid,2],a[valid,3],color='b',scale=100, width=0.0025) plt.draw() plt.savefig(file_name_png, format="png") with open(file_name_text, "rb") as resultFileText: file_reader_text = resultFileText.read() text_encode = base64.encodestring(file_reader_text) base64_string_text = str(text_encode, 'utf-8') with open(file_name_png, "rb") as resultFilePng: file_reader_image = resultFilePng.read() image_encode = base64.encodestring(file_reader_image) base64_string_image = str(image_encode, 'utf-8') return base64_string_text, base64_string_image
def test_load(): """ Unit testing of correct loading of the image """ _ = imread('./test1/exp1_001_b.bmp') assert _[0, 0] == 8 im2 = imread('./test1/exp1_001_c.bmp') assert im2.shape == (369, 511) # at least one failing test try: _ = imread('test1/non_existing_image.bmp') except FileNotFoundError: print('correct testing of a non existing file')
def add_image(self, image_path, bit): self.bit = bit if self.bit == "8 bit": self.piv_images_list.append([ image_path, QtCore.QFileInfo(image_path).fileName(), np.uint8(tools.imread(image_path)), None, None ]) else: self.piv_images_list.append([ image_path, QtCore.QFileInfo(image_path).fileName(), np.uint16(tools.imread(image_path)), None, None ])
def show_img(self, fname): """ Display an image. Parameters ---------- fname : str Pathname of an image file. """ img = piv_tls.imread(fname) print('\nimage data type: {}'.format(img.dtype)) print('max count: {}'.format(img.max())) print('min count {}:'.format(img.min())) if 'int' not in str(img.dtype): print('Warning: For PIV processing, ' + 'image will be normalized and converted to uint8. ' + 'This may cause a loss of precision.') print('Processing image.') img = img.astype(np.int32) # generate background if needed if self.p['background_subtract'] and \ self.p['background_type'] != 'minA - minB': background = gen_background(self.p) elif self.p['background_subtract'] and \ self.p['background_type'] == 'minA - minB': if fname == self.p['fnames'][-1]: img2 = self.p['fnames'][-2] img2 = piv_tls.imread(img2) background = gen_background(self.p, img2, img) else: img2 = self.p['fnames'][self.index + 1] img2 = piv_tls.imread(img2) background = gen_background(self.p, img, img2) else: background = None # preprocessing method became parameter due to the AddInHandler img = process_images(self, img, self.preprocessing_methods, background=background) img = img.astype(np.int32) print('Processed image.') print('max count: {}'.format(img.max())) print('min count {}:'.format(img.min())) self.fig.add_subplot(111).matshow(img, cmap=plt.cm.Greys_r, vmax=self.p['matplot_intensity']) self.fig.canvas.draw()
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 two_images(image_1, image_2): with open("image_1.bmp", "wb") as fh1: fh1.write(base64.b64decode(image_1)) with open("image_2.bmp", "wb") as fh2: fh2.write(base64.b64decode(image_2)) frame_a = tools.imread('image_1.bmp') frame_b = tools.imread('image_2.bmp') winsize = 32 # pixels searchsize = 64 # pixels, search in image B overlap = 12 # pixels dt = 0.02 # sec u, v, sig2noise = pyprocess.piv(frame_a.astype(np.int32), frame_b.astype(np.int32), window_size=winsize, overlap=overlap, dt=dt, search_size=searchsize, sig2noise_method='peak2peak') x, y = pyprocess.get_coordinates(image_size=frame_a.shape, window_size=searchsize, overlap=overlap) u, v, mask = validation.sig2noise_val(u, v, sig2noise, threshold=1.3) u, v = filters.replace_outliers(u, v, method='localmean', max_iter=10, kernel_size=2) x, y, u, v = scaling.uniform(x, y, u, v, scaling_factor=96.52) file_name = 'result.txt' if os.path.isfile(file_name): os.remove(file_name) tools.save(x, y, u, v, np.zeros_like(u), file_name) # no masking, all values are valid with open(file_name, "rb") as resultFile: file_reader = resultFile.read() image_encode = base64.encodestring(file_reader) base64_string = str(image_encode, 'utf-8') return base64_string
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 two_images(image_1, image_2): local_dir = os.path.dirname(os.path.realpath(__file__)) newFile_1 = open('teting1.bmp', 'w+b') newFileByteArray = bytes(image_1) newFile_1.write(newFileByteArray) newFile_1.close() frame_a = tools.imread(local_dir + '/exp1_001_a.bmp') frame_b = tools.imread(local_dir + '/exp1_001_b.bmp') fig, ax = plt.subplots(1, 2, figsize=(10, 8)) ax[0].imshow(frame_a, cmap=plt.cm.gray) ax[1].imshow(frame_b, cmap=plt.cm.gray) winsize = 32 # pixels searchsize = 64 # pixels, search in image B overlap = 12 # pixels dt = 0.02 # sec u, v, sig2noise = pyprocess.extended_search_area_piv( frame_a.astype(np.int32), frame_b.astype(np.int32), window_size=winsize, overlap=overlap, dt=dt, search_area_size=searchsize, sig2noise_method='peak2peak') x, y = pyprocess.get_coordinates(image_size=frame_a.shape, window_size=searchsize, overlap=overlap) file_name = 'result.txt' # tools.save(x, y, u, v, np.zeros_like(u), 'exp1_001.txt' ) # no masking, all values are valid tools.save(x, y, u, v, np.zeros_like(u), file_name) # no masking, all values are valid with open(file_name, 'r') as result_file: data = result_file.read().replace('\n', '').replace('\t', ' ') return data
def simple_piv(im1, im2, plot=True): """ Simplest PIV run on the pair of images using default settings piv(im1,im2) will create a tmp.vec file with the vector filed in pix/dt (dt=1) from two images, im1,im2 provided as full path filenames (TIF is preferable, whatever imageio can read) """ if isinstance(im1, str): im1 = tools.imread(im1) im2 = tools.imread(im2) u, v, s2n = pyprocess.extended_search_area_piv(im1.astype(np.int32), im2.astype(np.int32), window_size=32, overlap=16, search_area_size=32) x, y = pyprocess.get_coordinates(image_size=im1.shape, search_area_size=32, overlap=16) valid = s2n > np.percentile(s2n, 5) if plot: _, ax = plt.subplots(figsize=(6, 6)) ax.imshow(im1, cmap=plt.get_cmap("gray"), alpha=0.5, origin="upper") ax.quiver(x[valid], y[valid], u[valid], -v[valid], scale=70, color='r', width=.005) plt.show() return x, y, u, v
def run_single(index, scale=1, src_dir=None, save_dir=None): frame_a = tools.imread(os.path.join(src_dir, f'{index:06}.tif')) frame_b = tools.imread(os.path.join(src_dir, f'{index + 1:06}.tif')) # no background removal will be performed so 'mask' is initialized to 1 everywhere mask = np.ones(frame_a.shape, dtype=np.int32) # main algorithm with warnings.catch_warnings(): warnings.simplefilter("ignore") x, y, u, v, mask = process.WiDIM(frame_a.astype(np.int32), frame_b.astype(np.int32), mask, min_window_size=MIN_WINDOW_SIZE, overlap_ratio=0.0, coarse_factor=2, dt=DT, validation_method='mean_velocity', trust_1st_iter=1, validation_iter=1, tolerance=0.4, nb_iter_max=3, sig2noise_method='peak2peak') x, y, u, v = scaling.uniform(x, y, u, v, scaling_factor=SCALING_FACTOR) tmp_fname = '.tmp_' + ''.join(random.choices(string.ascii_uppercase + string.digits, k=32)) tools.save(x, y, u, v, mask, filename=tmp_fname) tools.display_vector_field(tmp_fname, scale=scale, width=LINE_WIDTH) # scale: vector length ratio; width: line width of vector arrows os.remove(tmp_fname) # plt.quiver(x, y, u3, v3, color='blue') if save_dir is not None: save_path = os.path.join(save_dir, f'{index:06}.pdf') print(save_path) plt.savefig(save_path)
def process(args): file_a, file_b, counter = args # read images into numpy arrays frame_a = tools.imread(file_a) frame_b = tools.imread(file_b) print(counter + 1) # process image pair with piv algorithm. u, v, sig2noise = pyprocess.extended_search_area_piv( frame_a, frame_b, \ window_size=32, overlap=16, dt=0.0015, search_area_size=32, sig2noise_method='peak2peak') x, y = pyprocess.get_coordinates(image_size=frame_a.shape, window_size=32, overlap=16) u, v, mask1 = validation.sig2noise_val(u, v, sig2noise, threshold=1.0) u, v, mask2 = validation.global_val(u, v, (-2000, 2000), (-2000, 4000)) u, v, mask3 = validation.local_median_val(u, v, 400, 400, size=2) #u, v, mask4 = validation.global_std(u, v, std_threshold=3) mask = mask1 | mask2 | mask3 #u, v = filters.replace_outliers( u, v, method='localmean', max_iter=10, kernel_size=2) save_file = tools.create_path(file_a, 'Analysis') tools.save(x, y, u, v, mask, save_file + '.dat')
def TestRun(): # setting up the process settings stg = {} stg['WS'] = 64 stg['OL'] = 32 stg['SA'] = 80 stg['SC'] = 1 stg['BR'] = 'on' stg['BVR'] = 'off' stg['DT'] = 0.001094 stg['DP'] = os.path.join('E:\\repos\\FlowVisLab\\Images', 'raw_001094_25') stg['MF'] = [8000, 15000] stg['GF'] = [(-10000, 10000), (-1000, 20000)] #bg = ProcessHandler(stg) bg = tools.imread(os.path.join(stg['DP'], 'avg.jpg')) # plot results files = os.path.join(stg['DP'], f'Analysis/frame0008.dat') fig, q, label = DrawPIVPlot(files, stg['SC'], bg) return fig
def update(winsize, overlap, s2n, s2n_method): u, v, sig2noise = process.extended_search_area_piv( frame_a.astype(np.int32), frame_b.astype(np.int32), window_size=winsize, overlap=overlap, dt=1.0, search_area_size=64, sig2noise_method=s2n_method) x, y = process.get_coordinates(image_size=frame_a.shape, window_size=winsize, overlap=overlap) u, v, mask = validation.sig2noise_val(u, v, sig2noise, threshold=s2n) # u, v = filters.replace_outliers( u, v, method='localmean', max_iter=10, kernel_size=2) # x, y, u, v = scaling.uniform(x, y, u, v, scaling_factor = 1.0 ) # tools.save(x, y, u, v, mask, 'tutorial-part3.txt' ) fig, ax = plt.subplots() ax.imshow(tools.imread('20110919 exp3 x10 stream 488570.TIF'), cmap=plt.cm.gray, origin='upper') ax.quiver(x, np.flipud(y), u / 10., v / 10., scale=10, color='r', lw=3) plt.show()
def ProcessHandler(stg): # setting up the path and grabbing the files analysis_path = tools.create_directory(stg['DP']) task = tools.Multiprocesser(data_dir=stg['DP'], pattern_a='frame*.jpg') # finding background and reflections in the images if stg['BR'] == 'on': print('preprocessing:') bg_a, bg_b = task.find_background(50, 10, 6) reflection = tools.mark_reflection(180, task.files_a) #tools.imsave(os.path.join(stg['DP'], 'Analysis/reflection.jpg'), reflection) else: bg_a, bg_b, reflection = tools.imread( os.path.join(stg['DP'], 'avg.jpg')), None, None #tools.imsave(os.path.join(stg['DP'], 'Analysis/background.jpg'), bg_a) # start processing data print('main process:\nprocessing images...') #task.n_files = 6 main_process = partial(ProcessPIV, bga=bg_a, bgb=bg_b, reflection=reflection, stg=stg) task.run(func=main_process, n_cpus=6) print('- done processing') ''' fig, ax = plt.subplots(2,2) img = tools.imread(task.files_a[0]) bg = bg_a ax[0,0].imshow(img, cmap='gray') ax[0,1].imshow(bg, cmap='gray') ax[1,0].imshow(reflection, cmap='gray') img = img - bg img[reflection==255] = 0 ax[1,1].imshow(img, cmap='gray') plt.show() ''' return bg_a
# # OpenPIV on the bridgepile_wake # # See the post on LinkedIn by Stefano Brizzolara # https://www.linkedin.com/posts/stefano-brizzolara-6a8501198_rheinfall-flowvisualization-ugcPost-6672832128742408192-lRub # %% from openpiv import tools, process, validation, filters, scaling import numpy as np import matplotlib.pyplot as plt # %matplotlib inline import imageio # %% frame_a = tools.imread('~/Downloads/bridgepile_wake/frame0001.tif') frame_b = tools.imread('~/Downloads/bridgepile_wake/frame0011.tif') # %% fig, ax = plt.subplots(1, 2, figsize=(12, 10)) ax[0].imshow(frame_a, cmap=plt.cm.gray) ax[1].imshow(frame_b, cmap=plt.cm.gray) # %% winsize = 48 # pixels searchsize = 96 # pixels, search in image B overlap = 24 # pixels dt = 1. / 30 # sec, assume 30 fps u0, v0, sig2noise = process.extended_search_area_piv( frame_a.astype(np.int32),
from openpiv import tools, scaling, pyprocess, validation, filters, preprocess import os import numpy as np import matplotlib.pyplot as plt import os # we can run it from any folder path = os.path.dirname(os.path.abspath(__file__)) im_a = tools.imread(os.path.join(path, '../data/test4/Camera1-0101.tif')) im_b = tools.imread(os.path.join(path, '../data/test4/Camera1-0102.tif')) plt.imshow(np.c_[im_a, im_b], cmap='gray') # let's crop the region of interest frame_a = im_a[380:1980, 0:1390] frame_b = im_b[380:1980, 0:1390] plt.imshow(np.c_[frame_a, frame_b], cmap='gray') # Process the original cropped image and see the OpenPIV result: # typical parameters: window_size = 32 #pixels overlap = 16 # pixels search_area_size = 64 # pixels frame_rate = 40 # fps # process again with the masked images, for comparison# process once with the original images u, v, sig2noise = pyprocess.extended_search_area_piv( frame_a.astype(np.int32),
#!/usr/bin/env ipython import sys if 'OpenPIV' not in sys.path: sys.path.append('/Users/alex/Documents/OpenPIV/alexlib/openpiv-python') from openpiv import tools, validation, process, filters, scaling, pyprocess import numpy as np frame_a = tools.imread( 'exp1_001_a.bmp' ) frame_b = tools.imread( 'exp1_001_b.bmp' ) u, v, sig2noise = process.extended_search_area_piv( frame_a.astype(np.int32), frame_b.astype(np.int32), window_size=24, overlap=12, dt=0.02, search_area_size=64, sig2noise_method='peak2peak' ) x, y = process.get_coordinates( image_size=frame_a.shape, window_size=24, overlap=12 ) u, v, mask = validation.sig2noise_val( u, v, sig2noise, threshold = 2.5 ) u, v = filters.replace_outliers( u, v, method='localmean', max_iter=10, kernel_size=2) x, y, u, v = scaling.uniform(x, y, u, v, scaling_factor = 96.52 ) tools.save(x, y, u, v, mask, 'exp1_001.txt' ) tools.display_vector_field('exp1_001.txt', scale=100, width=0.0025) u, v, s2n= pyprocess.piv(frame_a, frame_b, corr_method='fft', window_size=24, overlap=12, dt=0.02, sig2noise_method='peak2peak' ) x, y = pyprocess.get_coordinates( image_size=frame_a.shape, window_size=24, overlap=12 ) u, v, mask = validation.sig2noise_val( u, v, s2n, threshold = 2.5 ) u, v = filters.replace_outliers( u, v, method='localmean', max_iter=10, kernel_size=2.5) x, y, u, v = scaling.uniform(x, y, u, v, scaling_factor = 96.52 ) tools.save(x, y, u, v, mask, 'exp1_002.txt' )
import openpiv from openpiv import tools, process, validation, filters, scaling, pyprocess import numpy as np import matplotlib.pyplot as plt from progressbar import * import openpiv.gpu_process reload(openpiv.gpu_process) frame_a = tools.imread('exp1_001_a.bmp') frame_b = tools.imread('exp1_001_b.bmp') fig, ax = plt.subplots(1, 2, figsize=(10, 8)) ax[0].imshow(frame_a, cmap=plt.cm.gray) ax[1].imshow(frame_b, cmap=plt.cm.gray) # gpu code parametes min_window_size = 32 overlap_ratio = 0.5 coarse_factor = 1 nb_iter_max = 2 # First time is slow as the GPU modules need to compile. Once they are compiled, they stay compiled. #Every time you run this after the first time it will be fast. x, y, u, v, mask = openpiv.gpu_process.WiDIM(frame_a.astype(np.int32), frame_b.astype(np.int32), np.ones(frame_a.shape, dtype=np.int32), min_window_size, overlap_ratio,
#!/usr/bin/env python import sys if 'OpenPIV' not in sys.path: sys.path.append('/Users/alex/Documents/OpenPIV/alexlib/openpiv-python') from openpiv import tools, process, pyprocess import numpy as np import matplotlib.pyplot as plt from skimage.transform import resize from skimage import img_as_ubyte frame_a = tools.imread( 'test001.png') frame_b = tools.imread( 'test002.png') # frame_a = img_as_ubyte(resize(frame_a,(1024,256))) # frame_b = img_as_ubyte(resize(frame_b,(1024,256))) frame_a = frame_a[:512,-200:] frame_b = frame_b[:512,-200:] #frame_a = frame_a[:256,:] #frame_b = frame_b[:256,:] plt.figure() plt.imshow(np.c_[frame_a,frame_b],cmap=plt.cm.gray) plt.show()
#!/usr/bin/env python import sys if 'OpenPIV' not in sys.path: sys.path.append('/Users/alex/Documents/OpenPIV/alexlib/openpiv-python') from openpiv import tools, process, pyprocess import numpy as np import matplotlib.pyplot as plt from skimage.transform import resize from skimage import img_as_ubyte frame_a = tools.imread('test001.png') frame_b = tools.imread('test002.png') # frame_a = img_as_ubyte(resize(frame_a,(1024,256))) # frame_b = img_as_ubyte(resize(frame_b,(1024,256))) frame_a = frame_a[:512, -200:] frame_b = frame_b[:512, -200:] #frame_a = frame_a[:256,:] #frame_b = frame_b[:256,:] plt.figure() plt.imshow(np.c_[frame_a, frame_b], cmap=plt.cm.gray) plt.show() u, v = process.extended_search_area_piv(frame_a.astype(np.int32), frame_b.astype(np.int32),
# --- # %% # # %load red_Cell.py from openpiv import tools, pyprocess, scaling, filters, \ validation, process import numpy as np import matplotlib.pyplot as plt import imageio from pylab import * # %matplotlib inline from skimage import img_as_uint frame_a = tools.imread('../test3/Y4-S3_Camera000398.tif') frame_b = tools.imread('../test3/Y4-S3_Camera000399.tif') # %% # for whatever reason the shape of frame_a is (3, 284, 256) # so we first tranpose to the RGB image and then convert to the gray scale # frame_a = img_as_uint(rgb2gray(frame_a)) # frame_b = img_as_uint(rgb2gray(frame_b)) plt.imshow(np.c_[frame_a, frame_b], cmap=plt.cm.gray) # %% # Use Cython version: process.pyx u, v, sig2noise = process.extended_search_area_piv( frame_a.astype(np.int32),
def piv_analysis(contr, relax, outfolder, scale, winsize_um=10, overlap_um=None, searchsize_um=None, drift_correction=True, threshold=1.2, scale_quiver=None): """ Computes deformations between 2 images by crosscorrelation using openpiv (must be installed - see Readme). Saves several quiver plots and the maximal found deformation for later analysis. contr: Path to active/contracted image file to calculate deformations between contracted and relaxed state relax: Path to relaxed image file to calculate deformations between contracted and relaxed state scale: resolution of image in µm per pixel winsize_um: size of the search window to be applied in µm drift_correction: Applies a drift correction before piv analysis threshold: filters displacement scale_quiver: can be used to scale the arrows in quiver plot (only for visualization) Default is None meaning automatically scaling , scale is inverse """ from openpiv import tools, process, validation, filters, scaling winsize = int(winsize_um / scale) # for pixel # if not specified use defaults if not overlap_um: overlap = winsize / 2 else: overlap = int(overlap_um / scale) if not searchsize_um: searchsize = winsize else: searchsize = int(searchsize_um / scale) print(winsize, overlap, searchsize) # odd winsize raise problems due to the overlap, thefore decrease by one pixel if odd and give warning if not (winsize % 2) == 0: print( 'Odd pixelnumbers raise problems due to the overlap: Winsize changed to ' + str((winsize - 1) * scale) + ' um') winsize -= 1 # creates folder if it doesn't exist if not os.path.exists(outfolder): os.makedirs(outfolder) #read in images relax = tools.imread(relax) contr = tools.imread(contr) # convert for openpiv relax = relax.astype(np.int32) contr = contr.astype(np.int32) dt = 1 # sec u0, v0, sig2noise = process.extended_search_area_piv( relax, contr, window_size=winsize, overlap=overlap, dt=dt, search_area_size=searchsize, sig2noise_method='peak2peak') x, y = process.get_coordinates(image_size=relax.shape, window_size=winsize, overlap=overlap) # drift correction if drift_correction: u0 -= np.nanmean(u0) v0 -= np.nanmean(v0) # filtered deformations u1, v1, mask = validation.sig2noise_val(u0, v0, sig2noise, threshold=threshold) # save deformations + coords np.save(outfolder + "/u.npy", u1) np.save(outfolder + "/v.npy", v1) np.save(outfolder + "/x.npy", x) np.save(outfolder + "/y.npy", y) # show filtered+unfiltered data plt.figure(figsize=(6, 3)) plt.subplot(121) plt.quiver(x, y[::-1], u0, v0, alpha=1, facecolor='orange', scale_units='xy', scale=scale_quiver) plt.title('unfiltered') plt.subplot(122) plt.title('filtered') plt.quiver(x, y[::-1], u1, v1, alpha=1, facecolor='b', scale_units='xy', scale=scale_quiver) plt.savefig(outfolder + '/filtered+unfilterd.png', bbox_inches='tight', pad_inches=0) plt.close() # save overlay # different color channels plt.figure() overlay = np.zeros((contr.shape[0], contr.shape[1], 3), 'uint8') overlay[..., 1] = contr #1 overlay[..., 2] = relax #2 plt.imshow(overlay, origin='upper' ) #extent=[0, contr.shape[0], contr.shape[1], 0]) # turn Y plt.quiver(x, y, u1, v1, facecolor='orange', alpha=1, scale_units='xy', scale=scale_quiver) plt.axis('off') plt.savefig(outfolder + '/overlay-filtered.png', bbox_inches='tight', pad_inches=0) # difference image plt.figure() plt.imshow(np.abs(contr - relax), cmap='viridis', origin='upper') plt.quiver(x, y, u1, v1, facecolor='orange', alpha=1, scale_units='xy', scale=scale_quiver) plt.axis('off') plt.savefig(outfolder + '/difference-img-filtered.png', bbox_inches='tight', pad_inches=0) plt.close() # save deformation and image data deformation_unfiltered = np.sqrt(u0**2 + v0**2) deformation_filtered = np.sqrt(u1**2 + v1**2) maxdefo_um_unfiltered = np.nanmax(deformation_unfiltered) * scale maxdefo_um_filtered = np.nanmax(deformation_filtered) * scale np.savetxt(outfolder + '/maxdefo_um_unfiltered.txt', [maxdefo_um_unfiltered]) np.savetxt(outfolder + '/maxdefo_um_filtered.txt', [maxdefo_um_filtered]) print('Maximal deformation unfiltered: ', maxdefo_um_unfiltered, 'Maximal deformation filtered: ', maxdefo_um_filtered) plt.imsave(outfolder + '/raw_contr.png', contr, cmap='gray') plt.imsave(outfolder + '/raw_relax.png', relax, cmap='gray') plt.close() return
# # OpenPIV tutorial 1 # # # In this tutorial we read the pair of images using `imread`, compare them visually # and process using OpenPIV. Here the import is using directly the basic functions and methods # %% from openpiv import tools, process, validation, filters, scaling import numpy as np import matplotlib.pyplot as plt # %matplotlib inline # %% frame_a = tools.imread( '../test1/exp1_001_a.bmp' ) frame_b = tools.imread( '../test1/exp1_001_b.bmp' ) # %% fig,ax = plt.subplots(1,2) ax[0].imshow(frame_a,cmap=plt.cm.gray) ax[1].imshow(frame_b,cmap=plt.cm.gray) # %% winsize = 24 # pixels searchsize = 64 # pixels, search in image B overlap = 12 # pixels dt = 0.02 # sec
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])