【问题标题】:blobFromImage Assertion error using OpenCV in Python在 Python 中使用 OpenCV 的 blobFromImage 断言错误
【发布时间】:2020-09-13 09:24:32
【问题描述】:

我正在尝试在 Python 中使用 OpenCV 运行(而不是训练)Caffe 网络。

我的图像 (img) 是 (48,118) 的单通道 ndarray

# single channel to RGB like
frame = np.zeros((img.shape[0], img.shape[1], 3))
frame[:,:,0] = img
frame[:,:,1] = img
frame[:,:,2] = img

然后我将其归一化为 0-1。

frame /= np.max(frame)

最后,我使用blobFromImage 函数创建了一个“blob”,然后喂给了网络。

inpBlob = cv2.dnn.blobFromImage(frame, size=(368,368), mean=(0,0,0), swapRB=False, crop=False)

使用上面的行后会出现问题。它引发了一个断言错误:

---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
c:\Users\helde\code\main.py in 
----> 67 inpBlob = cv2.dnn.blobFromImage(frame, size=(368,368), mean=(0,0,0), swapRB=False, crop=False)

error: OpenCV(3.4.2) C:\Miniconda3\conda-bld\opencv-suite_1534379934306\work\modules\dnn\src\dnn.cpp:177: 
error: (-215:Assertion failed) image.depth() == 5 in function 'cv::dnn::experimental_dnn_v5::blobFromImages'

有人知道是什么导致了这个错误吗?

【问题讨论】:

    标签: python opencv blob


    【解决方案1】:

    我真的不喜欢回答我自己的问题,但是,我会以防其他人有同样的问题。

    解决方案很简单,OpenCV 的blobFromImage 需要uint8 格式的图像。

    所以,在我的例子中,变量 frame 是灰度的,之前我将它缩放到 0-1:

    frame /= np.max(frame)
    

    在这种情况下,新框架是float

    正确的等待,与blobFromImage一起工作,将其转入uint8是:

    img = ((frame / np.max(frame)) * 255).astype('uint8')
    

    你需要这个 ....astype('uint8') 否则你会得到一些像素值在 0-255 之间但仍然是 float 格式的东西。

    示例:灰度图像

    假设我们有一个 float 图像 (img),我们想用 blobFromImage 进行预处理,尺寸为 100x100:

    print(img.shape, type(img), img.dtype)
    (48, 118) <class 'numpy.ndarray'> float64
    

    现在,如前所述将其转换为灰度

    img = ((img / np.max(img)) * 255).astype('uint8')
    

    只是为了检查:

    print(img.shape, type(img), img.dtype)
    (48, 118) <class 'numpy.ndarray'> uint8
    

    现在我们可以申请blobFromImage:

    inpBlob = cv2.dnn.blobFromImage(img, 
                                    size=(368,368), 
                                    mean=(0,0,0), 
                                    swapRB=False, 
                                    crop=False)
    

    现在,你必须拥有 4D 的东西:

    print(inpBlob.shape, type(inpBlob), inpBlob.dtype)
    (1, 1, 368, 368) <class 'numpy.ndarray'> float32
    

    检查!

    示例:RGB 图像

    floatuint8 部分几乎相同,唯一的区别是在复制图像以具有 3 通道 RGB 时。我将把整个代码,并指出复制部分:

    # we start with the same float image (img) as before
    
    # converting to uint8. Still one channel
    img = ((img / np.max(img)) * 255).astype('uint8')
    
    print(img.shape, type(img), img.dtype)
    (48, 118) <class 'numpy.ndarray'> uint8
    
    # replicating the only channel 3 times. There are other ways to do this:
    img_rgb = np.zeros((img.shape[0], img.shape[1], 3), dtype=np.uint8)
    img_rgb[:,:,0], img_rgb[:,:,1], img_rgb[:,:,2] = img, img, img
    
    # now you'll see a thrid dimension in the shape
    print(img_rgb.shape, type(img_rgb), img_rgb.dtype)
    (48, 118, 3) <class 'numpy.ndarray'> uint8
    
    # applying the blobFromImage function
    inpBlob = cv2.dnn.blobFromImage(img_rgb, 
                                    size=(368,368), 
                                    mean=(0,0,0), 
                                    swapRB=False, 
                                    crop=False)
    
    # checking...
    print(inpBlob.shape, type(inpBlob), inpBlob.dtype)
    (1, 3, 368, 368) <class 'numpy.ndarray'> float32
    # the 3 channels are reflected in the second component of inpBlop's shape.
    

    如您所见,如果您之前将其更改为 uint8,则非常简单。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-20
      • 1970-01-01
      • 1970-01-01
      • 2018-05-19
      • 1970-01-01
      • 2017-10-26
      • 2016-08-02
      • 1970-01-01
      相关资源
      最近更新 更多