Skip to content

Commit 08b6656

Browse files
author
Stefan van der Walt
committed
Development snapshot.
1 parent b75a487 commit 08b6656

File tree

12 files changed

+558
-236
lines changed

12 files changed

+558
-236
lines changed

.bzrignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
supreme/ext/.sconsign.dblite
22
supreme/ext/*.os
3-
build
3+
build
4+
*.os
5+
.sconsign.dblite

supreme/doc/examples/match.py

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import os.path
2+
import glob
3+
4+
from numpy.testing import set_local_path, restore_path
5+
import numpy as N
6+
import pylab as P
7+
8+
set_local_path('../../..')
9+
import supreme as sr
10+
from supreme.config import data_path
11+
restore_path()
12+
13+
print "Reading images and features..."
14+
features = []
15+
images = []
16+
17+
dataset = 'reflectometer'
18+
basename = 'D'
19+
imagetype = 'png'
20+
featuretype = 'sift'
21+
T = 0.6
22+
image_files = sorted(glob.glob(os.path.join(data_path,'%s/%s*.%s' % (dataset,basename,imagetype))))
23+
feature_files = sorted(glob.glob(os.path.join(data_path,'%s/%s*.%s' % (dataset,basename,featuretype))))
24+
25+
images = [sr.imread(fn,flatten=True) for fn in image_files]
26+
features = [sr.feature.SIFT.fromfile(fn,mode=featuretype.upper()) for fn in feature_files]
27+
28+
for pair in zip(image_files,feature_files):
29+
print pair[0], '->', pair[1]
30+
31+
image_plane = N.hstack((images[0],images[1]))
32+
33+
print "Matching features..."
34+
ref = features[0]
35+
tf_matrices = [N.eye(3)]
36+
valid_matrices = [True]
37+
for frame in features[1:]:
38+
match,dist,valid = sr.feature.match(frame['data'],ref['data'],threshold=T)
39+
40+
valid_ref = match[valid]
41+
xf,yf = frame['column'][valid],frame['row'][valid]
42+
xr,yr = ref['column'][valid_ref],ref['row'][valid_ref]
43+
44+
M,ier = sr.register.sparse(yr,xr,yf,xf)
45+
valid_matrices.append(ier == 1)
46+
tf_matrices.append(M)
47+
48+
print "Found %d matches." % valid.sum()
49+
50+
# Adjust coordinates for image plane
51+
rows,cols = images[0].shape
52+
xf += cols
53+
yf = rows - yf
54+
yr = rows - yr
55+
56+
# Display matches
57+
#P.imshow(image_plane,cmap=P.cm.gray)
58+
#P.gca().set_autoscale_on(False)
59+
60+
#P.plot(xf,yf,'.b')
61+
#P.plot(xr,yr,'.r')
62+
#xzip = zip(xf,xr)
63+
#yzip = zip(yf,yr)
64+
#for i in range(len(xzip)):
65+
# P.plot(xzip[i:i+1],yzip[i:i+1],'-w')
66+
#P.show()
67+
68+
images = [i for i,v in zip(images,valid_matrices) if v]
69+
tf_matrices = [t for t,v in zip(tf_matrices,valid_matrices) if v]
70+
71+
# Scale for super-resolution
72+
scale = 3
73+
for M in tf_matrices:
74+
M[:2,:] *= scale
75+
oshape = N.ceil(N.array(images[0].shape)*scale).astype(int)
76+
77+
for img in images:
78+
img -= img.min()
79+
print "Reconstructing using interpolation..."
80+
out1 = sr.register.stack.with_transform(images,tf_matrices,oshape=oshape)
81+
82+
# Astronomy
83+
#out[out > 10] = 10
84+
#out /= out.max()
85+
86+
87+
print "Stacking using polygon overlap..."
88+
out2 = N.zeros(oshape,float)
89+
for i,(img,M) in enumerate(zip(images,tf_matrices)):
90+
print "Stacking frame %d" % i
91+
out2 += sr.ext.interp_transf_polygon(img,N.linalg.inv(M),oshape)
92+
out2 /= len(images)
93+
#out2[out2 > 500] = 500
94+
95+
import scipy as S
96+
imsave = S.misc.pilutil.imsave
97+
imsave('original.png',images[0])
98+
imsave('_linear.png',out1)
99+
imsave('_polygon.png',out2)
100+
101+
P.subplot(121)
102+
P.imshow(out1,interpolation='nearest',cmap=P.cm.gray)
103+
P.subplot(122)
104+
P.imshow(out2,interpolation='nearest',cmap=P.cm.gray)
105+
P.show()

supreme/ext/SConstruct

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from glob import glob
22

33
env = Environment()
4-
env.Replace(CCFLAGS=['-O2','-Wall','-ansi','-pedantic'])
4+
env.Replace(CCFLAGS=['-O2','-ggdb','-Wall','-ansi','-pedantic'])
55
env.SharedLibrary('supreme_', glob('*.c'))

supreme/ext/libsupreme.py

Lines changed: 44 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class POI(Structure):
3434
'variance_map' : (None,
3535
[c_int, c_int, array_2d_uchar, array_2d_double,
3636
c_int, c_int]),
37-
37+
3838
'line_intersect' : (None,
3939
[c_double, c_double, c_double, c_double,
4040
c_double, c_double, c_double, c_double,
@@ -52,11 +52,13 @@ class POI(Structure):
5252
[c_int, c_int, array_2d_uchar,
5353
c_int, c_int, array_2d_double, array_2d_double,
5454
c_char, c_uint8, array_2d_uchar]),
55+
'interp_transf_polygon': (None,
56+
[c_int, c_int, array_2d_uchar,
57+
c_int, c_int, array_2d_double,
58+
array_2d_double]),
5559
}
5660

5761
def register_api(lib,api):
58-
import inspect
59-
parent_frame = inspect.currentframe().f_back
6062
for f, (restype, argtypes) in api.iteritems():
6163
func = getattr(lib, f)
6264
func.restype = restype
@@ -66,13 +68,13 @@ def register_api(lib,api):
6668

6769
# Python wrappers for libsupreme functions
6870

69-
def _atype(arrays, types):
71+
def atype(arrays, types):
7072
"""Return contiguous arrays of given types.
7173
7274
arrays - list of input arrays
7375
types - list of corresponding types
74-
75-
"""
76+
77+
"""
7678
out = ()
7779
try:
7880
za = zip(arrays,types)
@@ -81,28 +83,25 @@ def _atype(arrays, types):
8183

8284
out = ()
8385
for A,T in za:
84-
try:
85-
out += N.ascontiguousarray(A,T),
86-
except:
87-
out += N.ascontiguousarray(A).astype(T),
86+
out += N.ascontiguousarray(A,T),
8887

8988
return out
90-
89+
9190
def npnpoly(x_vertices, y_vertices, x_points, y_points):
9291
"""Calculate whether points are in a given polygon.
9392
9493
Returns a boolean array of length len(x_points).
95-
94+
9695
"""
97-
xi,yi,x,y = _atype([x_vertices,y_vertices,
96+
xi,yi,x,y = atype([x_vertices,y_vertices,
9897
x_points,y_points],[N.double]*4)
9998

10099
if xi[0] != xi[-1] or yi[0] != yi[-1]:
101100
xi = N.append(xi,x[0])
102101
yi = N.append(yi,y[0])
103102

104103
out = N.empty(len(x),dtype=N.uint8)
105-
104+
106105
_lib.npnpoly(len(xi), xi, yi,
107106
len(x), x, y,
108107
out)
@@ -118,7 +117,7 @@ def variance_map(image, shape=(3,3)):
118117
the variance of all the pixels in the window is stored.
119118
120119
"""
121-
image, = _atype(image,N.uint8)
120+
image, = atype(image,N.uint8)
122121
assert image.ndim == 2, "Image must be 2-dimensional"
123122
window_size_rows, window_size_columns = shape
124123
rows, columns = image.shape
@@ -151,16 +150,16 @@ def poly_clip(x, y, xleft, xright, ytop, ybottom):
151150
x and y are 1D arrays describing the coordinates of the vertices.
152151
xleft, xright, ytop and ybottom specify the borders of the
153152
bounding box. Note that a cartesian axis system is used such that
154-
the following must hold:
153+
the following must hold true:
155154
156155
x_left < x_right
157156
y_bottom < y_top
158157
159158
The x and y coordinates of the vertices of the resulting polygon
160159
are returned.
161-
160+
162161
"""
163-
x,y = _atype([x,y],[N.double,N.double])
162+
x,y = atype([x,y],[N.double,N.double])
164163

165164
assert len(x) == len(y), "Equal number of x and y coordinates required"
166165
assert ytop > ybottom
@@ -170,11 +169,11 @@ def poly_clip(x, y, xleft, xright, ytop, ybottom):
170169
if x[0] != x[-1] or y[0] != y[-1]:
171170
x = N.append(x,x[0])
172171
y = N.append(y,y[0])
173-
172+
174173
xleft,xright,ytop,ybottom = map(N.double,[xleft,xright,ytop,ybottom])
175174

176-
workx = N.empty(2*len(x-1),dtype=N.double)
177-
worky = N.empty(2*len(x-1),dtype=N.double)
175+
workx = N.empty(2*len(x)-1,dtype=N.double)
176+
worky = N.empty_like(workx)
178177
M = _lib.poly_clip(len(x),x,y,xleft,xright,ytop,ybottom,workx,worky)
179178
workx[M] = workx[0]
180179
worky[M] = worky[0]
@@ -193,10 +192,10 @@ def correlate(A,B,
193192
mode_column -- values outside boundaries, 'zero' or 'mirror'
194193
195194
Returns a rows-by-columns array of correlation values.
196-
195+
197196
"""
198197

199-
A,B = _atype([A,B],[N.double,N.double])
198+
A,B = atype([A,B],[N.double,N.double])
200199
assert A.ndim == 2 and B.ndim == 2, "Input arrays must be two dimensional"
201200

202201
A_r,A_c = A.shape
@@ -210,7 +209,7 @@ def correlate(A,B,
210209

211210
modes = {'zero': 0,
212211
'mirror': 1}
213-
212+
214213
output = N.empty((rows,columns),dtype=N.double)
215214
_lib.correlate(A_r, A_c, A,
216215
B_r, B_c, B,
@@ -220,7 +219,8 @@ def correlate(A,B,
220219

221220
return output
222221

223-
def interp_bilinear(grey_image,transform_coords_r,transform_coords_c,
222+
def interp_bilinear(grey_image,
223+
transform_coords_r=None,transform_coords_c=None,
224224
mode='N',cval=0,output=None):
225225
"""Calculate values at given coordinates using bi-linear interpolation.
226226
@@ -249,23 +249,36 @@ def interp_bilinear(grey_image,transform_coords_r,transform_coords_c,
249249
An image of shape transform_coords_r.shape and type N.uint8.
250250
251251
"""
252-
grey_image, = _atype(grey_image,N.uint8)
253-
transform_coords_r,transform_coords_c = _atype([transform_coords_r,transform_coords_c],
252+
grey_image, = atype(grey_image,N.uint8)
253+
transform_coords_r,transform_coords_c = atype([transform_coords_r,transform_coords_c],
254254
[N.double,N.double])
255255
assert grey_image.ndim == 2, "Input image must be 2-dimensional"
256256
assert transform_coords_r.ndim == 2 and transform_coords_c.ndim == 2, \
257257
"Transform coordinates must be 2-dimensional"
258258
if output is None:
259-
output = N.empty(transform_coords_r.shape,dtype=N.uint8)
259+
output = N.empty(transform_coords_r.shape,dtype=N.uint8)
260260
else:
261-
output, = _atype(output,N.uint8)
262-
output.shape = transform_coords_r.shape
261+
output, = atype(output,N.uint8)
262+
output.shape = transform_coords_r.shape
263263

264264
rows,columns = grey_image.shape
265265
tf_rows,tf_columns = transform_coords_r.shape
266266
_lib.interp_bilinear(rows,columns,grey_image,
267267
tf_rows,tf_columns,
268268
transform_coords_r,transform_coords_c,
269269
mode[0],cval,output)
270-
270+
271271
return output
272+
273+
def interp_transf_polygon(grey_image,transform,oshape=None):
274+
grey_image,transform = atype([grey_image,transform],[N.uint8,N.double])
275+
ishape = grey_image.shape
276+
if oshape is None:
277+
oshape = ishape
278+
279+
out = N.empty(oshape,dtype=SC.ftype)
280+
_lib.interp_transf_polygon(ishape[0],ishape[1],grey_image,
281+
oshape[0],oshape[1],out,
282+
transform)
283+
return out
284+

0 commit comments

Comments
 (0)