[Python中使用OpenCV的blobFromImage声明错误

问题描述 投票:0回答:1

我正在尝试使用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功能创建了一个“斑点”,后来又喂入网络。

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个回答
0
投票

我真的不喜欢回答我自己的问题,但如果有人遇到同样的问题,我会答应的。

解决方案非常简单,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格式的图像。

示例:灰度图像

假设我们要使用尺寸为100x100的float预处理img图像(blobFromImage):

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,则非常简单。

© www.soinside.com 2019 - 2024. All rights reserved.