Skip to content

Commit 65ef3f1

Browse files
committed
Added iterator_ij to iterate over pixel coordinates.
1 parent a1a6e34 commit 65ef3f1

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

spectral/algorithms/algorithms.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,55 @@ def iterator(image, mask=None, index=None):
149149
return ImageIterator(image)
150150

151151

152+
def iterator_ij(image, mask=None, index=None):
153+
'''
154+
Returns an iterator over image pixel coordinates for a given mask.
155+
156+
Arguments:
157+
158+
`image` (ndarray or :class:`spectral.Image`):
159+
160+
An image over whose pixels will be iterated.
161+
162+
`mask` (ndarray) [default None]:
163+
164+
An array of integers that specify over which pixels in `image`
165+
iteration should be performed.
166+
167+
`index` (int) [default None]:
168+
169+
Specifies which value in `mask` should be used for iteration.
170+
171+
Returns:
172+
173+
An iterator over image pixel coordinates. Each returned item is a
174+
2-tuple of the form (row, col).
175+
176+
If neither `mask` nor `index` are defined, iteration is performed over all
177+
pixels. If `mask` (but not `index`) is defined, iteration is performed
178+
over all pixels for which `mask` is nonzero. If both `mask` and `index`
179+
are defined, iteration is performed over all pixels `image[i,j]` for which
180+
`mask[i,j] == index`.
181+
'''
182+
183+
if mask is None and index is None:
184+
# Iterate over all pixels
185+
(nrows, ncols) = image.shape[:2]
186+
for r in range(nrows):
187+
for c in range(ncols):
188+
yield (r, c)
189+
else:
190+
if mask.shape != image.shape[:len(mask.shape)]:
191+
raise ValueError('Mask shape does not match image.')
192+
193+
if index is None:
194+
mask = mask != 0
195+
else:
196+
mask = mask == index
197+
for rc in np.argwhere(mask):
198+
yield tuple(rc)
199+
200+
152201
def mean_cov(image, mask=None, index=None):
153202
'''
154203
Return the mean and covariance of the set of vectors.

spectral/tests/iterators.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,28 @@ def test_iterator_index(self):
7878
itsum = np.sum(np.array([x for x in iterator(data, self.gt, cls)]), 0)
7979
assert_allclose(sum, itsum)
8080

81+
def test_iterator_ij_nonzero(self):
82+
'''Iteration over all non-background pixels.'''
83+
from spectral.algorithms.algorithms import iterator_ij
84+
data = self.image.load()
85+
classes = self.gt.ravel()
86+
pixels = data.reshape((-1, data.shape[-1]))
87+
sum = np.sum(pixels[classes > 0], 0)
88+
itsum = np.sum(np.array([data[ij] for ij in iterator_ij(data,
89+
self.gt)]), 0)
90+
assert_allclose(sum, itsum)
91+
92+
def test_iterator_ij_index(self):
93+
'''Iteration over single ground truth index'''
94+
from spectral.algorithms.algorithms import iterator_ij
95+
cls = 5
96+
data = self.image.load()
97+
classes = self.gt.ravel()
98+
pixels = data.reshape((-1, data.shape[-1]))
99+
sum = np.sum(pixels[classes == cls], 0)
100+
itsum = np.sum(np.array([data[ij] for ij in iterator_ij(data, self.gt, cls)]), 0)
101+
assert_allclose(sum, itsum)
102+
81103
def test_iterator_spyfile(self):
82104
'''Iteration over SpyFile object for single ground truth index'''
83105
from spectral.algorithms.algorithms import iterator

0 commit comments

Comments
 (0)