【问题标题】:h5py flipping dimensions of imagesh5py翻转图像尺寸
【发布时间】:2017-12-03 04:41:08
【问题描述】:

我一直致力于构建一种机器学习算法来识别图像,首先是创建自己的 h5 数据库。我一直在关注this 教程,它很有用,但我一直遇到一个重大错误——在代码的图像处理部分使用 OpenCV 时,程序无法保存处理后的图像,因为它不断翻转我的图像的高度和宽度。当我尝试编译时,出现以下错误:

Traceback (most recent call last):
   File "array+and+label+data.py", line 79, in <module>
   hdf5_file["train_img"][i, ...] = img[None]
   File "h5py/_objects.pyx", line 54, in h5py._objects.with_phil.wrapper
   File "h5py/_objects.pyx", line 55, in h5py._objects.with_phil.wrapper
   File "/Users/USER/miniconda2/lib/python2.7/site-packages/h5py/_hl/dataset.py", line 631, in __setitem__
   for fspace in selection.broadcast(mshape):
   File "/Users/USER/miniconda2/lib/python2.7/site-packages/h5py/_hl/selections.py", line 299, in broadcast
   raise TypeError("Can't broadcast %s -> %s" % (target_shape, count))
   TypeError: Can't broadcast (1, 240, 320, 3) -> (1, 320, 240, 3)     

我的图像应该全部为 320 x 240,但您可以看到这是以某种方式翻转的。研究表明这是因为 OpenCV 和 NumPy 对高度和宽度使用不同的约定,但我不确定如何在不修补我的 OpenCV 安装的情况下在此代码中协调这个问题。关于如何解决这个问题的任何想法?我是 Python 及其所有库的相对新手(尽管我很了解 Java)!

提前谢谢你!

编辑:为上下文添加更多代码,这与教程中“加载图像并保存它们”代码示例下的内容非常相似。

我的数组的大小:

train_shape = (len(train_addrs), 320, 240, 3)
val_shape = (len(val_addrs), 320, 240, 3)
test_shape = (len(test_addrs), 320, 240, 3)

循环遍历图像地址并调整它们大小的代码:

# Loop over training image addresses
  for i in range(len(train_addrs)):
     # print how many images are saved every 1000 images
     if i % 1000 == 0 and i > 1:
     print ('Train data: {}/{}'.format(i, len(train_addrs)))

     # read an image and resize to (320, 240)
     # cv2 load images as BGR, convert it to RGB
     addr = train_addrs[i]
     img = cv2.imread(addr)
     img = cv2.resize(img, (320, 240), interpolation=cv2.INTER_CUBIC)
     img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

     # save the image and calculate the mean so far
     hdf5_file["train_img"][i, ...] = img[None]
     mean += img / float(len(train_labels))

【问题讨论】:

  • 提供图像和ndarrays的更多代码和形状。我想重塑 numpy 数组应该会有所帮助。 numpy documentation 是一个很好的广播资源。
  • 谢谢@skrubber,我添加了更多代码上下文。如果您想查看我遵循的完整代码示例,它实际上在上面的教程链接中,如果有帮助的话!
  • 你也回滚img的2轴吗?而且我在教程中没有看到异常处理。您为哪个代码 sn-p 捕获了异常?
  • 我更新了上面的错误以包含整个 sn-p - 它发生在保存 hdf5_file 的循环的倒数第二行,"hdf5_file["train_img"][i, ... ] = img[无]"
  • 切片为 None 的数组意味着正在插入一个新轴,即 1。所以形状为 320,240 的 img 将变成 (1,320,240),正如您在广播的形状上看到的那样进入。但 hd5_file train_img 的形状是 240,320。在本教程的情况下,它会起作用,因为行和列的暗淡是相同的:224。但在你的行和列暗淡不相等的情况下,它不会。试试 320x320。

标签: python numpy opencv computer-vision


【解决方案1】:

研究表明这是因为 OpenCV 和 NumPy 使用不同的高度和宽度约定

不完全是。图像唯一棘手的是二维数组/矩阵使用 (row, col) 进行索引,这与我们可能用于图像的正常笛卡尔坐标 (x, y) 相反。因此,有时当您在 OpenCV 函数中指定点时,它希望它们在 (x, y) 坐标中——同样,它希望在 (w, h) 而不是 (h, w) 就像一个数组一样。这就是 OpenCV 的 resize() 函数内部的情况。你在 (h, w) 中传递它,但它实际上想要 (w, h)。来自docs for resize()

dsize – 输出图像大小;如果它等于 0,则计算为:

dsize = Size(round(fx*src.cols), round(fy*src.rows))

dsizefxfy 都必须非零。

所以你可以在这里看到列数是第一个维度(宽度),行数是第二个维度(高度)。

简单的解决方法就是在 resize() 函数中将 (h, w) 交换为 (w, h):

img = cv2.resize(img, (240, 320), interpolation=cv2.INTER_CUBIC)

【讨论】:

  • 这很简单,而且完全有效!非常感谢你,亚历山大!我也很感谢您对索引的解释,这很有意义。谢谢:)
猜你喜欢
  • 2014-04-28
  • 2020-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多