PythonLibrary Python NumPy 2019年 1月 9日
ピクセルごとにアクセスをするイテレータのテストを行いたい. 例として,整数ベースのヒストグラムを計算する generate_with_int_hist のテストを行う.
with such.A('MonoImage class') as it:
(省略)
@it.should('generate integer histogram')
def test():
correct = MonoImage.create_with_array([0, 2, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], np.uint32, 32);
### vector test
vec = MonoImage.create_with_array([3, 1, 4, 1, 5, 9], np.uint8, 4);
it.assertEqual(vec.generate_with_int_hist(), correct)
def generate_with_int_hist(self):
ans = MonoImage.create_with_zeros(self.max_value+1, np.uint32, 32)
for pi in self.pixel_iterator():
ans.inc_value_at(pi.value)
return ans
ans = MonoImage.create_with_zeros(self.max_value+1, np.uint32, self.bits)
for pi in self.pixel_iterator():
ans.inc_value_at(pi.value)
return ans
def pixel_iterator(self):
return MonoImagePixelIterator(self)
class MonoImage:
(中略: ここに MonoImage のクラスの内容が記述されている)
class MonoImagePixelIterator:
def __init__(self, mono_image):
self._mono_image = mono_image
self._width = mono_image.width
self._height = mono_image.height
self._f = self.vector_iterator_func
self._getter = self.vector_getter_func
self._setter = self.vector_setter_func
class MonoImagePixelIterator:
(中略)
def __iter__(self):
return self._f()
class MonoImagePixelIterator:
(中略)
def vector_iterator_func(self):
self._nowi = 0
while (self._nowi != -1):
yield self
self._nowi += 1
if self._nowi == self._width:
self._nowi = -1
class MonoImagePixelIterator:
(中略)
@property
def value(self):
return self._getter()
@value.setter
def value(self, v):
self._setter(v)
def vector_getter_func(self):
return self._mono_image._array[self._nowi]
def vector_setter_func(self, v):
self._mono_image._array[self._nowi] = v
ここまでの実装で MonoImage クラスに inc_value_at というインスタンスメソッドが必要となった. 通常はテストを書いてから実装をするのだが,今回の一連のテストが通過すれば十分このメソッドのテストをしていることになるため,直接のテストは省略する.
class MonoImage:
(中略)
def inc_value_at(self, pos):
self._array[pos] += 1
it.assertEqual(vec.generate_with_int_hist(), correct)
# Check if the method is called twice
it.assertEqual(vec.generate_with_int_hist(), correct)
行列版も描こうとしたが長くなったので今日はここまで.次回はこれを行列に対応させる.