我正在尝试从 URL 自动加载图像,然后将其加载到 numpy 矩阵。为此,我需要使用 requests 和 opencv 库。对于像 uint8 这样编码的标准图像,它以正确的方式工作,并且由于值溢出而损坏了 uint16 图像。这是我现在正在使用的一个简单的最小代码:
import requests
import cv2
import numpy as np
import sys
r = requests.get(sys.argv[1])
img_bin = r.content
image_data = np.asarray(bytearray(img_bin), dtype="uint8")
image = cv2.imdecode(image_data, cv2.IMREAD_UNCHANGED)
# image.dtype -> np.uint8
从本地驱动器加载 uint16 图像工作正常:
import cv2
import sys
png_u16_filepath = sys.argv[1]
png_u8_filepath = sys.argv2[]
image = cv2.imread(png_u16_filepath, cv2.IMREAD_UNCHANGED)
#image.dtype -> np.uint16
image = cv2.imread(png_u8_filepath, cv2.IMREAD_UNCHANGED)
#image.dtype -> np.uint8
但是,我需要从互联网加载图像,然后从内存加载图像,我无法编写它们本地到图像文件。
- 是否可以从requests.img_bin或任何其他方式知道图像文件是uint8还是uint16? URL 后面的图像可以是 uint8 或 uint16 图像。
- 我也尝试 np.asarray(bytearray(img_bin), dtype="uint16") 但它会导致错误: ValueError: 缓冲区大小必须是元素大小的倍数 有没有办法通过 opencv lib 将 img_bin 转换为正确的 np.uint16 numpy 图像?
以下图像发生问题 https://images.ximilar.com/examples/fail/png16.png
在加载 uint16 PNG 图像时遇到的问题是,试图将字节流直接解释为 numpy 数组,而没有考虑 PNG 文件结构中的位深度信息。
以下是如何使用
requests
和
opencv
加载 uint8 和 uint16 PNG 图像的解决方案:
import requests
import cv2
import numpy as np
import io
def load_image_from_url(url):
"""从 URL 加载图像并将其解码为合适的 numpy 数组。"""
r = requests.get(url)
r.raise_for_status() # 检查请求是否成功
# 使用 BytesIO 将字节流包装为文件对象
image_file = io.BytesIO(r.content)
# 使用 imdecode 加载图像,自动检测位深度
image = cv2.imdecode(np.frombuffer(image_file.read(), np.uint8), cv2.IMREAD_UNCHANGED)
return image
# 示例用法:
image_url = "https://images.ximilar.com/examples/fail/png16.png" # 或任何其他 PNG 图像 URL
image = load_image_from_url(image_url)
# 打印图像数据类型以验证
print(image.dtype)
代码说明:
-
load_image_from_url(url)
函数: -
它使用
requests.get()
获取给定 URL 的图像数据。 -
r.raise_for_status()
确保请求成功,否则引发异常。 -
io.BytesIO(r.content)
将字节流 (r.content
) 包装为文件对象,以便cv2.imdecode
可以读取它。 -
np.frombuffer(image_file.read(), np.uint8)
将字节数据解释为无符号 8 位整数数组。 -
cv2.imdecode(..., cv2.IMREAD_UNCHANGED)
解码图像数据,保留其原始位深度(uint8 或 uint16)。 -
示例用法:
- 提供要加载的图像的 URL。
-
调用
load_image_from_url()
函数来获取解码后的图像数组。 -
打印
image.dtype
以验证图像是否已加载为正确的位深度。
关键点:
-
使用
cv2.imdecode()
和cv2.IMREAD_UNCHANGED
标志可以让 OpenCV 自动检测和处理 uint8 和 uint16 PNG 图像,而无需手动检查位深度。 -
io.BytesIO
允许将字节流视为文件对象,这对于与cv2.imdecode()
等函数一起使用至关重要。
使用此方法,应该能够从 URL 加载 uint8 和 uint16 PNG 图像,而不会遇到任何数据溢出问题。
标签:python,numpy,image,opencv,python-requests From: 78822177