I have a 1D array of size 18874568 created from bytes as shown below
np_img = np.array(list(data), dtype=np.uint16)
How can I convert this to a 2D array of size 3072 x 3072 and in 8bit?
The bytes data is acquired from a image capture device called as a flat panel detector (FPD). It's specified in the docs that the FPD captures 16bit image of size 3072x3072.
16bit raw image is attached below https://drive.google.com/file/d/1Kw1UeKOaBGtXNpxGsCXEk-gjGw3YaDJJ/view?usp=sharing
Edit: C# code on conversion given by the FPD support team
private Bitmap Load16bppGrayImage(string fileName, int offset=0)
{
Bitmap loadind_bmp;
var raw = File.ReadAllBytes(fileName).Skip(offset).ToArray();
var pwi = 3072;
var phi = 3072;
var dpiX = 96d;
var dpiY = 96d;
loadind_bmp = new Bitmap(pwi, phi, PixelFormat.Format48bppRgb);
BitmapData bmpData = loadind_bmp.LockBits(new Rectangle(0, 0, loadind_bmp.Width, loadind_bmp.Height), ImageLockMode.ReadWrite, loadind_bmp.PixelFormat);
int depth = Bitmap.GetPixelFormatSize(bmpData.PixelFormat) / 16;
IntPtr srcAdr = bmpData.Scan0;
unsafe
{
for (int y = 0; y < bmpData.Height; y )
{
int pos = y * bmpData.Stride / 3;
ushort* imgPtr = (y * bmpData.Stride / 2) (ushort*)bmpData.Scan0;
for (int x = 0; x < bmpData.Width; x )
{
ushort value = (ushort)(raw[pos (x * sizeof(ushort)) 1] << 8 | raw[pos x * sizeof(ushort)]);
imgPtr[x * depth] = value; //Blue 0-255
imgPtr[x * depth 1] = value; //Green 0-255
imgPtr[x * depth 2] = value; //Red 0-255
}
}
}
loadind_bmp.UnlockBits(bmpData);
return loadind_bmp;
}
CodePudding user response:
Right, based on all of the information gathered by the comments, I think you'll want something like this:
import numpy as np
import PIL.Image as Image
with open("data1.raw", "rb") as fp:
data = fp.read()
w = h = 3072
dt = np.dtype(np.uint16).newbyteorder("<") # little-endian
image = np.frombuffer(data, offset=96, count=w * h, dtype=dt).reshape((h, w))
# Dump to 16bpp TIFF:
Image.fromarray(image).save("data1.tiff")
The resulting image is quite dark, not "just white" – maybe it needs to be inverted? Who knows... :)
CodePudding user response:
Use ndarray.view
:
>>> a = np.random.randint(2 ** 7, 2 ** 12, 10, dtype=np.uint16)
>>> a
array([3434, 1565, 3144, 357, 3755, 3130, 3799, 338, 3224, 2794],
dtype=uint16)
>>> a.view(np.uint8)
array([106, 13, 29, 6, 72, 12, 101, 1, 171, 14, 58, 12, 215,
14, 82, 1, 152, 12, 234, 10], dtype=uint8)
The better way is to read with uint8 instead of uint16 before conversion. You should refer to: Input and output