我有一个由字节创建的大小为18874568的1D数组,如下所示
np_img = np.array(list(data), dtype=np.uint16)
我如何将其转换为大小为3072 x 3072和8bit的2D数组?
字节数据是从称为平板检测器(FPD)的图像捕获设备获取的。文档中指定FPD捕获大小为3072x3072的16位图像。
16位原始图像附在下面https://drive.google.com/file/d/1Kw1UeKOaBGtXNpxGsCXEk-gjGw3YaDJJ/view?usp=sharing
编辑:由FPD支持团队提供的c#代码转换
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;
}
好的,根据评论收集的所有信息,我想你会想要这样的东西:
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")
生成的图像相当暗,而不是"只是白色"。-也许它需要倒过来?谁知道……:)
使用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)
更好的方法是在转换前用uint8而不是uint16来读取。你应该参考:Input and output