def median_calculation(network_input, med_frame2=None, dims=None, median_decimate=1, display=True): '''Calculate the median and median-based standard deviation of a video. Inputs: network_input (numpy.ndarray of float32): the input video. med_frame2 (3D empty numpy.ndarray of float32, default to None): empty array to store the median and median-based standard deviation. dims (tuple of int, shape = (2,), default to None): lateral dimension of the video median_decimate (int, default to 1): Median and median-based standard deviation are calculate from every "median_decimate" frames of the video display (bool, default to True): Indicator of whether display the timing information Outputs: med_frame3 (3D numpy.ndarray of float32): the median and median-based standard deviation. ''' if display: start = time.time() if dims: (rows, cols) = dims else: (_, rows, cols) = network_input.shape if med_frame2 is None: med_frame2 = np.zeros(rows, cols, 2, dtype='float32') result = np.copy(network_input[::median_decimate, :rows, :cols].transpose( [1, 2, 0])) fastquant(result, np.array([0.5, 0.25], dtype='float32'), med_frame2) # med_frame2[:, :, 0] stores the median # Noise is estimated using median-based standard deviation calculated from # the difference bwtween 0.5 quantile and 0.25 quantile temp_noise = (med_frame2[:, :, 0] - med_frame2[:, :, 1]) / (math.sqrt(2) * special.erfinv(0.5)) zeronoise = (temp_noise == 0) # if the calculated temp_noise is 0 at some pixels, replace the median-based standard deviation # with conventional stantard deviation if np.any(zeronoise): [x0, y0] = zeronoise.nonzero() for (x, y) in zip(x0, y0): new_noise = np.std(network_input[:, x, y]) if new_noise > 0: temp_noise[x, y] = new_noise else: temp_noise[x, y] = np.inf # med_frame2[:, :, 1] stores the median-based standard deviation med_frame2[:, :, 1] = np.reciprocal(temp_noise).astype('float32') med_frame3 = np.copy(med_frame2.transpose( [2, 0, 1])) # Using copy to avoid computer crashing if display: endmedtime = time.time() print('median computation: {} s'.format(endmedtime - start)) return med_frame3
def median_normalization(network_input, med_frame2=None, dims=None, median_decimate=1, display=True): '''Normalize the video by dividing to its temporal median. network_input(t,x,y) = network_input(t,x,y) / mean(median(x,y)). Inputs: network_input (numpy.ndarray of float32, shape = (T,Lx,Ly)): the input video. med_frame2 (3D empty numpy.ndarray of float32, default to None): empty array to store the median. dims (tuple of int, shape = (2,), default to None): lateral dimension of the video median_decimate (int, default to 1): Median is calculate from every "median_decimate" frames of the video display (bool, default to True): Indicator of whether display the timing information Outputs: med_frame3 (3D numpy.ndarray of float32): the median. In addition, "network_input" is changed to become the normalized video during the function ''' if display: start = time.time() if dims: (rows, cols) = dims else: (_, rows, cols) = network_input.shape if med_frame2 is None: med_frame2 = np.zeros(rows, cols, 2, dtype='float32') result = np.copy(network_input[::median_decimate, :rows, :cols].transpose( [1, 2, 0])) fastquant(result, np.array([0.5], dtype='float32'), med_frame2[:, :, 0:1]) # med_frame2[:, :, 0] stores the median if display: endmedtime = time.time() print('median computation: {} s'.format(endmedtime - start)) fastnormback(network_input[:, :rows, :cols], max(1, med_frame2[:, :, 0].mean())) med_frame3 = np.copy(med_frame2.transpose( [2, 0, 1])) # Using copy to avoid computer crashing if display: endnormtime = time.time() print('normalization: {} s'.format(endnormtime - endmedtime)) return med_frame3
def median_std(result, med_frame2): '''Calculate median and median_based_standard_deviation from the selected video. Inputs: result (numpy.ndarray of float32): the input video. The temporal dimension is transposed to the first dimension. med_frame2 (3D empty numpy.ndarray of float32): empty array to store the median and median-based standard deviation. Outputs: med_frame3 (3D numpy.ndarray of float32): the median and median-based standard deviation. ''' fastquant(result, np.array([0.5, 0.25], dtype='float32'), med_frame2) # med_frame2[:, :, 0] stores the median # Noise is estimated using median-based standard deviation calculated from # the difference bwtween 0.5 quantile and 0.25 quantile temp_noise = (med_frame2[:, :, 0] - med_frame2[:, :, 1]) / (math.sqrt(2) * special.erfinv(0.5)) zeronoise = (temp_noise == 0) # if the calculated temp_noise is 0 at some pixels, replace the median-based standard deviation # with conventional stantard deviation if np.any(zeronoise): [x0, y0] = zeronoise.nonzero() for (x, y) in zip(x0, y0): new_noise = np.std(result[:, x, y]) if new_noise > 0: temp_noise[x, y] = new_noise else: temp_noise[x, y] = np.inf # med_frame2[:, :, 1] stores the median-based standard deviation med_frame2[:, :, 1] = np.reciprocal(temp_noise).astype('float32') med_frame3 = np.copy(med_frame2.transpose( [2, 0, 1])) # Using copy to avoid computer crashing return med_frame3
def median_normalization(network_input, med_frame2=None, dims=None, frames_initf=10**4, \ update_baseline=False, frames_init=10**6, display=True): '''Normalize the video by dividing to its temporal median. network_input(t,x,y) = network_input(t,x,y) / mean(median(x,y)). Inputs: network_input (numpy.ndarray of float32, shape = (T,Lx,Ly)): the input video. med_frame2 (3D empty numpy.ndarray of float32, default to None): empty array to store the median. dims (tuple of int, shape = (2,), default to None): lateral dimension of the video frames_initf (int, default to a very large number): Median and median-based standard deviation are calculate from the first "frames_initf" frames of the video update_baseline (bool, default to False): True if the median and median-based std is updated every "frames_init" frames. frames_init (int, default to a very large number): Median and median-based standard deviation are updated every "frames_init" frames of the video. Only used when update_baseline = True display (bool, default to True): Indicator of whether display the timing information Outputs: No explicit output. In addition, "network_input" is changed to become the normalized video during the function ''' if display: start = time.time() if dims: (rows, cols) = dims else: (_, rows, cols) = network_input.shape if med_frame2 is None: med_frame2 = np.zeros(rows, cols, 2, dtype='float32') result = np.copy(network_input[:frames_initf, :rows, :cols].transpose( [1, 2, 0])) fastquant(result, np.array([0.5], dtype='float32'), med_frame2[:, :, 0:1]) # med_frame2[:, :, 0] stores the median if not update_baseline: if display: endmedtime = time.time() print('median computation: {} s'.format(endmedtime - start)) fastnormback(network_input[:, :rows, :cols], max(1, med_frame2[:, :, 0].mean())) # med_frame3 = np.copy(med_frame2.transpose([2,0,1])) # Using copy to avoid computer crashing if display: endnormtime = time.time() print('normalization: {} s'.format(endnormtime - endmedtime)) else: fastnormback(network_input[:frames_initf + frames_init, :rows, :cols], max(1, med_frame2[:, :, 0].mean())) for t_update in range(frames_initf + frames_init, network_input.shape[0], frames_init): result = np.copy( network_input[t_update - frames_init:t_update, :rows, :cols].transpose( [1, 2, 0])) fastquant(result, np.array([0.5], dtype='float32'), med_frame2[:, :, 0:1]) fastnormback( network_input[t_update:t_update + frames_init, :rows, :cols], max(1, med_frame2[:, :, 0].mean())) if display: endnormtime = time.time() print('median computation and normalization: {} s'.format( endnormtime - start))