如何从我的数组数据集创建一个16位灰度图像

huangapple go评论68阅读模式
英文:

How do I create a 16-bit grayscale image from my array dataset

问题

我想将NASA数据库中的高度图转换成图像文件。网络上已经有一些相关的信息,这帮助我将文件读入数组中,看起来像这样:

data = [(113.0, 39.0, 1242), (113.00027777777778, 39.0, 1231), (113.00055555555555, 39.0, 1232), (113.00083333333333, 39.0, 1239), (113.00111111111111, 39.0, 1244), ...]

所以我有一个按照数据模式

data[width][height][tuple]
tuple = [longitude, latitude, height]

的数组。

宽度和高度都是3601。

print (data[1800][1800])

返回元组:(113.5, 39.5, 2032)

这挺好的。这正是数据集的中心,从经度39到40,纬度113到114。我认为我不会需要经度和纬度,因为我知道数据集的尺寸是3601 x 3601。有价值的信息在最后一个值,高度上。在我的例子中是2032。

现在我的问题是:我如何将数据集data = [rows, columns, [longitude, latitude, height]] 转换成一个16位灰度图像。如上所述,经度和纬度并不重要。我是否必须首先将数据集变成类似data = [rows, columns, heights] 过滤掉经度和纬度?之后我才能进一步处理图像文件吗?

以及我如何确切地从这个数据集创建一个16位灰度图像文件(png)?

英文:

I want to convert a height map from NASA database into an image file. There is already a bit about this on the net and that helped me to read the file into an array and it looks like this:

data = [(113.0, 39.0, 1242), (113.00027777777778, 39.0, 1231), (113.00055555555555, 39.0, 1232), (113.00083333333333, 39.0, 1239), (113.00111111111111, 39.0, 1244), ...]

So I have an array with all the data according to the data pattern

data[width][height][tupel]
tupel = [longitude, latitude, height] 

the width and height are both 3601 long.

print (data[1800][1800])

returns the tupel: (113.5, 39.5, 2032)

and that's fine. It is exactly the center of the dataset which goes from longitude 39 to 40 and from latitude 113 to 114. I don't think I will need longitude and latitude because I know that the data set is 3601 x 3601 in size. The valuable information is in the last value, the height. In my example here the 2032.

My question now is: How do i get the data set data = [rows, columns, [longitude, latitude, height] ] to a 16 bit grayscale image. As mentioned, longitude and latitude are not relevant. Do I have to first make the dataset something like data = [rows, columns, heights] so filter out longitude and latitude? before I can further process the image file?

And how exactly do I create a 16-bit grayscale image file in png from this?

答案1

得分: 0

以下是翻译好的部分,代码部分不翻译:

我们可以将数据转换为NumPy数组并使用一些NumPy数据操作

-`data` 转换为NumPy数组
数组形状应该是 3601*36013

        arr = np.array(data)

- 仅保留高度海拔数据

        alt = arr[:, 2]

- 将长列重塑为 3601 x 3601

        alt = alt.reshape(height, width)

- 将 alt 值剪裁到范围 [0, 65535]四舍五入并转换为 `np.uint16` 类型

        alt = alt.clip(0, np.iinfo(np.uint16).max).round().astype(np.uint16)

---

以下是一个代码示例使用 4x4 图像代替 3601x3601

    import numpy as np
    import cv2
    
    width, height = 4, 4  # 测试 4x4 图像,而不是 3601x3601
    
    data = [(113.0, 39.0, 1242), (113.00027777777778, 39.0, 1231), (113.00055555555555, 39.0, 1232), (113.00083333333333, 39.0, 1239), (113.00111111111111, 39.0, 1244), 
            (1113.0, 139.0, 11242), (1113.00027777777778, 139.0, 11231), (1113.00055555555555, 139.0, 11232), (1113.00083333333333, 139.0, 1239), (1113.00111111111111, 139.0, 11244),
            (2113.0, 239.0, 21242), (2113.00027777777778, 239.0, 21231), (2113.00055555555555, 239.0, 21232), (2113.00083333333333, 239.0, 21239), (2113.00111111111111, 39.0, 1244), (2113.00111111111111, 239.0, 21244)]
    
    arr = np.array(data)  # arr 形状为 16 行,3 列。
    
    alt = arr[:, 2]  # 仅保留高度(海拔)数据(16 行)。
    
    assert alt.size == width*height  # 确保元素的数量正确。
    
    alt = alt.reshape(height, width)  # 将 alt 重塑为 4x4。
    
    alt = alt.clip(0, np.iinfo(np.uint16).max).round().astype(np.uint16)  # 将 alt 值剪裁到范围 [0, 65535],四舍五入并转换为 uint16
    
    cv2.imwrite('alt.png', alt)  # 将 alt 保存为 16 位灰度图像文件,格式为 PNG。

---

注意
上述代码基于您对数据集的描述
为使其与实际数据集配合使用可能需要进行微小的调整
英文:

We may convert the data to NumPy array, and use few NumPy data operation:

  • Convert data to NumPy array
    array shape is supposed to be 3601*3601 rows by 3 columns:

     arr = np.array(data)
    
  • Keep only the altitude (height) data:

     alt = arr[:, 2]
    
  • Reshape the long column to 3601 x 3601:

     alt = alt.reshape(height, width)
    
  • Clip alt to range [0, 65535], round and convert to np.uint16:

     alt = alt.clip(0, np.iinfo(np.uint16).max).round().astype(np.uint16)
    

Here is a code sample with 4x4 image instead of 3601x3601:

import numpy as np
import cv2
width, height = 4, 4  # Test 4x4 image instead of 3601x3601
data = [(113.0, 39.0, 1242), (113.00027777777778, 39.0, 1231), (113.00055555555555, 39.0, 1232), (113.00083333333333, 39.0, 1239), (113.00111111111111, 39.0, 1244), 
(1113.0, 139.0, 11242), (1113.00027777777778, 139.0, 11231), (1113.00055555555555, 139.0, 11232), (1113.00083333333333, 139.0, 1239), (1113.00111111111111, 139.0, 11244),
(2113.0, 239.0, 21242), (2113.00027777777778, 239.0, 21231), (2113.00055555555555, 239.0, 21232), (2113.00083333333333, 239.0, 21239), (2113.00111111111111, 39.0, 1244), (2113.00111111111111, 239.0, 21244)]
arr = np.array(data)  # arr shape is 16 rows by 3 columns.
alt = arr[:, 2]  # Keep only the altitude (height) data (16 rows).
assert alt.size == width*height  # Make sure the number of elements is correct.
alt = alt.reshape(height, width)  # Reshape alt to 4x4.
alt = alt.clip(0, np.iinfo(np.uint16).max).round().astype(np.uint16)  # Clip alt to range [0, 65535], round and convert to uint16
cv2.imwrite('alt.png', alt)  # Save alt as 16-bit grayscale image file in PNG format.

Note:
The above code is based on your description of the dataset.
The solution may require minor adjustments to work with the actual dataset.

huangapple
  • 本文由 发表于 2023年2月10日 04:00:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/75403841.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定