def create_arrays(basepath='.'): basepath = Path(basepath) / 'examplearrays' / 'arrays' basepath.mkdir(parents=True, exist_ok=True) metadata = { "channels": [0, 9], "comments": "This example array has metadata, which is stored in a " "separate JSON file. Metadata in Darr is a dictionary " "that can contain anything that is JSON serializable.", "datetime": f"{datetimestring()}", "samplingrate": 25000.0 } # 2D ar = np.arange(0, 16).reshape(8, 2) # sums to 120, axis 0 sums to 56, 1 to 64 car = np.array(ar, dtype='complex128') + 2.0j for numtype in numtypesdescr.keys(): if numtype.startswith('complex'): a = car else: a = ar darr.asarray(basepath / f'array_{numtype}_2D.darr', a, dtype=numtype, metadata=metadata, overwrite=True) # 1D ar = [1, 3, 5, 7, 9, 11, 14] # 0:7 sums to 50 car = np.array(ar, dtype='complex128') + 2.0j for numtype in numtypesdescr.keys(): if numtype.startswith('complex'): a = car elif 'int' in numtype: imin, imax = minmaxints[numtype] a = ar[:] a.extend([imin, imax]) else: a = ar darr.asarray(basepath / f'array_{numtype}_1D.darr', a, dtype=numtype, metadata=metadata, overwrite=True)
def to_darrsnd(self, path, accessmode='r', dtype='float32', metadata=None, overwrite=False): ds = darr.asarray(array=self.frames, dtype=dtype, accessmode=accessmode, metadata=metadata, overwrite=overwrite) ds.metadata['fs'] = self.fs return DarrSnd(path=path, accessmode=accessmode)
def to_darrsnd(self, path=None, dtype=None, metadata=None, mode='r', startframe=None, endframe=None, starttime=None, endtime=None, startdatetime=None, enddatetime=None, blocklen=44100, accessmode='r', overwrite=False, channelindex=None): from .darrsnd import DarrSnd dd = create_datadir(path, overwrite=overwrite) framespath = dd.path / DarrSnd._framespath snds = self.iterread(startframe=startframe, endframe=endframe, channelindex=channelindex, blocklen=blocklen) snd1, snds = peek_iterable(snds) startdatetime = str(snd1.startdatetime) origintime = float(snd1.origintime) frames = (snd.read_frames() for snd in snds) da = asarray(path=framespath, array=frames, dtype=dtype, accessmode=accessmode, overwrite=overwrite) duration = da.shape[0] / self.fs sndinfo = { 'dtype': da.dtype.name, 'fs': self.fs, 'duration': duration, 'startdatetime': startdatetime, 'origintime': origintime, 'nchannels': da.shape[1], 'nframes': da.shape[0], 'soundversion': get_versions()['version'], 'unit': self.unit, } dd.write_sndinfo(sndinfo, overwrite=overwrite) if (metadata is not None) and (not overwrite): dd.update(metadata) da.accessmode = accessmode return DarrSnd(path=path, accessmode=accessmode)
def detect_movement(videofilestream, bgs, morphologyex=2, color=False, roi=None, nroi=None, analysispath='.', ignore_firstnframes=10, overwrite=False, resultvideo=False): """Detects movement based on a background subtraction algorithm. The backgound subtractor should be provided as a parameter. Parameters ---------- videofilestream : VideoFileStream A Birdwatcher VideoFileStream object bgs : BaseBackgroundSubtractor Can be any instance of child from BaseBackgroundSubtractor. Currently included in Birdwatcher are BackgroundSubtractorMOG2, BackgroundSubtractorKNN, BackgroundSubtractorLSBP. morphologyex : int, default=2 Kernel size of MorphologeEx open processing. color : bool, default=False Should detection be done on color frames (True) or on gray frames (False). roi : (int, int, int, int), optional Region of interest. Only look at this rectangular region. h1, h2, w1, w2. nroi : (int, int, int, int), optional Not region of interest. Exclude this rectangular region. h1, h2, w1, w2. analysispath : Path or str, optional Where to write results to. The default writes to the current working directory. ignore_firstnframes : int, default=10 Do not provide coordinates for the first n frames. These often have a lot of false positives. overwrite : bool, default=False Overwrite results or not. resultvideo : bool, default=False Automatically generate a video with results, yes or no. Returns ------- tuple of arrays (coordinates, coordinate count, coordinate mean) These are Darr arrays that are disk-based. """ if isinstance(videofilestream, VideoFileStream): vfs = videofilestream else: raise TypeError(f"`videofilestream` parameter not a VideoFileStream " f"object ({type(videofilestream)}).") Path(analysispath).mkdir(parents=True, exist_ok=True) movementpath = Path(analysispath) / f'{vfs.filepath.stem}_movement' Path(movementpath).mkdir(parents=True, exist_ok=True) metadata = {} metadata['backgroundsegmentclass'] = str(bgs) metadata['backgroundsegmentparams'] = bgs.get_params() metadata['morphologyex'] = morphologyex metadata['roi'] = roi metadata['nroi'] = nroi metadata['birdwatcherversion'] = get_versions()['version'] frames = (vfs.iter_frames(color=color).apply_backgroundsegmenter( bgs, roi=roi, nroi=nroi)) if morphologyex is not None: frames = frames.morphologyex(kernelsize=morphologyex) cd = create_coordarray(movementpath / 'coords.darr', framewidth=vfs.framewidth, frameheight=vfs.frameheight, metadata=metadata, overwrite=overwrite) empty = np.zeros((0, 2), dtype=np.uint16) coords = (c if i >= ignore_firstnframes else empty for i, c in enumerate(frames.find_nonzero())) cd.iterappend(coords) cc = darr.asarray(movementpath / 'coordscount.darr', cd.get_coordcount(), metadata=metadata, overwrite=True) cm = darr.asarray(movementpath / 'coordsmean.darr', cd.get_coordmean(), metadata=metadata, overwrite=True) if resultvideo: ovfilepath = Path(movementpath) / f'{ vfs.filepath.stem}_movement.mp4' cframes = cd.iter_frames(nchannels=3, value=(0, 0, 255)) (vfs.iter_frames().add_weighted(0.7, cframes, 0.8).draw_framenumbers().tovideo( ovfilepath, framerate=vfs.avgframerate, crf=25)) return cd, cc, cm