Skip to content

Commit f08fe66

Browse files
author
BB
committed
-
1 parent 56023ed commit f08fe66

File tree

1 file changed

+277
-0
lines changed

1 file changed

+277
-0
lines changed

compscieng/compscieng_2_11/tst4.py

Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
import pandas as pd
2+
import numpy as np
3+
import matplotlib.pyplot as plt
4+
from numpy import *
5+
from scipy import ndimage
6+
7+
def bilinear_interpolate(im, x, y):
8+
x = np.asarray(x)
9+
y = np.asarray(y)
10+
11+
x0 = np.floor(x).astype(int)
12+
x1 = x0 + 1
13+
y0 = np.floor(y).astype(int)
14+
y1 = y0 + 1
15+
16+
x0 = np.clip(x0, 0, im.shape[1]-1);
17+
x1 = np.clip(x1, 0, im.shape[1]-1);
18+
y0 = np.clip(y0, 0, im.shape[0]-1);
19+
y1 = np.clip(y1, 0, im.shape[0]-1);
20+
21+
Ia = im[ y0, x0 ]
22+
Ib = im[ y1, x0 ]
23+
Ic = im[ y0, x1 ]
24+
Id = im[ y1, x1 ]
25+
26+
wa = (x1-x) * (y1-y)
27+
wb = (x1-x) * (y-y0)
28+
wc = (x-x0) * (y1-y)
29+
wd = (x-x0) * (y-y0)
30+
31+
return wa*Ia + wb*Ib + wc*Ic + wd*Id
32+
33+
def grad(M, bound="sym", order=1):
34+
"""
35+
grad - gradient, forward differences
36+
37+
[gx,gy] = grad(M, options);
38+
or
39+
g = grad(M, options);
40+
41+
options.bound = 'per' or 'sym'
42+
options.order = 1 (backward differences)
43+
= 2 (centered differences)
44+
45+
Works also for 3D array.
46+
Assme that the function is evenly sampled with sampling step 1.
47+
48+
See also: div.
49+
50+
Copyright (c) Gabriel Peyre
51+
"""
52+
53+
54+
# retrieve number of dimensions
55+
nbdims = np.ndim(M)
56+
57+
58+
if bound == "sym":
59+
nx = np.shape(M)[0]
60+
if order == 1:
61+
fx = M[np.hstack((np.arange(1,nx),[nx-1])),:] - M
62+
else:
63+
fx = (M[np.hstack((np.arange(1,nx),[nx-1])),:] - M[np.hstack(([0],np.arange(0,nx-1))),:])/2.
64+
# boundary
65+
fx[0,:] = M[1,:]-M[0,:]
66+
fx[nx-1,:] = M[nx-1,:]-M[nx-2,:]
67+
68+
if nbdims >= 2:
69+
ny = np.shape(M)[1]
70+
if order == 1:
71+
fy = M[:,np.hstack((np.arange(1,ny),[ny-1]))] - M
72+
else:
73+
fy = (M[:,np.hstack((np.arange(1,ny),[ny-1]))] - M[:,np.hstack(([0],np.arange(ny-1)))])/2.
74+
# boundary
75+
fy[:,0] = M[:,1]-M[:,0]
76+
fy[:,ny-1] = M[:,ny-1]-M[:,ny-2]
77+
78+
if nbdims >= 3:
79+
nz = np.shape(M)[2]
80+
if order == 1:
81+
fz = M[:,:,np.hstack((np.arange(1,nz),[nz-1]))] - M
82+
else:
83+
fz = (M[:,:,np.hstack((np.arange(1,nz),[nz-1]))] - M[:,:,np.hstack(([0],np.arange(nz-1)))])/2.
84+
# boundary
85+
fz[:,:,0] = M[:,:,1]-M[:,:,0]
86+
fz[:,:,ny-1] = M[:,:,nz-1]-M[:,:,nz-2]
87+
else:
88+
nx = np.shape(M)[0]
89+
if order == 1:
90+
fx = M[np.hstack((np.arange(1,nx),[0])),:] - M
91+
else:
92+
fx = (M[np.hstack((np.arange(1,nx),[0])),:] - M[np.hstack(([nx-1],np.arange(nx-1))),:])/2.
93+
94+
if nbdims >= 2:
95+
ny = np.shape(M)[1]
96+
if order == 1:
97+
fy = M[:,np.hstack((np.arange(1,ny),[0]))] - M
98+
else:
99+
fy = (M[:,np.hstack((np.arange(1,ny),[0]))] - M[:,np.hstack(([ny-1],np.arange(ny-1)))])/2.
100+
101+
if nbdims >= 3:
102+
nz = np.shape(M)[2]
103+
if order == 1:
104+
fz = M[:,:,np.hstack((np.arange(1,nz),[0]))] - M
105+
else:
106+
fz = (M[:,:,np.hstack((np.arange(1,nz),[0]))] - M[:,:,np.hstack(([nz-1],np.arange(nz-1)))])/2.
107+
108+
if nbdims==2:
109+
fx = np.concatenate((fx[:,:,np.newaxis],fy[:,:,np.newaxis]), axis=2)
110+
elif nbdims==3:
111+
fx = np.concatenate((fx[:,:,:,np.newaxis],fy[:,:,:,np.newaxis],fz[:,:,:,np.newaxis]),axis=3)
112+
113+
return fx
114+
115+
def imageplot(f, str='', sbpt=[]):
116+
"""
117+
Use nearest neighbor interpolation for the display.
118+
"""
119+
if sbpt != []:
120+
plt.subplot(sbpt[0], sbpt[1], sbpt[2])
121+
imgplot = plt.imshow(f, interpolation='nearest')
122+
imgplot.set_cmap('gray')
123+
plt.axis('off')
124+
125+
def perform_dijstra_fm(W, pstart, niter=np.inf, method='dijstr', bound='sym', svg_rate=10):
126+
n = W.shape[0]
127+
neigh = np.array([[1, -1, 0, 0], [0, 0, 1, -1]])
128+
129+
def symmetrize(x,n):
130+
if (x<0):
131+
x = -x;
132+
elif (x>=n):
133+
x = 2*(n-1)-x
134+
return x
135+
136+
if bound=='per':
137+
boundary = lambda x: np.mod(x,n)
138+
else:
139+
boundary = lambda x: [symmetrize(x[0],n), symmetrize(x[1],n)] # todo
140+
141+
ind2sub1 = lambda k: [int( (k-np.fmod(k,n))/n ), np.fmod(k,n)]
142+
sub2ind1 = lambda u: int( u[0]*n + u[1] )
143+
Neigh = lambda k,i: sub2ind1(boundary(ind2sub1(k) + neigh[:,i]))
144+
extract = lambda x,I: x[I]
145+
extract1d = lambda x,I: extract(x.flatten(),I)
146+
147+
nstart = pstart.shape[1]
148+
I = list( np.zeros( (nstart, 1) ) )
149+
for i in np.arange(0, nstart):
150+
I[i] = int( sub2ind1(pstart[:,i]) )
151+
152+
D = np.zeros( (n,n) ) + np.inf # current distance
153+
for i in np.arange(0, nstart):
154+
D[pstart[0,i],pstart[1,i]] = 0
155+
156+
S = np.zeros( (n,n) )
157+
for i in np.arange(0, nstart):
158+
S[pstart[0,i],pstart[1,i]] = 1 # open
159+
160+
iter = 0
161+
q = 100 # maximum number of saves
162+
Dsvg = np.zeros( (n,n,q) )
163+
Ssvg = np.zeros( (n,n,q) )
164+
while ( not(I==[]) & (iter<=niter) ):
165+
iter = iter+1;
166+
if iter==niter:
167+
break
168+
j = np.argsort( extract1d(D,I) )
169+
if np.ndim(j)==0:
170+
j = [j]
171+
j = j[0]
172+
i = I[j]
173+
a = I.pop(j)
174+
u = ind2sub1(i);
175+
S[u[0],u[1]] = -1
176+
J = []
177+
for k in np.arange(0,4):
178+
j = Neigh(i,k)
179+
if extract1d(S,j)!=-1:
180+
J.append(j)
181+
if extract1d(S,j)==0:
182+
u = ind2sub1(j)
183+
S[u[0],u[1]] = 1
184+
I.append(j)
185+
DNeigh = lambda D,k: extract1d(D,Neigh(j,k))
186+
for j in J:
187+
dx = min(DNeigh(D,0), DNeigh(D,1))
188+
dy = min(DNeigh(D,2), DNeigh(D,3))
189+
u = ind2sub1(j)
190+
w = extract1d(W,j);
191+
if method=='dijstr':
192+
D[u[0],u[1]] = min(dx + w, dy + w)
193+
else:
194+
Delta = 2*w - (dx-dy)**2
195+
if (Delta>=0):
196+
D[u[0],u[1]] = (dx + dy + np.sqrt(Delta))/ 2
197+
else:
198+
D[u[0],u[1]] = min(dx + w, dy + w)
199+
t = iter/svg_rate
200+
if (np.mod(iter,svg_rate)==0) & (t<q):
201+
print (t)
202+
Dsvg[:,:,int(t-1)] = D
203+
Ssvg[:,:,int(t-1)] = S
204+
205+
Dsvg = Dsvg[:,:,:int(t-1)]
206+
Ssvg = Ssvg[:,:,:int(t-1)]
207+
return (D,Dsvg,Ssvg);
208+
209+
def exo3(x0,W):
210+
"""
211+
Compute the distance map to these starting point using the FM algorithm.
212+
"""
213+
n = W.shape[0]
214+
pstart = transpose(array([x0]))
215+
[D,Dsvg,Ssvg] = perform_dijstra_fm(W, pstart, inf,'fm', 'sym',n*6)
216+
# display
217+
k = 8
218+
displ = lambda D: cos(2*pi*k*D/ max(D.flatten()))
219+
plt.figure()
220+
imageplot(displ(D))
221+
plt.set_cmap('jet')
222+
plt.savefig('out-560.png')
223+
return D
224+
225+
226+
def exo4(tau,x0,x1,G):
227+
"""
228+
Perform the full geodesic path extraction by iterating the gradient
229+
descent. You must be very careful when the path become close to
230+
$x_0$, because the distance function is not differentiable at this
231+
point. You must stop the iteration when the path is close to $x_0$.
232+
"""
233+
n = G.shape[0]
234+
Geval = lambda G,x: bilinear_interpolate(G[:,:,0], imag(x), real(x) ) + 1j * bilinear_interpolate(G[:,:,1],imag(x), real(x))
235+
niter = 1.5*n/tau;
236+
# init gamma
237+
gamma = [x1]
238+
xtgt = x0[0] + 1j*x0[1]
239+
for i in arange(0,niter):
240+
g = Geval(G, gamma[-1] )
241+
gamma.append( gamma[-1] - tau*g )
242+
if abs(gamma[-1]-xtgt)<1:
243+
break
244+
gamma.append( xtgt )
245+
return gamma
246+
247+
248+
n = 100
249+
x = linspace(-1, 1, n)
250+
[Y, X] = meshgrid(x, x)
251+
sigma = .2
252+
W = 1 + 8 * exp(-(X**2 + Y**2)/ (2*sigma**2))
253+
x0 = [round(.1*n), round(.1*n)]
254+
D = exo3(x0,W)
255+
256+
G0 = grad(D)
257+
d = sqrt(sum(G0**2, axis=2))
258+
U = zeros((n,n,2))
259+
U[:,:,0] = d
260+
U[:,:,1] = d
261+
G = G0 / U
262+
tau = .8
263+
x1 = round(.9*n) + 1j*round(.88*n)
264+
gamma = [x1]
265+
266+
Geval = lambda G,x: bilinear_interpolate(G[:,:,0], imag(x), real(x) ) + 1j * bilinear_interpolate(G[:,:,1],imag(x), real(x))
267+
g = Geval(G, gamma[-1] )
268+
gamma.append( gamma[-1] - tau*g )
269+
gamma = exo4(tau,x0,x1,G)
270+
271+
imageplot(W)
272+
plt.set_cmap('gray')
273+
h = plt.plot(imag(gamma), real(gamma), '.b', linewidth=2)
274+
h = plt.plot(x0[1], x0[0], '.r', markersize=20)
275+
h = plt.plot(imag(x1), real(x1), '.g', markersize=20)
276+
plt.savefig('out-760.png')
277+

0 commit comments

Comments
 (0)