【问题标题】:skimage.io.imread Versus cv2.imreadskimage.io.imread 与 cv2.imread
【发布时间】:2020-05-08 08:54:04
【问题描述】:

我使用并熟悉cv2,今天我尝试使用skimage

我尝试使用skimagecv2 读取图像。似乎他们俩都完美地阅读了图像。但是当我绘制图像的直方图但通过不同的库(skimagecv2)读取时,直方图显示出显着差异。

谁能帮我解释直方图之间的区别?

我的代码:

import cv2
import skimage.io as sk
import numpy as np
import matplotlib.pyplot as plt

path = '../../img/lenna.png'

img1 = sk.imread(path, True)
img2 = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
print(img1.shape)
print(img2.shape)

plt.subplot(2, 2, 1)
plt.imshow(img1, cmap='gray')
plt.title('skimage read')
plt.xticks([])
plt.yticks([])

plt.subplot(2, 2, 2)
plt.imshow(img2, cmap='gray')
plt.title('cv2 read')
plt.xticks([])
plt.yticks([])

plt.subplot(2, 2, 3)
h = np.histogram(img1, 100)
plt.plot(h[0])
plt.title('skimage read histogram')

plt.subplot(2, 2, 4)
h = np.histogram(img2, 100)
plt.plot(h[0])
plt.title('cv2 read histogram')

plt.show()

文本输出:

(512, 512) (512, 512)

输出:



编辑:

这是输入图像:

【问题讨论】:

  • 能否打印np.mean()np.std() 这两个图像,以便我们查看差异是在加载和灰度转换还是在直方图的生成和显示中?此外,如果您分享您使用的实际 Lena 图像会有所帮助。
  • 您应该注意 OpenCVskimage 使用完全不同的图像表示。 OpenCV 倾向于使用 [0..255] 范围内的 8 位无符号整数,而 skimage 倾向于使用 [0..1] 范围内的浮点数。
  • 非常感谢。正如您所提到的,强度范围差异是原因,我已经理解了。这是np.meannp.std,他们说了很多。 skimage mean: 0.4578778306070963 skimage std: 0.19380367354500247 cv2 mean: 123.54518127441406 cv2 std: 47.853738824592234

标签: python numpy histogram scikit-image cv2


【解决方案1】:

这两个imread 函数只是具有不同的读取图像的默认格式。 skimage.io 标准使用 64 位浮点数,而 cv2 标准似乎是无符号字节。
您可以通过将img1 转换为无符号字节格式来看到这一点。

import skimage as skk
img1 = skk.img_as_ubyte(img1)

现在您会得到一些相似的直方图。它们并不完全相同,因为它们最初被读取为不同的格式。

【讨论】:

  • 非常感谢。我想我已经明白了原因。还是有区别的,不就是转换时的精度损失吗?
  • 是的,也是。当读取为无符号字节(在 OpenCV 的情况下)或转换(如上所示)为无符号字节时,您总是会失去一些精度。不同之处在于你如何失去精度。在 OpenCV 的情况下,您会失去精度,因为您试图将 .png 文件格式表示为字节数组。在使用 img_as_ubyte 在 scikt 中进行转换的情况下,您正在失去精度,因为您正在从浮点数转换为字节数。希望这能让事情更清楚。
  • 对 .png 格式的外观有一个想法:en.wikipedia.org/wiki/Portable_Network_Graphics#File_format
猜你喜欢
  • 2019-09-17
  • 2021-04-05
  • 2017-11-17
  • 1970-01-01
  • 2013-07-30
  • 2013-10-01
  • 2018-04-07
  • 2019-01-06
相关资源
最近更新 更多