Here is the list of numpy's data types, so no uint4
.
For uint
s, you have the following:
(note: .itemsize
returns the "length of one array element in bytes")
In [1]: numpy_dtypes = (
...: (np.uint8, np.ubyte),
...: (np.uint16, np.ushort),
...: (np.uint32, np.uintc),
...: (np.uint64, np.uintp, np.ulonglong),
...: )
...: for dtypes in numpy_dtypes:
...: print([dt().itemsize for dt in dtypes])
[1, 1]
[2, 2]
[4, 4]
[8, 8, 8]
You can simulate any bit depth by just scaling into the correct dynamic range and rounding to integers:

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.axes_grid1 import make_axes_locatable
def main():
imh, imw = 512, 512
data = np.arange(imh * imw).reshape(imh, imw)
num_bits = [2, 4, 8, 16]
images = {
nbits: np.round(minmax_scale(data, vmin=0, vmax=2**nbits - 1))
for nbits in num_bits
}
fig, axes = plt.subplots(ncols=len(images), figsize=(12, 4))
for ax, (nbits, image) in zip(axes, images.items()):
ax.set_title(f"{nbits = }")
im = ax.imshow(image, vmin=0, vmax=2**nbits - 1, interpolation="none")
add_colorbar(ax, im)
plt.subplots_adjust(wspace=0.8)
plt.show()
def add_colorbar(ax, im):
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
cax.get_figure().colorbar(im, cax=cax, orientation="vertical")
def minmax_scale(arr, *, vmin, vmax):
amin, amax = arr.min(), arr.max()
arr_std = (arr - amin) / (amax - amin)
return arr_std * (vmax - vmin) + vmin
if __name__ == "__main__":
main()