将十六进制颜色的Pandas DB转换为cv2的numpy 3d数组



我有一个文件,其中有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元素

最新更新