def demosaic(self):
if self._demo is None:
# XXX Again, should take into account camera's vflip and hflip here
# Construct representation of the bayer pattern
bayer = np.zeros(self.array.shape, dtype=np.uint8)
bayer[1::2, 0::2, 0] = 1 # Red
bayer[0::2, 0::2, 1] = 1 # Green
bayer[1::2, 1::2, 1] = 1 # Green
bayer[0::2, 1::2, 2] = 1 # Blue
# Allocate output array with same shape as data and set up some
# constants to represent the weighted average window
window = (3, 3)
borders = (window[0] - 1, window[1] - 1)
border = (borders[0] // 2, borders[1] // 2)
# Pad out the data and the bayer pattern (np.pad is faster but
# unavailable on the version of numpy shipped with Raspbian at the
# time of writing)
rgb = np.zeros((
self.array.shape[0] + borders[0],
self.array.shape[1] + borders[1],
self.array.shape[2]), dtype=self.array.dtype)
rgb[
border[0]:rgb.shape[0] - border[0],
border[1]:rgb.shape[1] - border[1],
:] = self.array
bayer_pad = np.zeros((
self.array.shape[0] + borders[0],
self.array.shape[1] + borders[1],
self.array.shape[2]), dtype=bayer.dtype)
bayer_pad[
border[0]:bayer_pad.shape[0] - border[0],
border[1]:bayer_pad.shape[1] - border[1],
:] = bayer
bayer = bayer_pad
# For each plane in the RGB data, construct a view over the plane
# of 3x3 matrices. Then do the same for the bayer array and use
# Einstein summation to get the weighted average
self._demo = np.empty(self.array.shape, dtype=self.array.dtype)
for plane in range(3):
p = rgb[..., plane]
b = bayer[..., plane]
pview = as_strided(p, shape=(
p.shape[0] - borders[0],
p.shape[1] - borders[1]) + window, strides=p.strides * 2)
bview = as_strided(b, shape=(
b.shape[0] - borders[0],
b.shape[1] - borders[1]) + window, strides=b.strides * 2)
psum = np.einsum('ijkl->ij', pview)
bsum = np.einsum('ijkl->ij', bview)
self._demo[..., plane] = psum // bsum
return self._demo
评论列表
文章目录