英文:
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*3601 行,3列:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论