我正在尝试使用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'
有人知道导致此错误的原因吗?
我真的不喜欢回答我自己的问题,但如果有人遇到同样的问题,我会答应的。
解决方案非常简单,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
检查!
float
至uint8
部分几乎相同,唯一的区别是复制图像时具有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
,则非常简单。