我有一个文件,其中有X行Y十六进制代码,如下所示:
FFFFFF 123456 453623 ....
354352 5AB12A 123789 ....
...... ...... ...... ....
我的最终目标是在Python中将它转换为OpenCV图像,也就是NumPy数组。我也使用pandasread_table
,因为它比通过python文件读取更快。所以现在我有了六进制的Pandas DB,我对它进行了一些转换:
data = pd.read_table('ИРС/sample/0', sep=' ', header=None, dtype=str)
data = data.iloc[:,:-1]
data = data.applymap(lambda x: int(x, 16))
data = data.applymap(lambda x: np.array([x>>16, x>>8, x]).astype(np.uint8))
现在,当我通过data.to_numpy()
将其转换为NumPU数组并运行cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
时,我得到以下错误:
> - src data type = 17 is not supported
这表明我在数组中使用了带符号的int,但事实并非如此。
我的问题是,我该如何转换它,我是在做Pandas到cv2的转换吗?
我建议您在将数据转换为整数后,将DataFrame转换为NumPy数组,并使用NumPy继续转换。
您可以使用以下阶段:
-
从十六进制转换为整数
data = data.applymap(lambda x: int(x, 16))
-
转换为类型为
np.uint32
的NumPy数组并使其连续(因为下一个操作".view(np.uint8)
"需要连续数据(。data = np.ascontiguousarray(data.to_numpy(np.uint32))
-
使用
.view(np.uint8)
-每个uint32元素被视为4个uint8元素
数据格式采用类似RGBA的格式(第4个0元素可能被视为alpha通道-第4个元素应被删除(。data = data.view(np.uint8).reshape((data.shape[0], data.shape[1], 4))
-
使用OpenCV将RGBA转换为BGR(假设输入表示为RGB(。
img = cv2.cvtColor(data, cv2.COLOR_RGBA2BGR)
完整的代码示例:
import pandas as pd
import numpy as np
import cv2
data = pd.read_table('0.txt', sep=' ', header=None, dtype=str)
# data:
# 0 1 2
# 0 FFFFFF 123456 453623
# 1 354352 5AB12A 123789
#data = data.iloc[:,:-1]
data = data.applymap(lambda x: int(x, 16)) # Convert from hex to int
# data:
# 0 1 2
# 0 16777215 1193046 4535843
# 1 3490642 5943594 1193865
# data = data.applymap(lambda x: np.array([x>>16, x>>8, x]).astype(np.uint8))
# Convert to NumPy array of type np.uint32, make it contiguous, because the next operation ".view(np.uint8)" requires contiguous data.
data = np.ascontiguousarray(data.to_numpy(np.uint32))
# data:
# array([[16777215, 1193046, 4535843],
# [ 3490642, 5943594, 1193865]], dtype=uint32)
# Use .view(np.uint8) - each uint32 element is viewed as 4 uint8 elements.
# The data format applies RGBA-like format (the 4'th 0 element may be considered to be alpha).
data = data.view(np.uint8).reshape((data.shape[0], data.shape[1], 4))
# data:
# array([[[255, 255, 255, 0], [ 86, 52, 18, 0], [ 35, 54, 69, 0]],
# [[ 82, 67, 53, 0], [ 42, 177, 90, 0], [137, 55, 18, 0]]], dtype=uint8)
# Convert from RGBA to BGR
img = cv2.cvtColor(data, cv2.COLOR_RGBA2BGR)
# img:
# array([[[255, 255, 255], [ 18, 52, 86], [ 69, 54, 35]],
# [[ 53, 67, 82], [ 90, 177, 42], [ 18, 55, 137]]], dtype=uint8)
# Show image for testing
#cv2.imshow('img', img)
#cv2.waitKey()
#cv2.destroyAllWindows()
注:
- 使用
data.view(np.uint8).reshape
的技巧可能是不直观的
也可以使用移位操作将每个uint32
元素转换为三个uint8
元素