def smooth_target(df, window): window = window signal_df = pd.DataFrame(index=df.index) signal_df['signal'] = 0.0 signal_df['Smooth'] = smooth(df['Close'].values, 2 * window + 1, 3) # cubic signal_df['Smooth'] = smooth(signal_df['Smooth'].values, window + 1, 1) # linear df['Smooth'] = signal_df['Smooth'] max_list = extrema(df['Smooth'].values, np.greater)[0].tolist() min_list = extrema(df['Smooth'].values, np.less)[0].tolist() for x in min_list: t = df.index[x] signal_df.loc[t, 'signal'] = 1 for x in max_list: t = df.index[x] signal_df.loc[t, 'signal'] = -1 signal_df['positions'] = signal_df['signal'].diff() df['SMOOTH_TARGET'] = signal_df['positions'] df['SMOOTH_TARGET'] = df['SMOOTH_TARGET'].replace( 0, np.nan).interpolate(method='slinear').ffill().bfill() df['SMOOTH_TARGET'] = (df['SMOOTH_TARGET'] >= 0.5).astype(np.uint8) return df, signal_df
def coherence_len(E, axis, thr=0.88): j12 = coherence_1d(E) print("Calculating Coherence Length") mu_ = j12[len(j12) // 2:] mu_ = extrema(j12, np.less)[0] mu_ = mu_[(mu_ > len(j12) // 2) & (j12[mu_][0] < thr)] print(mu_) mu_ = axis[mu_[0]] - axis[len(j12) // 2] return j12, mu_
def intensity_width(II, axis, thr=0.88): print("Calculating Intensity Profile Width") var = np.sum((I - np.mean(II))**2 for I in II) / np.sum(II) std = np.sqrt(var) sig = extrema(II, np.less)[0] sig = sig[(axis[sig] > len(II) // 2) & (II[sig][:, 0] < np.mean(II) + std * 2)] sig = axis[sig[0]] - axis[len(II) // 2] return sig
def findPeaks(data_array): xvalues = data_array[0] yvalues = data_array[1] indices = extrema(np.array(yvalues),np.greater)[0] ext = [[],[]] temp = [] for index in indices: temp.append(yvalues[index]) indices = [index for tem, index in sorted(zip(temp, indices),reverse=True)] for (index,i) in zip(indices,range(len(indices))): if i < num_traps+5 or yvalues[index] > -10: ext[0].append(xvalues[index]) ext[1].append(yvalues[index]) else: break # for i in range(len(array)-1): # if val >= array[i].temp and val <= array[i+1].temp: # break # ind_guess += 1 # ind = ind_guess # val = array[ind].pres # for i in range(int(len(array)*.165)): # if ind_guess + i < len(array): # if val < array[ind_guess + i].pres: # ind = ind_guess + i # val = array[ind].pres # if ind_guess - i > 0: # if val < array[ind_guess - i].pres: # ind = ind_guess - i # val = array[ind].pres # print( "Peak found at " + str(val)) return ext
def get_peak_ecg(ecg, sfreq=1017.25, flow=10, fhigh=20, pct_thresh=95.0, default_peak2peak_min=0.5, event_id=999): # ------------------------------------------- # import necessary modules # ------------------------------------------- from mne.filter import band_pass_filter from jumeg.jumeg_math import calc_tkeo from scipy.signal import argrelextrema as extrema # ------------------------------------------- # filter ECG to get rid of noise and drifts # ------------------------------------------- fecg = band_pass_filter(ecg, sfreq, flow, fhigh, n_jobs=1, method='fft') ecg_abs = np.abs(fecg) # ------------------------------------------- # apply Teager Kaiser energie Operator (TKEO) # ------------------------------------------- tk_ecg = calc_tkeo(fecg) # ------------------------------------------- # find all peaks of abs(EOG) # since we don't know if the EOG lead has a # positive or negative R-peak # ------------------------------------------- ixpeak = extrema(tk_ecg, np.greater, axis=0) # ------------------------------------------- # threshold for |R-peak| # ------------------------------------------ peak_thresh_min = np.percentile(tk_ecg, pct_thresh, axis=0) ix = np.where(tk_ecg[ixpeak] > peak_thresh_min)[0] npeak = len(ix) if (npeak > 1): ixpeak = ixpeak[0][ix] else: return -1 # ------------------------------------------- # threshold for max Amplitude of R-peak # fixed to: median + 3*stddev # ------------------------------------------- mag = fecg[ixpeak] mag_mean = np.median(mag) if (mag_mean > 0): nstd = 3 else: nstd = -3 peak_thresh_max = mag_mean + nstd * np.std(mag) ix = np.where(ecg_abs[ixpeak] < np.abs(peak_thresh_max))[0] npeak = len(ix) if (npeak > 1): ixpeak = ixpeak[ix] else: return -1 # ------------------------------------------- # => test if the R-peak is positive or negative # => we assume the the R-peak is the largest peak !! # # ==> sometime we have outliers and we should check # the number of npos and nneg peaks -> which is larger? -> note done yet # -> we assume at least 2 peaks -> maybe we should check the ratio # ------------------------------------------- ixp = np.where(fecg[ixpeak] > 0)[0] npos = len(ixp) ixn = np.where(fecg[ixpeak] < 0)[0] nneg = len(ixp) if (npos == 0 and nneg == 0): import pdb pdb.set_trace() if (npos > 3): peakval_pos = np.abs(np.median(ecg[ixpeak[ixp]])) else: peakval_pos = 0 if (nneg > 3): peakval_neg = np.abs(np.median(ecg[ixpeak[ixn]])) else: peakval_neg = 0 if (peakval_pos > peakval_neg): ixpeak = ixpeak[ixp] ecg_pos = ecg else: ixpeak = ixpeak[ixn] ecg_pos = - ecg npeak = len(ixpeak) if (npeak < 1): return -1 # ------------------------------------------- # check if we have peaks too close together # ------------------------------------------- peak_ecg = ixpeak/sfreq dur = (np.roll(peak_ecg, -1)-peak_ecg) ix = np.where(dur > default_peak2peak_min)[0] npeak = len(ix) if (npeak < 1): return -1 ixpeak = np.append(ixpeak[0], ixpeak[ix]) peak_ecg = ixpeak/sfreq dur = (peak_ecg-np.roll(peak_ecg, 1)) ix = np.where(dur > default_peak2peak_min)[0] npeak = len(ix) if (npeak < 1): return -1 ixpeak = np.unique(np.append(ixpeak, ixpeak[ix[npeak-1]])) npeak = len(ixpeak) # ------------------------------------------- # search around each peak if we find # higher peaks in a range of 0.1 s # ------------------------------------------- seg_length = np.ceil(0.1 * sfreq) for ipeak in range(0, npeak-1): idx = [int(np.max([ixpeak[ipeak] - seg_length, 0])), int(np.min([ixpeak[ipeak]+seg_length, len(ecg)]))] idx_want = np.argmax(ecg_pos[idx[0]:idx[1]]) ixpeak[ipeak] = idx[0] + idx_want # ------------------------------------------- # to be confirm with mne implementation # ------------------------------------------- ecg_events = np.c_[ixpeak, np.zeros(npeak), np.zeros(npeak)+event_id] return ecg_events.astype(int)
def segment(dir): read_dir = dir save_dir = dir err_dir = dir file_list = listdir(read_dir) print("total original image number " + str(len(file_list))) file_list.sort() # print file_list count = 0 for filename in file_list: print("processing image No." + str(count)) # print(filename) img = cv2.imread(read_dir + '/' + filename) origin = img.copy() gray1 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) gray = cv2.equalizeHist(gray1) width, height = gray1.shape groups = [range(0, width - 1), \ range(int(np.rint(width * 0.0)), int(np.rint(width * 0.25))), \ range(int(np.rint(width * 0.25)), int(np.rint(width * 0.5))), \ range(int(np.rint(width * 0.5)), int(np.rint(width * 0.75))), \ range(int(np.rint(width * 0.75)), width - 1)] left = 0 right = height - 1 for index_range in groups: found_solution = False average = np.mean(gray1[index_range, :], axis=0) sigma = 20 sig2 = 10 points = [] last = 0 while (len(points) != 2): filtered = gaussian_filter1d(average, sigma, truncate=2 * sigma) filtered = gaussian_filter1d(filtered, sig2, truncate=2 * sig2) minima = extrema(filtered, np.less) points = minima[0] if len(points) < 2: sigma = max(sigma - 1, 1) sig2 = max(sig2 - 1, 1) elif len(points) > 2: sigma = min(sigma + 1, 30) sig2 = min(sig2 + 1, 30) if len(points) < 2: sigma = max(sigma - 1, 1) sig2 = max(sig2 - 1, 1) if last == 1: break last = -1 elif len(points) > 2: sigma = min(sigma + 1, 30) sig2 = min(sig2 + 1, 30) if last == -1: break last = 1 else: found_solution = True if sigma == 1 and sig2 == 1: # print("low limit reached") break if sigma == 30 and sig2 == 30: # print("high limit reached") break if found_solution: if 120 < abs(points[0] - points[1]) < 300: if points[0] > points[1]: left = points[1] right = points[0] else: left = points[0] right = points[1] break if not found_solution or (abs(points[0] - points[1]) > 300 or abs(points[0] - points[1]) < 100): print("did not find boundary!") out = img outfile_ = err_dir + '/' + filename # cv2.imwrite(outfile_, out) else: out = img[:, left:right, :] outfile_ = save_dir + '/' + str(count) + '.png' # cv2.imwrite(outfile_, out) count = count + 1 return (out, left, right)
def get_peak_ecg(ecg, sfreq=1017.25, flow=10, fhigh=20, pct_thresh=95.0, default_peak2peak_min=0.5, event_id=999): # ------------------------------------------- # import necessary modules # ------------------------------------------- from mne.filter import filter_data from jumeg.jumeg_math import calc_tkeo from scipy.signal import argrelextrema as extrema # ------------------------------------------- # filter ECG to get rid of noise and drifts # ------------------------------------------- fecg = filter_data(ecg, sfreq, flow, fhigh, n_jobs=1, method='fft') ecg_abs = np.abs(fecg) # ------------------------------------------- # apply Teager Kaiser energie Operator (TKEO) # ------------------------------------------- tk_ecg = calc_tkeo(fecg) # ------------------------------------------- # find all peaks of abs(EOG) # since we don't know if the EOG lead has a # positive or negative R-peak # ------------------------------------------- ixpeak = extrema(tk_ecg, np.greater, axis=0) # ------------------------------------------- # threshold for |R-peak| # ------------------------------------------ peak_thresh_min = np.percentile(tk_ecg, pct_thresh, axis=0) ix = np.where(tk_ecg[ixpeak] > peak_thresh_min)[0] npeak = len(ix) if (npeak > 1): ixpeak = ixpeak[0][ix] else: return -1 # ------------------------------------------- # threshold for max Amplitude of R-peak # fixed to: median + 3*stddev # ------------------------------------------- mag = fecg[ixpeak] mag_mean = np.median(mag) if (mag_mean > 0): nstd = 3 else: nstd = -3 peak_thresh_max = mag_mean + nstd * np.std(mag) ix = np.where(ecg_abs[ixpeak] < np.abs(peak_thresh_max))[0] npeak = len(ix) if (npeak > 1): ixpeak = ixpeak[ix] else: return -1 # ------------------------------------------- # => test if the R-peak is positive or negative # => we assume the the R-peak is the largest peak !! # # ==> sometime we have outliers and we should check # the number of npos and nneg peaks -> which is larger? -> note done yet # -> we assume at least 2 peaks -> maybe we should check the ratio # ------------------------------------------- ixp = np.where(fecg[ixpeak] > 0)[0] npos = len(ixp) ixn = np.where(fecg[ixpeak] < 0)[0] nneg = len(ixp) if (npos == 0 and nneg == 0): import pdb pdb.set_trace() if (npos > 3): peakval_pos = np.abs(np.median(ecg[ixpeak[ixp]])) else: peakval_pos = 0 if (nneg > 3): peakval_neg = np.abs(np.median(ecg[ixpeak[ixn]])) else: peakval_neg = 0 if (peakval_pos > peakval_neg): ixpeak = ixpeak[ixp] ecg_pos = ecg else: ixpeak = ixpeak[ixn] ecg_pos = -ecg npeak = len(ixpeak) if (npeak < 1): return -1 # ------------------------------------------- # check if we have peaks too close together # ------------------------------------------- peak_ecg = ixpeak / sfreq dur = (np.roll(peak_ecg, -1) - peak_ecg) ix = np.where(dur > default_peak2peak_min)[0] npeak = len(ix) if (npeak < 1): return -1 ixpeak = np.append(ixpeak[0], ixpeak[ix]) peak_ecg = ixpeak / sfreq dur = (peak_ecg - np.roll(peak_ecg, 1)) ix = np.where(dur > default_peak2peak_min)[0] npeak = len(ix) if (npeak < 1): return -1 ixpeak = np.unique(np.append(ixpeak, ixpeak[ix[npeak - 1]])) npeak = len(ixpeak) # ------------------------------------------- # search around each peak if we find # higher peaks in a range of 0.1 s # ------------------------------------------- seg_length = np.ceil(0.1 * sfreq) for ipeak in range(0, npeak - 1): idx = [ int(np.max([ixpeak[ipeak] - seg_length, 0])), int(np.min([ixpeak[ipeak] + seg_length, len(ecg)])) ] idx_want = np.argmax(ecg_pos[idx[0]:idx[1]]) ixpeak[ipeak] = idx[0] + idx_want # ------------------------------------------- # to be confirm with mne implementation # ------------------------------------------- ecg_events = np.c_[ixpeak, np.zeros(npeak), np.zeros(npeak) + event_id] return ecg_events.astype(int)
def firstone(imfs, draw=0): extrema_upper_index_vector = [] # record, make no sense extrema_lower_index_vector = [] forecast_value_vector = [] imfsums = [] for n in np.arange( 1 ): ########################################################################## # try to figure out the trend and give prediction # ---------wash the extremas---------------------------------------------------- extrema_upper_index = extrema(imfs[n], np.greater_equal)[0] # max extrema neighbours = [] imfsums.append(np.sum(imfs[n])) for i in np.arange(len(extrema_upper_index) - 1): # clean the indexes which close to each other if extrema_upper_index[i] - extrema_upper_index[i + 1] == -1: neighbours.append(i) extrema_upper_index = np.delete(extrema_upper_index, neighbours) extrema_upper_index = np.delete( extrema_upper_index, np.where((extrema_upper_index == 0) | (extrema_upper_index == len(imfs[n]) - 1))) neighbours = [] extrema_lower_index = extrema(imfs[n], np.less_equal)[0] # min exrema for i in np.arange(len(extrema_lower_index) - 1): # clean the indexes which close to each other if extrema_lower_index[i] - extrema_lower_index[i + 1] == -1: neighbours.append(i) extrema_lower_index = np.delete(extrema_lower_index, neighbours) extrema_lower_index = np.delete( extrema_lower_index, np.where((extrema_lower_index == 0) | (extrema_lower_index == len(imfs[n] - 1) - 1))) if draw == 1: extrema_upper_index_vector.append(extrema_upper_index) extrema_lower_index_vector.append(extrema_lower_index) # ------------------------ the derivation starts from here--------------------- # --some basic calculations --------# extrema_upper_value = imfs[n][extrema_upper_index] extrema_lower_value = imfs[n][extrema_lower_index] extremas = np.unique( np.hstack([extrema_upper_index, extrema_lower_index])) if extremas.any(): last_extrema = extremas[-1] else: last_extrema = len(imfs[n]) - 1 if len(extrema_upper_index) + len( extrema_lower_index) <= 0: # if there is no real extrema distance = last_extrema # means that there is no enough extremas to do the calculation amplitude_upper_ema = max(imfs[n]) amplitude_lower_ema = min(imfs[n]) step = abs(amplitude_upper_ema - amplitude_lower_ema) / distance forecast_value = imfs[n][-1] + step * ( imfs[n][-1] - imfs[n][-2]) / abs( (imfs[n][-1] - imfs[n][-2])) # just extend the tread elif len(extrema_upper_index) + len( extrema_lower_index) == 1: # if there is only one extrema distance = len(imfs[n]) - last_extrema amplitude_upper_ema = max(imfs[n][last_extrema], imfs[n][-1]) amplitude_lower_ema = min(imfs[n][last_extrema], imfs[n][-1]) step = abs(amplitude_upper_ema - amplitude_lower_ema) / distance # reference_amplitude = abs(imfs[n][-1]) + 2 * step forecast_value = imfs[n][-1] + step * ( imfs[n][-1] - imfs[n][-2]) / abs( (imfs[n][-1] - imfs[n][-2])) # also, extend is the best way else: # if there are more than two extremas amplitude_upper_ema = ema( extrema_upper_value, alpha=0.6) # whether use ema is a good thing here? amplitude_lower_ema = ema( extrema_lower_value, alpha=0.6) # whether use ema is a good thing here? nextremas = min(len(extrema_lower_index), len(extrema_upper_index)) distance_set = abs(extrema_upper_index[-nextremas:] - extrema_lower_index[-nextremas:]) distance = ema( distance_set, alpha=0.6 ) # here as well, not so sure whether ema is better though step = abs(amplitude_upper_ema - amplitude_lower_ema) / distance reference_amplitude = abs(amplitude_lower_ema) * 0.25 + abs( amplitude_upper_ema) * 0.25 + abs(imfs[n][last_extrema]) * 0.5 if imfs[n][-1] * imfs[n][ last_extrema] < 0: # if the last point has already crossed the axis if abs(imfs[n][-1]) >= 0.8 * reference_amplitude and abs( imfs[n][-1]) + step > 1.3 * reference_amplitude: forecast_value = imfs[n][-1] + step * (-abs(imfs[n][-1]) / imfs[n][-1]) else: forecast_value = reference_amplitude * (abs(imfs[n][-1]) / imfs[n][-1]) else: forecast_value = imfs[n][-1] + step * ( imfs[n][-1] - imfs[n][-2]) / abs( (imfs[n][-1] - imfs[n][-2])) if abs(forecast_value) >= abs(imfs[n][last_extrema]) * 1.1: forecast_value = abs(imfs[n][last_extrema]) * 1.1 * ( -abs(imfs[n][-1]) / imfs[n][-1]) return forecast_value
def pointprediction( differsets, draw=0): # forecast the next differ of members in differsets emd = EMD() forecast_result = [] imfset = [] imfsumset = [] for loop in np.arange(len(differsets)): imfs = emd(differsets[loop]) # do the EMD nimfs = len(imfs) imfset.append(imfs[0]) extrema_upper_index_vector = [] # record, make no sense extrema_lower_index_vector = [] forecast_value_vector = [] imfsums = [] for n in np.arange(nimfs): # try to figure out the trend and give prediction #---------wash the extremas---------------------------------------------------- extrema_upper_index = extrema(imfs[n], np.greater_equal)[0] # max extrema neighbours = [] imfsums.append(np.sum(imfs[n])) for i in np.arange( len(extrema_upper_index) - 1): # clean the indexes which close to each other if extrema_upper_index[i] - extrema_upper_index[i + 1] == -1: neighbours.append(i) extrema_upper_index = np.delete(extrema_upper_index, neighbours) extrema_upper_index = np.delete( extrema_upper_index, np.where((extrema_upper_index == 0) | (extrema_upper_index == len(imfs[n]) - 1))) neighbours = [] extrema_lower_index = extrema(imfs[n], np.less_equal)[0] # min exrema for i in np.arange( len(extrema_lower_index) - 1): # clean the indexes which close to each other if extrema_lower_index[i] - extrema_lower_index[i + 1] == -1: neighbours.append(i) extrema_lower_index = np.delete(extrema_lower_index, neighbours) extrema_lower_index = np.delete( extrema_lower_index, np.where((extrema_lower_index == 0) | (extrema_lower_index == len(imfs[n] - 1) - 1))) if draw == 1: extrema_upper_index_vector.append(extrema_upper_index) extrema_lower_index_vector.append(extrema_lower_index) #------------------------ the derivation starts from here--------------------- #--some basic calculations --------# extrema_upper_value = imfs[n][extrema_upper_index] extrema_lower_value = imfs[n][extrema_lower_index] extremas = np.unique( np.hstack([extrema_upper_index, extrema_lower_index])) if extremas.any(): last_extrema = extremas[-1] else: last_extrema = len(imfs[n]) - 1 if len(extrema_upper_index) + len( extrema_lower_index) <= 0: # if there is no real extrema distance = last_extrema # means that there is no enough extremas to do the calculation amplitude_upper_ema = max(imfs[n]) amplitude_lower_ema = min(imfs[n]) step = abs(amplitude_upper_ema - amplitude_lower_ema) / distance forecast_value = imfs[n][-1] + step * ( imfs[n][-1] - imfs[n][-2]) / abs( (imfs[n][-1] - imfs[n][-2])) # just extend the tread elif len(extrema_upper_index) + len( extrema_lower_index) == 1: # if there is only one extrema distance = len(imfs[n]) - last_extrema amplitude_upper_ema = max(imfs[n][last_extrema], imfs[n][-1]) amplitude_lower_ema = min(imfs[n][last_extrema], imfs[n][-1]) step = abs(amplitude_upper_ema - amplitude_lower_ema) / distance #reference_amplitude = abs(imfs[n][-1]) + 2 * step forecast_value = imfs[n][-1] + step * ( imfs[n][-1] - imfs[n][-2]) / abs( (imfs[n][-1] - imfs[n][-2])) # also, extend is the best way else: # if there are more than two extremas amplitude_upper_ema = ema( extrema_upper_value, alpha=0.6) # whether use ema is a good thing here? amplitude_lower_ema = ema( extrema_lower_value, alpha=0.6) # whether use ema is a good thing here? nextremas = min(len(extrema_lower_index), len(extrema_upper_index)) distance_set = abs(extrema_upper_index[-nextremas:] - extrema_lower_index[-nextremas:]) distance = ema( distance_set, alpha=0.6 ) # here as well, not so sure whether ema is better though step = abs(amplitude_upper_ema - amplitude_lower_ema) / distance reference_amplitude = abs(amplitude_lower_ema) * 0.25 + abs( amplitude_upper_ema) * 0.25 + abs( imfs[n][last_extrema]) * 0.5 if imfs[n][-1] * imfs[n][ last_extrema] < 0: # if the last point has already crossed the axis if abs(imfs[n][-1]) >= 0.8 * reference_amplitude and abs( imfs[n][-1]) + step > 1.3 * reference_amplitude: forecast_value = imfs[n][-1] + step * ( -abs(imfs[n][-1]) / imfs[n][-1]) else: forecast_value = reference_amplitude * ( abs(imfs[n][-1]) / imfs[n][-1]) else: forecast_value = imfs[n][-1] + step * ( imfs[n][-1] - imfs[n][-2]) / abs( (imfs[n][-1] - imfs[n][-2])) if abs(forecast_value) >= abs(imfs[n][last_extrema]) * 1.1: forecast_value = abs(imfs[n][last_extrema]) * 1.1 * ( -abs(imfs[n][-1]) / imfs[n][-1]) forecast_value_vector.append(forecast_value) imfsumset.append(imfsums) forecast_result.append((sum(forecast_value_vector))) #-------------------------the derivation is done------------------------------ # a drawing to show some result for bugging if draw == 1: size = imfs.shape x = np.arange(len(differsets[0])) plt.figure() plt.plot(x, differsets[0], marker='.', markerfacecolor='blue', markersize=6) plt.show() plt.figure(figsize=(20, 18)) for loop in range(1, size[0] + 1): plt.subplot(size[0], 1, loop) plt.plot(x, imfs[loop - 1], marker='.', markerfacecolor='blue', markersize=6) plt.scatter(extrema_upper_index_vector[loop - 1], imfs[loop - 1][extrema_upper_index_vector[loop - 1]], c='red', marker='+', s=50) plt.scatter(extrema_lower_index_vector[loop - 1], imfs[loop - 1][extrema_lower_index_vector[loop - 1]], marker='+', color='green', s=50) plt.scatter(x[-1] + 1, forecast_value_vector[loop - 1], marker='o', c='black', s=50) plt.hlines(0, 0, len(differsets[0]), colors="black", linestyles="--") plt.title(loop) plt.show() return forecast_value_vector, forecast_result return forecast_result, imfset, imfsumset
range(int(np.rint(width*0.5)), int(np.rint(width*0.75))), \ range(int(np.rint(width*0.75)), width-1)] left = 0 right = height - 1 for index_range in groups: found_solution = False average = np.mean(gray1[index_range, :], axis=0) sigma = 20 sig2 = 10 points = [] last = 0 while(len(points) != 2): filtered = gaussian_filter1d(average, sigma, truncate=2*sigma) filtered = gaussian_filter1d(filtered, sig2, truncate=2*sig2) minima = extrema(filtered, np.less) points = minima[0] if len(points) < 2: sigma = max(sigma - 1, 1) sig2 = max(sig2 - 1, 1) elif len(points) > 2: sigma = min(sigma + 1, 30) sig2 = min(sig2 + 1, 30) if len(points) < 2: sigma = max(sigma - 1, 1) sig2 = max(sig2 - 1, 1) if last == 1: break last = -1 elif len(points) > 2: