向图像添加新通道

Adding a new channel to an image

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

我有边缘检测功能,我什至可以附加图像,但由于某种原因,循环后的数据 'reverts'。我对图像大小所做的更改没有保留。


代码

我有三组 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)

其他尝试

如果我用 dataset[i] = np.concatenate((img, edges),axis=2) 替换 img = 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)
  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?难道你不认为你必须以某种方式存储程序的结果到 "remember" 吗?

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

好的,我之前的回答不够详细,不符合某些人的口味,所以被否决了。所以,让我提供一个 "ready" 解决方案:

# 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 循环开始之前展开,这可能会节省一些内存。