I want to find pattern in some spectra.
Spectrum image
Pattern should look like 2 in gray circles on picture, all data looks similarly. Light blue line is the original data, dotted dark blue line - average over 6 points. I was trying to do window with some size and scan data and check whether the y-flux value drops/rise below 60 ish % but that seems to find other regions and the one that I want, or only this I don't want.
The width of pattern is not always the same in spectra that I have. There is a picture of spectrum with pattern black dashed line but my program didn't found it.
not found picture
I tried changing size of window but it doesn't help. Can I use some pattern recognition algorithm to find this patterns? Could somebody point me in some direction? Or explain in easy way since I'm kinda lost in this, please?
That's my code:
import numpy as np
import matplotlib.pyplot as plt
from astropy.io import ascii
import glob
def reading(file_name):
data = ascii.read(file_name)
lam = data['col0'][1:-1]
#data offset *10**17 + 5
flux = data['col1'][1:-1]*10**17 + 5
return lam, flux
def percentChange(startPoint,currentPoint):
return abs(((currentPoint-startPoint)/startPoint))*100.00
def window(data, size):
n = len(data)
out = []
wind = data[0 : size]
i = size
while i + size/2 < n:
wind = data[i - size/2 : i + size/2]
tmp = percentChange(wind[0], wind[-1])
if tmp > 50.:
out.append([tmp, i - size/2, i + size/2])
i = i + size
return out
def window2(data, size):
n = len(data)
out = []
wind = data[0 : size]
i = size
while i + size/2 < n:
wind = data[i - size/2 : i + size/2]
tmp = percentChange(wind[0], wind[len(wind)/2])
if tmp > 50.:
out.append([tmp, i - size/2, i + size/2])
i = i + size
return out
def plotting(lamb, flux):
plt.rcParams['font.family'] = 'freeserif'
plt.rcParams['font.size'] = 12
plt.rcParams['axes.labelsize'] = 15
plt.rcParams['xtick.labelsize'] = 12
plt.rcParams['ytick.labelsize'] = 12
plt.rcParams['legend.fontsize'] = 12
plt.rcParams['figure.titlesize'] = 12
plt.rcParams['xtick.minor.visible'] = True
plt.rcParams['ytick.minor.visible'] = True
plt.plot(lamb, flux)
plt.xlabel("wavelenght [A]")
plt.ylabel("flux [erg/cm^2/s/A]")
def averaging(lamb, flux, param):
end = 1480
bin_flux_1 = [np.mean(flux[i : i + param]) for i in range(0, end, param)]
bin_lam_1 = [np.mean(lamb[i : i + param]) for i in range(0, end, param)]
return bin_lam_1, bin_flux_1
def main():
param = 6
stack = 6
for name in glob.glob('TRAIN/*.dat'):
print name
lamb, flux = reading(name)
lamb_a, flux_a = averaging(lamb, flux, param)
plotting(lamb, flux)
plotting(lamb_a, flux_a)
change = window(flux_a, stack)
change2 = window2(flux_a, stack)
minim = flux_a.index(min(flux_a))
for i in range(len(change)):
plt.axvline(lamb_a[change[i][1]], color='r', linestyle='--',linewidth=1)
plt.axvline(lamb_a[change[i][2]], color='r', linestyle='--',linewidth=1)
for i in range(len(change2)):
plt.axvline(lamb_a[change2[i][1]], color='y', linestyle='-',linewidth=1)
plt.axvline(lamb_a[change2[i][2]], color='y', linestyle='-',linewidth=1)
plt.axvline(lamb_a[minim], color='k', linestyle='--',linewidth=1)
plt.show()
if __name__ == "__main__":
main()
You can do it by using Knuth–Morris–Pratt algorithm in linear O(n + m) time complexity where n and m are the lengths of text and pattern.
KMP algorithm is basically a pattern matching algorithm (finding the starting position of a needle in haystack) which works on character string.
def kmp_matcher(t, d):
n=len(t)
m=len(d)
pi = compute_prefix_function(d)
q = 0
i = 0
while i < n:
if d[q]==t[i]:
q=q+1
i = i + 1
else:
if q != 0:
q = pi[q-1]
else:
i = i + 1
if q == m:
print "pattern occurs with shift "+str(i-q)
q = pi[q-1]
def compute_prefix_function(p):
m=len(p)
pi =range(m)
k=1
l = 0
while k < m:
if p[k] <= p[l]:
l = l + 1
pi[k] = l
k = k + 1
else:
if l != 0:
l = pi[l-1]
else:
pi[k] = 0
k = k + 1
return pi
t = 'brownfoxlazydog'
p = 'lazy'
kmp_matcher(t, p)
Related
I am writing a function that scales the input image into times of
its input size. The function Resize(Mat I, float s) first fills in the and Mat’s
that contained the query point coordinates. Then I calculate the query value by
using bilinear interpolation.
The output image seems to be alright except it has an unexpected # shape grid on it. Can you provide any hint for the resolution?
Output image:
Code:
import numpy as np
import cv2 as cv
import math
import matplotlib.pyplot as plt
#Mat I, float s
def Resize(I, s):
orig_x = I.shape[0];
orig_y = I.shape[1];
tar_x = int (orig_x * s) #int tar_x and tar_y
tar_y = int (orig_y * s);
#print(tar_x)
# Query points
X = np.empty((tar_y, tar_x), np.float32)
Y = np.empty((tar_y, tar_x), np.float32)
# calc interval between output points
interval = (orig_x-1) / (tar_x-1)
# Setting the query points
for i in range(0, tar_y):
for j in range(0, tar_x):
#set X[i, j] and Y[i,j]
X[i][j] = j * interval
Y[i][j] = i * interval
# Output image
output = np.empty((tar_y, tar_x), np.uint8)
# Performing the interpolation
for i in range(0, tar_y):
for j in range(0, tar_x):
#set output[i,j] using X[i, j] and Y[i,j]
x = X[i][j]
y = Y[i][j]
x1 = math.floor(x)
x2 = math.ceil(x)
y1 = math.floor(y)
y2 = math.ceil(y)
vq1= (x-x1)*I[y1,x2] + (x2-x)*I[y1,x1]
vq2= (x-x1)*I[y2,x2] + (x2-x)*I[y2,x1]
output[i,j] = (y-y1)*vq2 + (y2-y)*vq1
return output
s= 640 / 256
I = cv.imread("aerial_256.png", cv.IMREAD_GRAYSCALE)
output = Resize(I,s)
output = cv.cvtColor(output, cv.COLOR_BGR2RGB)
plt.imshow(output)
plt.savefig("aerial_640.png",bbox_inches='tight',transparent=True, pad_inches=0)
plt.show()
You are getting a black pixel where x is an integer and where y is an integer.
Take a look at the following code:
x1 = math.floor(x)
x2 = math.ceil(x)
vq1= (x-x1)*I[y1,x2] + (x2-x)*I[y1,x1]
vq2= (x-x1)*I[y2,x2] + (x2-x)*I[y2,x1]
Assume: x = 85.0
x1 = floor(x) = 85
x2 = ceil(x) = 85
(x-x1) = (85-85) = 0
(x2-x) = (85-85) = 0
vq1 = (x-x1)*I[y1,x2] + (x2-x)*I[y1,x1] = 0*I[y1,x2] + 0*I[y1,x1] = 0
vq2 = (x-x1)*I[y2,x2] + (x2-x)*I[y2,x1] = 0*I[y2,x2] + 0*I[y2,x1] = 0
output[i,j] = (y-y1)*vq2 + (y2-y)*vq1 = (y-y1)*0 + (y2-y)*0 = 0
Result:
In the entire column where x = 85.0 the value of output[i,j] is zero (we are getting a black column).
Same result applied to y = 85.0 - we are getting a black row.
When does x value is an integer?
Take a look at the following code:
# calc interval between output points
interval = (orig_x-1) / (tar_x-1)
# Setting the query points
for i in range(0, tar_y):
for j in range(0, tar_x):
#set X[i, j] and Y[i,j]
X[i][j] = j * interval
interval = (orig_x-1) / (tar_x-1) = 255/639 = (3*5*17/(3*3*71) = 85/213
j * interval = j * 85/213
Each time j is a multiple of 213, j * interval is an integer (we are getting a black column).
It happens when j=0, j=213, j=426, j=639, so there are two black columns (beside margins).
There are also two visible black rows (beside margins).
Suggested solution:
Replace x2 = math.ceil(x) with x2 = min(x1 + 1, orig_x-1).
Replace y2 = math.ceil(y) with y2 = min(y1 + 1, orig_y-1).
Corrected loop:
for i in range(0, tar_y):
for j in range(0, tar_x):
#set output[i,j] using X[i, j] and Y[i,j]
x = X[i][j]
y = Y[i][j]
x1 = math.floor(x)
x2 = min(x1 + 1, orig_x-1)
y1 = math.floor(y)
y2 = min(y1 + 1, orig_y-1)
vq1= (x-x1)*I[y1,x2] + (x2-x)*I[y1,x1]
vq2= (x-x1)*I[y2,x2] + (x2-x)*I[y2,x1]
output[i,j] = (y-y1)*vq2 + (y2-y)*vq1
Result:
As you can see below, I have a Monte Carlo calculation using M = 1000 so printing whether a step was left or right results in a very long list. Instead I’d like to print “Right = x” and “Left = y ” x and y being the amount of times the Walker stepped left and right.
I do not know how to go about that. Some help would be appreciated, Thank you!!
Here’s what i have so far
def Random_Walker(N, p, s):
x = 0 # Walker starts from rest
for i in range(N):
if(np.random.rand() < p):
print("right", count)
x = x + s
else:
print("left")
x = x - s
return(x)
# Defining the main part of the code
def main():
import numpy as np
# Defining variables
N = 50 # Number of steps before stopping
p = 0.66 # Probability of stepping right
s = 0.75 # Length of a step in meters
M = 1000 # Number of walks
X = np.zeros(M)
for i in range(M):
X[i] = Random_Walker(N, p, s)
print(X)
print("Mean = ", np.mean(X))
print("Standard Deviation = ", np.std(X))
main()
Here's an attempt. I haven't tried to run it:
def Random_Walker(N, p, s):
x = 0 # Walker starts from rest
lcount = 0
rcount = 0
for i in range(N):
if(np.random.rand() < p):
print("right", count)
rcount += 1
x = x + s
else:
print("left")
lcount += 1
x = x - s
return (x, lcount, rcount)
# Defining the main part of the code
def main():
import numpy as np
# Defining variables
N = 50 # Number of steps before stopping
p = 0.66 # Probability of stepping right
s = 0.75 # Length of a step in meters
M = 1000 # Number of walks
X = np.zeros(M)
for i in range(M):
X[i], lcount, rcount = Random_Walker(N, p, s)
print (f"Walker {i} L/R ratio: {lcount}/{rcount}")
print(X)
print("Mean = ", np.mean(X))
print("Standard Deviation = ", np.std(X))
main()
I am trying to implement the S1 measure (Spectral Measure of Sharpness - Section III-A) from this paper. Here we have to calculate slope (alpha) of the magnitude spectrum for an image in order to measure sharpness. I am able to write the other part of the algorithm, but unable to calculate the slope. Here is my code. Function 'alpha' is where I calculate the magnitude_spectrum and I think using this we can calculate the slope but am not sure how to do that -
def aplha(image_block):
img_float32 = np.float32(image_block)
dft = cv2.dft(img_float32, flags = cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
magnitude_spectrum = 20*np.log(cv2.magnitude(dft_shift[:,:,0],dft_shift[:,:,1]))
return output (??)
Rest of the code:
def S1_calc(alpha):
tou1 = -3
tou2 = 2
output = 1 - (1 / (1 + np.exp(tou1 * (alpha - tou2))))
return output
def lx(image_block):
b = 0.7656
k = 0.0364
y = 2.2
return np.power((b + k * image_block), y)
def contrast(lx_val):
T1 = 5
T2 = 2
max_val = np.max(lx_val)
min_val = np.min(lx_val)
mean_val = np.mean(lx_val)
return (((max_val - min_val) < T1) or (mean_val < T2))
def image_gray(image_RGB):
output = (0.2989 * image_RGB[:,:,0] +
0.5870 * image_RGB[:,:,1] +
0.1140 * image_RGB[:,:,2])
return output
def S1(gray_image, m = 32, d = 24):
### SPECTRAL MEASURE OF SHARPNESS ###
# m = each block size
# d = overlapping pixels of neighbouring blocks
h,w = gray_image.shape
output = gray_image.copy()
row = 0
while (row < h):
col = 0
while (col < w):
top = row
bottom = min(row + m, h)
left = col
right = min(col + m, w)
image_block = gray_image[top : bottom, left : right]
lx_val = lx(image_block)
contrast_bool = contrast(lx_val)
if contrast_bool==True:
output[top : bottom, left : right] = 0
else:
alpha_val = aplha(image_block)
output[top : bottom, left : right] = S1_calc(alpha_val)
col = col + m - d
row = row + m - d
return output
Am using jupyter notebook, python 3.6
You could check this MATLAB code. See also another MATLAB code.
According to the latter one, we need to know freq and power value, and then we could fit these two var with a linear function, the slope of the line is what we need. We could get the slope with np.polyfit.
Now, our question is how to get the freq of a image, you could do this:
from skimage.data import camera
import numpy as np
image = camera()
height, width = image.shape
u, v = np.meshgrid(np.arange(height // 2), np.arange(width // 2))
freq = np.round(np.sqrt(u**2 + v**2)).astype(np.int64)
Now freq should be the same shape as fft transform of the input image. You need to sum all value of the magnitude_spectrum where they have the same freq, like this:
freq_uniq = np.unique(freq.flatten())
y = []
for value in f_uniq:
y.append(magnitude_spectrum[f == value].sum())
y = np.array(y)
Finally, you could just fit freq_uniq and y and get the slope. You might need to scale them with np.log first.
I am trying to create a program that solves the mass-spring-damper system using backward differentiating, the only problem is that I am running into an index error that I am not sure how to solve:
import numpy as np
import matplotlib.pyplot as plt
def MSD_Solver(m,b,K):
#input: m = mass, b = damping ratio, K = spring constant
#output: (t,x) time vs position
tinitial = 0
tfinal = 15
step = .005
t = np.linspace(tinitial,tfinal,step)
x = np.zeros_like(t)
x[0]=0
x[1]=0
for k in range (len(t)-1): # extra element so subtract by 1
x[k] = (t**2)/((m+b)*t+(t**2)*k) + (x[k-2](-m))/((m+b)*t+(t**2)*k) + (x[k-1]((2*m)+(b*t)))/((m+b)*t+(t**2)*k)
return plt.plot(t,x)
print(MSD_Solver(1,.5,5)),MSD_Solver(1,1,5),MSD_Solver(1,2,5)
plt.show()
The linspace doc shows that the third argument is the number of items, not the step. Your step value got truncated to 0, so the returned array for t was empty. As a result, x has no elements, and x[0] is out of range.
Try this:
tinitial = 0
tfinal = 15
step = .005
num = (tfinal - tinitial) / step + 1
t = np.linspace(tinitial,tfinal,num)
This will get you to the semantic errors in your complex computation.
You want, probably(?), use first and second order difference quotients to discretize
m*x''(t) + b*x'(t) + K*x(t) = 1
to
m*(x[j+1]-2*x[j]+x[j-1]) + 0.5*dt*b*(x[j+1]-x[j-1]) + dt^2*K*x[j] = dt**2
so that
x[j+1] = ( dt**2 + (2*m-K*dt**2)*x[j] - (m-0.5*dt*b)*x[j-1] ) / (m+0.5*dt*b)
In code
def MSD_Solver(m,b,K):
#input: m = mass, b = damping ratio, K = spring constant
#output: (t,x) time vs position
tinitial = 0
tfinal = 15
step = .005
t = np.arange(tinitial,tfinal,step)
x = np.zeros_like(t)
dt = t[1]-t[0] # use the actual time step
x[0:2] = [ 0, 0]
for j in range(1,len(t)-1):
x[j+1] = ( dt**2 + (2*m-K*dt**2)*x[j] - (m-0.5*dt*b)*x[j-1] ) / (m+0.5*dt*b)
return t,x
t,x = MSD_Solver(1,.5,5)
plt.plot(t,x); plt.show();
I am studying about neural network tutorial and made simple perceptron code like this below
The purpose is
Spliting 20 points into two groups.
perceptron.py
import numpy as np
from pprint import pprint
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
from tensorflow.contrib.learn.python.learn.tests.dataframe.mocks import Mock2x2Transform
plt.style.use('ggplot')
font = {'family' : 'meiryo'}
matplotlib.rc('font', **font)
rng = np.random.RandomState(123)
d = 2 #dimension
N = 10 # each group items
mean = 5
x1 = rng.randn(N,d) + np.array([0,0]) # group 0
x2 = rng.randn(N,d) + np.array([mean,mean]) $group 1
x = np.concatenate((x1,x2),axis = 0)
##### Plot points
allDf = pd.DataFrame(columns=['x','y'])
k = 0
for i in x:
print(i[0])
temp = pd.DataFrame({'x' : i[0],
'y' : i[1]},index=[k])
k = k + 1
allDf = pd.concat([allDf,temp])
pprint(allDf)
allDf.plot(kind='scatter',x = 'x',y='y')
#########
#initialize w b
w = np.zeros(d)
b = 0
def y(x):
return step(np.dot(w,x) + b)
def step(x):
return 1 * (x > 0)
def t(i):
if i < N:
return 0
else:
return 1
while True:
classified = True
for i in range(N * 2):
delta_w = (t(i) - y(x[i])) * x[i]
delta_b = (t(i) - y(x[i]))
w += delta_w
b += delta_b
classified *= all(delta_w == 0 ) * (delta_b == 0)
if classified:
print("Final answer")
pprint(w)
pprint(b) # I get the answer here but how can I plot this w and b
X = np.linspace(-2,6,100) # it's wrong!!
Y = (w[0] * X + w[1] * X) - b # it's wrong!!
plt.plot(X,Y)
plt.show()
break
This source code gives me
the final answer like this
w = array([ 2.14037745, 1.2763927 ])
b = -9
But how can I plot this??
I want to make line between two groups.
The final graph(line) is supposed to be like this