代码之家  ›  专栏  ›  技术社区  ›  wasd

如何将cv2.imread与keras image.img_加载输出匹配

  •  9
  • wasd  · 技术社区  · 6 年前

    我在学习深度学习。训练了一种图像分类算法。但问题是,为了训练我使用的图像:

    test_image = image.load_img('some.png', target_size = (64, 64))
    test_image = image.img_to_array(test_image)
    

    而对于实际应用,我使用:

    test_image = cv2.imread('trick.png')
    test_image = cv2.resize(test_image, (64, 64))
    

    但我发现它们给出了不同的ndarray(不同的数据):

    加载图像的最后条目:

      [ 64.  71.  66.]
      [ 64.  71.  66.]
      [ 62.  69.  67.]]]
    

    来自cv2.imread的最后条目:

      [ 15  23  27]
      [ 16  24  28]
      [ 14  24  28]]]
    

    ,所以系统无法工作。有没有办法把一个结果和另一个结果相匹配?

    2 回复  |  直到 6 年前
        1
  •  9
  •   rayryeng    6 年前

    opencv以bgr格式读取图像,而在keras中,它以rgb表示。要使opencv版本符合我们期望的顺序(rgb),只需反转通道:

    test_image = cv2.imread('trick.png')
    test_image = cv2.resize(test_image, (64, 64))
    test_image = test_image[...,::-1] # Added
    

    最后一行将通道反转为rgb顺序。你可以把这个输入你的凯拉斯模型。

    我想补充一点 cv2.imread 通常读入图像 uint8 精度。检查keras加载图像的输出,可以看到数据是浮点精度的,因此您可能还希望转换为浮点表示,例如 float32 :

    import numpy as np
    # ...
    # ...
    test_image = test_image[...,::-1].astype(np.float32)
    

    最后一点,取决于您如何训练模型,通常将图像像素值规格化为 [0,1] 范围。如果对Keras模型执行此操作,请确保将通过Opencv读取的图像中的值除以255:

    import numpy as np
    # ...
    # ...
    test_image = (test_image[...,::-1].astype(np.float32)) / 255.0
    
        2
  •  4
  •   Kyle Vrooman    6 年前

    除了使用bgr格式的cv2和使用rgb格式的keras(使用pil作为后端)外,使用相同参数的cv2和pil的大小调整方法也有显著差异。

    在因特网上可以找到多个参考文献,但总的想法是,在两种调整大小算法中使用的像素坐标系存在细微的差异,而且在插值算法中,不同的铸造方法作为中间步骤浮动也可能存在问题。最终的结果是一个视觉上相似的图像,但在不同版本之间有轻微的移动/扰动。

    一个对抗性攻击的完美例子,尽管输入的差异很小,但会导致精度的巨大差异。