向图像添加新频道

时间:2017-07-07 02:47:46

标签: python opencv numpy computer-vision

我正在尝试添加第4个"频道"到图像。具体来说,我有一个RGB图像,并希望将该图像矩阵与Canny过滤器找到的边缘检测层相加,然后我将其用作神经网络的输入。

我有边缘检测工作,我甚至可以附加图像,但出于某种原因,数据“恢复”'循环后。我在图像大小上所做的更改不会粘住。

代码

我有三组32x32x3彩色图片:X_trainX_validX_test。对于每一个,我正在对图像进行标准化,然后附加渐变。循环时附加似乎生效,但循环后变化不存在。

代码段

import cv2 as cv
example_record = 2

print('X_train is shape {}'.format(X_train.shape))
print('X_valid is shape {}'.format(X_valid.shape))
print('X_test is shape {}'.format(X_test.shape))

# Show before
plt.imshow(X_valid[example_record])
plt.title('Validation Input {} Before Normalization'.format(example_record))

# Normalize
canny_low = 50
canny_high = 100
for dataset in [X_train, X_valid, X_test]:
    for i, img in enumerate(dataset):
        cv.normalize(img, img, 0, 255, cv.NORM_MINMAX)
        edges = cv.Canny(img, canny_low, canny_high)
        edges = np.reshape(edges, (img.shape[0], img.shape[1], 1))
        img = np.concatenate((img, edges),axis=2)
        if i == 0:
            print('img shape after concatenation {}'.format(img.shape))

# Show after
plt.figure()
print('Updated image shape: {}'.format(X_valid[example_record].shape))
plt.imshow(X_valid[example_record])
plt.title('Validation Input {} After Normalization'.format(example_record))

输出

X_train is shape (34799, 32, 32, 3)
X_valid is shape (4410, 32, 32, 3)
X_test is shape (12630, 32, 32, 3)
img shape after concatenation (32, 32, 4)
img shape after concatenation (32, 32, 4)
img shape after concatenation (32, 32, 4)
Updated image shape: (32, 32, 3)

其他尝试

如果我将img = np.concatenate((img, edges),axis=2)替换为dataset[i] = np.concatenate((img, edges),axis=2),我会收到错误:

     21         edges = cv.Canny(img, canny_low, canny_high)
     22         edges = np.reshape(edges, (img.shape[0], img.shape[1], 1))
---> 23         dataset[i] = np.concatenate((img, edges),axis=2)
     24         if i == 0:
     25             print('img shape after concatenation {}'.format(img.shape))

ValueError: could not broadcast input array from shape (32,32,4) into shape (32,32,3)

2 个答案:

答案 0 :(得分:1)

好的,我以前的答案对于某人的口味并不够详细,而且还被低估了。所以,让我提供一个“准备好”的解决方案:

# Normalize
canny_low = 50
canny_high = 100
X = [X_train, X_valid, X_test]
X_new = [np.empty(x.shape[:-1] + (x.shape[-1] + 1,), dtype=x.dtype) for x in X]

for dataset, dsnew in zip(X, X_new):
    for i, img in enumerate(dataset):
        cv.normalize(img, img, 0, 255, cv.NORM_MINMAX)
        edges = np.expand_dims(cv.Canny(img, canny_low, canny_high), axis=2)
        dsnew[i, :, :, :] = np.concatenate((img, edges), axis=2)

或者,您可以在循环开始之前展开X_trainX_validX_test ,这可能会节省一些内存。

答案 1 :(得分:0)

  1. 你内心循环

    for i, img in enumerate(dataset):
    

    会覆盖连接img

  2. 的值
  3. print('X_train is shape {}'.format(X_train.shape))
    print('X_valid is shape {}'.format(X_train.shape))
    print('X_test is shape {}'.format(X_train.shape))
    

    正在打印X_train.shape形状的值!

  4. 行后

    img = np.concatenate(...)

    在循环内部,您如何处理连接图像img?难道你不认为你必须以某种方式存储结果才能使程序“记住”它吗?

  5. 您的第二次尝试很有希望,只是不要在img中存储新的dataset。在循环外定义dataset_new(创建一个空列表或正确形状的numpy数组),然后在循环中执行dataset_new[i] = np.concatenate...