def main(): usage = """meshfmsf.py [vid_in] [flow_in] -threshold THRESH -gridsize GRIDSIZE Visualize results of MFSF run by meshing an object and 'tracking' it Ben Lansdell 02/21/2017 """ parser = argparse.ArgumentParser() parser.add_argument('vid_in', help='output mat file') parser.add_argument('flow_in', help='input mat files from MFSF') parser.add_argument('-threshold', help='intensities below this are not meshed', default=25) parser.add_argument('-gridsize', help='approximate gridsize for mesh', default=25) args = parser.parse_args() #Test code #fn_in='../hydra/video/20170202/20170202_8bit.tif' #mfsf_in = './mfsf_output/20170202_16bit/' #gridsize = 50 #threshold = 15 mfsf_in = args.flow_in fn_in = args.vid_in threshold = args.threshold gridsize = args.gridsize dm_out = 'init_mesh.pkl' cuda = False #Skip to this frame and create mesh capture = TIFFStream(fn_in, threshold) nx = capture.nx nF = capture.nframes #Load MFSF data try: a = loadmat(mfsf_in + '/result.mat') params = a['parmsOF'] u = a['u'] v = a['v'] #Find reference frame nref = params['nref'][0, 0][0, 0] except NotImplementedError: #Load using HDF package instead. This happens if the file is too big and had to be #saved using MATLAB's -v7.3 flag print "Failed to read using loadmat, using hdf5 library to read %s" % mfsf_in f = h5py.File(mfsf_in + '/result.mat', 'r') #Note the x and y axes may need to be switched here... #u = np.transpose(np.array(f.get('u')), (1,2,0)) #v = np.transpose(np.array(f.get('v')), (1,2,0)) u = np.transpose(np.array(f.get('u')), (2, 1, 0)) v = np.transpose(np.array(f.get('v')), (2, 1, 0)) params = f.get('parmsOF') nref = int(params['nref'][0][0]) print "Loaded MFSF data" for idx in range(nF): print 'Loading frame', idx ret, frame, mask = capture.read() if idx == nref: refframe = frame.copy() tracking_mask = mask (mask, ctrs, fd) = findObjectThreshold(tracking_mask, threshold=.5) distmesh = DistMesh(refframe, h0=gridsize) if not os.path.exists(mfsf_in + dm_out): distmesh.createMesh(ctrs, fd, refframe, plot=False) #Save this distmesh and reload it for quicker testing distmesh.save(mfsf_in + dm_out) else: distmesh.load(mfsf_in + dm_out) refpositions = distmesh.p #Perturb mesh points according to MFSF flow field and save screenshot output nF = min(u.shape[2], nF) del capture gc.collect() imageoutput = mfsf_in + 'mesh/' #Make directory if needed... if not os.path.exists(imageoutput): os.makedirs(imageoutput) capture2 = TIFFStream(fn_in, threshold) for idx in range(nF): #Update positions based on reference positions and flow field print("Visualizing frame %d" % idx) ret, frame, mask = capture2.read() dx = u[refpositions[:, 1].astype(int), refpositions[:, 0].astype(int), idx] dy = v[refpositions[:, 1].astype(int), refpositions[:, 0].astype(int), idx] X = refpositions.copy() X[:, 0] += dx X[:, 1] += dy frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2BGR) drawGrid(frame, X / 4, distmesh.bars, L=None, F=None) cv2.imwrite(imageoutput + 'frame_%03d.png' % idx, frame) #Make a video print 'Making movie' overlayoutput = mfsf_in + 'mesh_overlay/' if not os.path.exists(overlayoutput): os.makedirs(overlayoutput) #avconv = 'avconv -i ' + imageoutput + 'frame_%03d.png -c:v mpeg4 -qscale 8 -y' avconv = 'avconv -i ' + imageoutput + 'frame_%03d.png -c:v mpeg4 -qscale 29 -y' os.system(avconv + ' ' + overlayoutput + 'output.mp4')
def continuation(path_in, mfsf_in, iframes, rframes): usage = """Continue MFSF optic flow fields from separate videos into the one flow field whose coordinates are relative to a set of reference frames specified. Visualize results by generating meshes of different colors -- to correspond to different reference frames. Example: ./continue_mesh.py --rframes 1,501 --iframes 1,251,501,751 ./simmatrix/20160412/ ./mfsf_output/ For help: ./continue_mesh.py -h Ben Lansdell 1/6/2017 """ #Test code vid_path_in = '../hydra/video/20160412/combined/' name = './simmatrix/20160412/' mfsf_in = name + '/continuation_mfsf/' #seg_in = name + '/seg_admm/gpu_MS_lambda_1.00e-04_rho_1.00e-03_niter_3000.npy' rframes = [1, 501] iframes = [1, 251, 501, 751, 1001, 1251, 1501] colors = np.array([[0, 255, 0], [255, 0, 0]]) dm_frames = [1, 501, 1251] forward_mfsf = [[501, 751], [1251, 1501]] reverse_mfsf = [[501, 251], [1251, 1001]] threshold = 2 cuda = True gridsize = 50 mesh_out = name + '/mesh/' #Make directory if needed... if not os.path.exists(mesh_out): os.makedirs(mesh_out) imageoutput = name + '/mesh_frames/' #Make directory if needed... if not os.path.exists(imageoutput): os.makedirs(imageoutput) masks = [] refpositions = [] faces = [] #Load in mask images for idx, fn in enumerate(rframes): dm_out = mesh_out + '/frame_%04d.pkl' % fn mask_in = name + '/masks/mask_%04d.png' % fn masks.append(cv2.cvtColor(cv2.imread(mask_in), cv2.COLOR_BGR2GRAY)) #Make the meshes #Generate ctrs and fd (m, ctrs, fd) = findObjectThreshold(masks[idx], threshold=threshold) d = DistMesh(m, h0=gridsize) if not os.path.exists(dm_out): d.createMesh(ctrs, fd, m, plot=True) #Save this distmesh and reload it for quicker testing d.save(dm_out) else: d.load(dm_out) refpositions.append(d.p) faces.append(d.t) refframe_files = sorted(glob(name + '/refframes/*.png')) mfsf_matfiles = sorted(glob(mfsf_in + '*.mat')) nV = len(refframe_files) #For each MFSF file, we will make a video coloring the mesh by for l, fn2 in enumerate(iframes): continued = [] u = [] v = [] #Flow data ./simmatrix/20160412/continuation/mfsf_r_0001_l_4251.mat for r, fn1 in enumerate(rframes): #Load MFSF data for each ref frames if fn2 in dm_frames: fn = mfsf_in + '/mfsf_r_%04d_l_%04d.mat' % (fn1, fn2) elif fn2 in [f[1] for f in forward_mfsf]: fn2_for = iframes[l - 1] fn = mfsf_in + '/mfsf_r_%04d_l_%04d_m_%04d.mat' % ( fn1, fn2_for, fn2) else: fn2_rev = iframes[l + 1] fn = mfsf_in + '/mfsf_r_%04d_l_%04d_m_%04d.mat' % ( fn1, fn2_rev, fn2) a = loadmat(fn) c = a['mask'] if len(c.shape) == 3: continued.append(a['mask'][:, :, 0]) else: continued.append(a['mask']) u.append(a['u']) v.append(a['v']) #Load video stream capture = TIFFStream(vid_path_in + 'stk_%04d.tif' % (l + 1), threshold) nx = capture.nx nF = capture.nframes #Perturb initial meshes by their flow fields positions = [] active_pts = [] active_faces = [] for r, fn1 in enumerate(rframes): dx = u[r][refpositions[r][:, 1].astype(int), refpositions[r][:, 0].astype(int), 0] dy = v[r][refpositions[r][:, 1].astype(int), refpositions[r][:, 0].astype(int), 0] X = refpositions[r].copy() X[:, 0] += dx X[:, 1] += dy positions.append(X) #Intersect perturbed points by labeled continuation data to get #the faces that we're going to display in this video act_pts = continued[r][X[:, 1].astype(int), X[:, 0].astype(int)] act_fcs = np.array([act_pts[f].all() for f in faces[r]]) active_pts.append(act_pts) active_faces.append(act_fcs) #Then, for each frame, perturb the vertices by their respective flow fields #and draw the active faces from each reference frame a different color for idx in range(nF): print("Visualizing frame %d" % idx) ret, frame, _ = capture.read(backsub=False) frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2RGB) for r, fn1 in enumerate(rframes): #Perturb the vertices according to the flow dx = u[r][refpositions[r][:, 1].astype(int), refpositions[r][:, 0].astype(int), idx] dy = v[r][refpositions[r][:, 1].astype(int), refpositions[r][:, 0].astype(int), idx] X = refpositions[r].copy() X[:, 0] += dx X[:, 1] += dy #Draw the active faces col = colors[r, :] drawFaces(frame, X, faces[r][active_faces[r]], col) #Save cv2.imwrite(imageoutput + 'l_%04d_frame_%04d.png' % (fn2, idx), frame) #Make a video print 'Making movie' overlayoutput = name + '/mesh_movies/' if not os.path.exists(overlayoutput): os.makedirs(overlayoutput) avconv = 'avconv -i ' + imageoutput + 'l_' + '%04d' % fn2 + '_frame_%04d.png -c:v mpeg4 -qscale 7 -y' os.system(avconv + ' ' + overlayoutput + 'output_l_%04d.avi' % fn2)
def main(): usage = """meshfneurons.py [vid_in] [tracks_csv] [name] Make animation of mesh with edges being the tracked neuron positions. To highlight the discontinuity in motion -- if it exists. Ben Lansdell 03/02/2017 """ parser = argparse.ArgumentParser() parser.add_argument('vid_in', help='video file for animation') parser.add_argument('tracks_in', help='csv file with tracks') parser.add_argument('name', help='name to save video files') args = parser.parse_args() #Test code #fn_in='../hydra/video/20170202/20170202_8bit.tif' #mfsf_in = './mfsf_output/20170202_16bit/' #gridsize = 50 #threshold = 15 threshold = 22 name = args.name if name[-1] != '/': name += '/' tracks_in = args.tracks_in fn_in = args.vid_in #Skip to this frame and create mesh capture = TIFFStream(fn_in, threshold) nx = capture.nx nF = capture.nframes #Load tracks ret, frame, mask = capture.read() (mask, ctrs, fd) = findObjectThreshold(mask, threshold=.5) tracks = load_tracks_csv(tracks_in) nC = len(tracks) p = np.zeros((nC, 2)) for c in tracks.keys(): p[c, :] = tracks[c][0][0:2] bars, t = Delaunay(p, fd) original_ori = orientation(p, t) nB = len(bars) imageoutput = name + 'mesh_neurons/' #Make directory if needed... if not os.path.exists(imageoutput): os.makedirs(imageoutput) capture = TIFFStream(fn_in, threshold) for idx in range(nF): #For each edge in each #Update positions based on reference positions and flow field print("Visualizing frame %d" % idx) ret, frame, mask = capture.read() frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2BGR) for c in tracks.keys(): p[c, :] = tracks[c][idx][0:2] current_ori = orientation(p, t) invalid_ori = (current_ori * original_ori == -1) threeori = np.hstack((invalid_ori, invalid_ori, invalid_ori)) bars = np.vstack( (t[:, [0, 1]], t[:, [1, 2]], t[:, [2, 0]])) # Interior bars duplicated #Bars with bad orientation... invalid_bars = bars[threeori, :] invalid_bars.sort(axis=1) invalid_bars = ml.unique_rows(invalid_bars) bars.sort(axis=1) bars = ml.unique_rows(bars) # Bars as node pairs colors = npml.repmat([0, 255, 0], nB, 1) for i, b in enumerate(bars): if b in invalid_bars: colors[i] = [0, 0, 255] drawGrid(frame, p, bars, cols=colors) cv2.imwrite(imageoutput + 'frame_%03d.png' % idx, frame) #Make a video print 'Making movie' overlayoutput = name + 'mesh_overlay/' if not os.path.exists(overlayoutput): os.makedirs(overlayoutput) #avconv = 'avconv -i ' + imageoutput + 'frame_%03d.png -c:v mpeg4 -qscale 8 -y' avconv = 'avconv -i ' + imageoutput + 'frame_%03d.png -c:v mpeg4 -qscale 15 -y' os.system(avconv + ' ' + overlayoutput + 'meshneurons.mp4')