def reset_fs(self):
        #if hasattr(self, 'fs'): del self.fs
        #if hasattr(self, 'fs2'): del self.fs2

        ext = self.fig_path.split('.')[-1]
        if ext in ['mes', 'mlf']:
            self.glob = ""

        if len(self.glob) > 0:
            path = os.sep.join(self.fig_path.split(os.sep)[:-1])
            print path
            path = str(path + os.sep + self.glob)
        else:
            path = str(self.fig_path)
        if self._verbose:
            print path
        ext = self.fig_path.split('.')[-1].lower()
        if ext == 'mes': # in case of mes, self.record is repr, not record name
            record = self.record.split(' ')[0][1:]
        else:
            record = self.record
        self.fs = fseq.open_seq(path, record=record, ch=color_channels[self.ch])
        if self._verbose:
            print "new fs created"
        #self.fs.fns = self.fw_presets[self.fw_trans1]
        if self._verbose:
            print "fns1 set"
        self._fs2_needs_reload = True
        self.get_fs2()
        if self._verbose:
            print 'fs2 set'
        return
Exemple #2
0
def apply_warps(warps, frames, njobs=4):
    """
    returns result of applying warps for given frames (one warp per frame)
    """
    if njobs > 1 :
        pool = ProcessingPool(nodes=njobs)
        out = np.array(pool.map(parametric_warp, frames, warps))
    else:
        out = np.array([parametric_warp(f,w) for f,w in itt.izip(frames, warps)])
    if isinstance(frames, fseq.FrameSequence):
        out = fseq.open_seq(out)
        out.meta = frames.meta
    return out
 def get_fs2(self):
     "returns frame sequence after pipeline processing"
     if self._fs2_needs_reload:
         out = self.fs
         for f in self.pipeline:
             if f.domain == 'spatial':
                 out.fns.append(f.apply)
             elif f.domain == 'temporal':
                 out = fseq.open_seq(f.apply(out.as3darray()))
             else:
                 print 'unknown filter domain'
         if hasattr(self.fs, 'meta'):
             out.meta['axes'] = self.fs.meta['axes'].copy()
         self.fs2 = out
         self._fs2_needs_reload = False
     return self.fs2
Exemple #4
0
 def get_fs2(self):
     "returns frame sequence after pipeline processing"
     if self._fs2_needs_reload:
         out = self.fs
         out.fns = []
         for f in self.pipeline:
             if f.domain == 'spatial':
                 out.fns.append(f.apply)
             elif f.domain == 'temporal':
                 out = fseq.open_seq(f.apply(out.as3darray()))
             else:
                 print 'unknown filter domain'
         if hasattr(self.fs, 'meta'):
             out.meta['axes'] = self.fs.meta['axes'].copy()
         self.fs2 = out
         self._fs2_needs_reload = False
     return self.fs2
Exemple #5
0
    def reset_fs(self):
        #if hasattr(self, 'fs'): del self.fs
        #if hasattr(self, 'fs2'): del self.fs2

        #ext = self.fig_path.split('.')[-1]
        #if ext in ['mes', 'mlf']:
        #    self.glob = ""

        #if len(self.glob) > 0:
        #    path = os.sep.join(self.fig_full_path.split(os.sep)[:-1])
        #    #path = self.fig_path
        #    print path
        #    path = str(path + os.sep + self.glob)
        #else:
        #    path = str(self.fig_full_path)

        path = self.fig_full_path
        if self._verbose:
            print path

        ext = path.split('.')[-1].lower()

        if ext == 'mes': # in case of mes, self.record is repr, not record name
            record = self.record.split(' ')[0][1:]
        else:
            record = self.record

        self.fs = fseq.open_seq(path, record=record, ch=color_channels[self.ch])

        if self._verbose:
            print "new fs created"
        #self.fs.fns = self.fw_presets[self.fw_trans1]
        if self._verbose:
            print "fns1 set"
        self._fs2_needs_reload = True
        self.get_fs2()
        if self._verbose:
            print 'fs2 set'
        return
def main():
    parser = argparse.ArgumentParser(description="""Motion stabilize image stack (frame sequence)""")
    argdict =  {
        'imagestacks' : dict(nargs='+'),
        '-j': ('--json', dict(default=None, help="json file with default parameters")),
        '-p': ('--pretend', dict(action='store_true',help="Pretend mode: don't do anything, dry-run")),
        '-ch': dict(default='r', choices='rgb012', help='color channel to use'),
        '-s': ('--smooth', dict(action='append', metavar = ('FILTER', 'PARAMETER'), nargs='+',
                                help="smoothing filters; available filters: {median, gaussian, atrous}")),
        '-m': ('--model', dict(action='append', metavar = ("MODEL", "PARAMETER"),
                               nargs = '+',
                               #choices = ['shifts', 'softmesh', 'affine', 'Greenberg-Kerr'],
                               help='add movement model to use for stabilization;\
                               available models: {shifts, softmesh,  affine, Greenberg-Kerr, homography}')),
        '-t' : ('--type', dict(default='template',
                                  choices = ['template', 'recursive'],
                                  help='stabilization type')),
        '-n': ('--ncpu', dict(default=4, type=int, help="number of CPU cores to use")),
        '--record': dict(default=None, help='record within file to use (where applicable)'),
        '-v': ('--verbose', dict(action='count', help='increment verbosity level')),
        '--with-movies': dict(action='store_true'),
        '--suff': dict(default='', help="optional suffix to append to saved registration recipe"),
        '--fps': dict(default=25,type=float,help='fps of exported movie'),
        '--bitrate':dict(default=2000,type=float, help='bitrate of exported movie'),
        '--no-zstacks': dict(action='store_true', help='try to avoid z-stacks')
        }
    for arg,kw in argdict.items():
        if isinstance(kw, dict):
            parser.add_argument(arg,  **argdict[arg])
        else:
            parser.add_argument(arg, kw[0], **kw[1])

    args = parser.parse_args()

    if args.model is None:
        args.model = ['softmesh']
    if args.smooth is None:
        args.smooth = []
    else:
        for m in args.model:
            if not isinstance(m, basestring) and len(m)>1:
                params = json.loads(m[1])
                m[1] = params
    for smoother in args.smooth:
        if len(smoother) == 1:
            default_par = (smoother[0] in ['median']) and 3 or 1
            smoother.append(default_par)

    # override everything if json parameter is given
    if args.json :
        with open(args.json) as jsonfile:
            pars = json.load(jsonfile)
            for key,val in pars.items():
                setattr(args, key, val)
            
    if args.verbose > 2:
        print args

    registrators = opflowreg.RegistrationInterfaces

    def apply_reg(frames):
        if args.type == 'template':
            if args.verbose > 1:
                print 'stabilization type is template'
            tstart = len(frames)/2
            tstop = min(len(frames),tstart+50)
            template = np.max(frames[tstart:tstop],axis=0)
            def register_stack(stack, registrator, **fnargs):
                return opflowreg.register_stack_to_template(stack,template,registrator,njobs=args.ncpu,**fnargs)
        elif args.type == 'recursive':
            def register_stack(stack, registrator,**fnargs):
                return opflowreg.register_stack_recursive(stack,registrator,**fnargs)[1]
        else:
            raise NameError("Unknown registration type")
        # TODO: below is just crazy. has to be made neat later
        reg_dispatcher = {'affine':registrators.affine,
                          'homography':registrators.homography,
                          'shifts':registrators.shifts,
                          'Greenberg-Kerr':registrators.greenberg_kerr,
                          'softmesh':registrators.softmesh}
        operations = args.model
        newframes = frames
        warp_history = []
        for movement_model in operations:
            if not isinstance(movement_model, basestring):
                if len(movement_model)>1:
                    model, model_params = movement_model
                else:
                    model, model_params = movement_model[0],{}
            else:
                model = movement_model
                model_params = {}
            if args.verbose > 1:
                print 'correcting for {} with params: {}'.format(model, model_params)
            warps = register_stack(newframes, reg_dispatcher[model], **model_params)
            warp_history.append(warps)
            newframes = opflowreg.apply_warps(warps, newframes, njobs=args.ncpu)
        final_warps = [lib.flcompose(*warpchain) for warpchain in zip(*warp_history)]
        del newframes
        return final_warps
    
    for stackname in args.imagestacks:
        out_suff = make_outname_suffix(args)
        outname = stackname + out_suff + '.stab'
        try:
            if args.verbose:
                print '\nCalculating motion stabilization for file {}'.format(stackname)
                
            if args.pretend: continue

            fs = fseq.open_seq(stackname, ch=args.ch, record=args.record)

            if 'no_zstacks' and guess_fseq_type(fs) == 'Z':
                continue
            
            smoothers = get_smoothing_pipeline(args.smooth)
            fs.fns = smoothers
            warps = apply_reg(fs)
            opflowreg.save_recipe(warps, outname)
            if args.verbose:
                print 'saved motions stab recipe to {}'.format(outname)
            del fs
            
            if args.with_movies:

                if args.verbose>2:
                    print stackname+'-before-video.mp4'
                fsall = fseq.open_seq(stackname, ch='all', record=args.record)
                vl, vh = fsall.data_percentile(0.5), fsall.data_percentile(99.5)
                vl,vh = np.min(vl), np.max(vh)
                if args.verbose > 10:
                    print 'vl, vh: ', vl, vh

                proj1 = fsall.time_project(fn=partial(np.mean, axis=0))

                fs2 = opflowreg.apply_warps(warps, fsall, njobs=args.ncpu)
                proj2 = fs2.time_project(fn=partial(np.mean, axis=0))

                fig,axs = plt.subplots(1,2,figsize=(12,5.5))
                def _lutfn(f): return np.clip((f-vl)/(vh-vl), 0, 1)
                #def _lutfn(f): return np.dstack([np.clip(f[...,k],vl[k],vh[k])/vh[k] for k in range(f.shape[-1])])
                for ax,f,t in zip(axs,(proj1,proj2),['before','stabilized']):
                    ax.imshow(_lutfn(f),aspect='equal')
                    #imh = ax.imshow(f[...,0],aspect='equal',vmin=vl,vmax=vh); plt.colorbar(imh,ax=ax)
                    plt.setp(ax, xticks=[],yticks=[],frame_on=False)
                    ax.set_title(t)
                plt.savefig(stackname+out_suff+'-average-projections.png')
                fig.clf()
                plt.close(fig)

                if args.verbose > 2:
                    print stackname+out_suff+'-stabilized-video.mp4'

                fseq.to_movie([fsall, fs2],
                              stackname+out_suff+'-stabilized-video.mp4',
                              titles=['before', 'stabilized'],
                              bitrate=3000)

                del fsall, fs2
                
                plt.close('all')
            del warps
            if args.verbose>2: print 'Done'


        except Exception as e:
            print "Couldn't process {} becase  {}".format(stackname, e)