I have an image in an esoteric format (BGR4) that I would like to load into numpy. In BGR4 individual pixels are byte aligned (thank god) and are comprised of 3 components (B, G, and R) encoded in a single byte. They are ordered like this: b0000BGGR.
Here is an example image with size (1, 2), aka. 2 pixels:
img_bytes = b"\x0F\x09" # this is how it looks in memory
img = np.array([[1, 3, 1], [1, 0, 1]], dtype=np.uint8) # this is my desired result
Since there are a lot of pixels in each image, what is the most performant way to inflate such an array?
I have the same question for BGR8 (ordered: bBBBGGGRR), but I assume the approach is similar, and I will cross that bridge when I get there :)
CodePudding user response:
Here is a numpy implementation that follows the suggestion @MichaelButscher made in the comments:
img_bytes = b"\x0f\x09" # this is how it looks in memory
# b0000BGGR
b = 0b00001000
g = 0b00000110
r = 0b00000001
template = np.array([b, g, r], dtype=np.uint8)[:,None]
shifts = np.array([3, 1, 0], dtype=np.uint8)[:,None]
arr = np.frombuffer(img_bytes, dtype=np.uint8)
res = (arr & template) >> shifts
print(res.T)
[[1 3 1]
[1 0 1]]
You may want to tune transpose order for better performance.
