将1D 16bit图像数据转换为2D numpy数组



我有一个由字节创建的大小为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

最新更新