当使用 OpenCV 将 B/W 图像读取为 Numpy 数组时,我得到的结果与读取为图像不同

Posted

技术标签:

【中文标题】当使用 OpenCV 将 B/W 图像读取为 Numpy 数组时,我得到的结果与读取为图像不同【英文标题】:When reading B/W image as Numpy array using OpenCV I get different results than reading as an image 【发布时间】:2021-08-31 10:23:26 【问题描述】:

我的最终用户正在读取图像,将它们转换为灰度并使用以下代码将它们作为 numpy 数组打包成 H5 文件:

image = Image.open(imageFilename)
greyscaleImage = image.convert("L")
imageData = np.asarray(greyscaleImage)
    if convertTo16Bit:
        imageData16bit = imageData.astype(np.uint16)
        imageData16bit = imageData16bit*8
        imageData = imageData16bit

h5Filename = makeFilename(imageId, appendToName)
h5FullPath = os.path.join(filePath, h5Filename)
h5file = h5py.File(h5FullPath, "w")
dset = h5file.create_dataset("image", data=imageData)

然后我如下读取这些H5文件:

        if args.file_types == 'image':
            image = cv2.imread(os.path.join(args.input, filename), cv2.IMREAD_COLOR)
            image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
            
        elif args.file_types == 'h5, hdf5':
            hf = h5py.File(os.path.join(args.input, filename), "r")
            key = list(hf.keys())[0]
            data = np.array(hf[key])
            hf.close()
            image = cv2.cvtColor(np.uint16(data), cv2.COLOR_GRAY2RGB)
            plt.axis('off')
            plt.imshow(image)
            plt.show()

我需要转换为 RGB,然后在对象检测模型中使用它们。 当我阅读 H5 文件并查看图像时,它们丢失了信息,并且模型不执行检测以及使用原始 jpg 时。

请有人帮助我了解如何在不丢失任何信息的情况下读取 H5 文件?

【问题讨论】:

很难弄清楚你真正想要做什么。您从图像开始,不清楚它是彩色还是灰度,以及它是 8 位还是 16 位。然后您丢弃所有颜色信息 - 为什么?然后你将它乘以 8 没有明显的原因,这不会使它比以前更好或更多的 16 位。然后你把它写进 hdf5 - 为什么?然后你试着假装它不是颜色......也许你可以从第一原则解释你从什么开始,最后你想要什么。谢谢。 【参考方案1】:

如上所述,您的 HDF5 文件中缺少信息,因为用户将图像转换为灰度(使用image.convert("L"))。执行此操作时,您的图像会从 3 个通道变为 1 个通道。下面的示例代码演示了这一点。

image = Image.open(imageFilename)
print(image.size,image.mode)
image.show()
imageData = np.asarray(image)
print('Color image:',imageData.dtype, imageData.shape)

greyscaleImage = image.convert("L")
print(greyscaleImage.size,image.mode)
greyscaleImage.show()
imageData = np.asarray(greyscaleImage)
print('Grey scale image:',imageData.dtype, imageData.shape)

您的对象检测模型是否需要彩色图像,或者您能否将 1 通道(灰度)阵列转换为 3 通道阵列?如果您需要彩色图像,我认为您会遇到问题-我认为您无法逆转该过程。您的用户必须将图像保存为 3 通道 RGB 数组。

如果你只需要一个3通道数组,你可以扩展1通道数组,如下图。

imageData3x = np.stack((imageData,imageData,imageData),axis=2)
print('3x Grey scale image:',imageData3x.dtype, imageData3x.shape)

plt.axis('off')
plt.imshow(imageData3x)
plt.show()

注意:上面的代码不处理 HDF5 文件中的其他数据转换(转换为 np.uint16 并将值乘以 8)。我不清楚为什么要完成其中任何一个。但是,只要您有标签知道if convertTo16BitTrueFalse,它们就可以很简单地“撤消”。

【讨论】:

以上是关于当使用 OpenCV 将 B/W 图像读取为 Numpy 数组时,我得到的结果与读取为图像不同的主要内容,如果未能解决你的问题,请参考以下文章

如何在 OpenCV 中将图像读取为双倍?

如何使用 OpenCV 以您想要的分辨率从 DVR 读取图像?

如何在OpenCV中使用Adobe RGB色彩空间读取jpeg图像?

Opencv:当使用运算符<<保存为原始数据时,将数据从文件读取到矩阵

将 ReadTensorFromImageFile 转换为 opencv 格式

当使用 OpenCV 完成图像加载和调整大小时,Resnet50 会产生不同的预测