【问题标题】:Adding a new channel to an image向图像添加新通道
【发布时间】:2017-07-07 02:47:45
【问题描述】:

我正在尝试向图像添加第四个“通道”。具体来说,我有一个 RGB 图像,并希望在该图像矩阵上附加一个由 Canny 滤波器找到的边缘检测层,然后我将其用作神经网络的输入。

我有边缘检测工作,我什至可以附加图像,但由于某种原因,循环后数据“恢复”。我对图像大小所做的更改没有保留。


代码

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

代码 sn-p

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)

【问题讨论】:

  • 我强烈建议将 img 写入新列表。

标签: python opencv numpy computer-vision


【解决方案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,这样可以节省一些内存。

【讨论】:

  • 是的!我尝试了这种方法和扩展数据集本身,并且都运行良好。我一直认为img 是参考而不是副本。
【解决方案2】:
  1. 你的内循环

    for i, img in enumerate(dataset):
    

    正在覆盖串联img的值

  2. 你的

    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 的形状值!

  3. 行后

    img = np.concatenate(...)

    在循环中,你如何处理拼接的图像img?您不认为您必须以某种方式存储结果以便程序“记住”它吗?

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

【讨论】:

  • 这个答案确实触及了问题,但没有触及解决方案。您应该添加更多内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-25
  • 2017-07-07
  • 1970-01-01
  • 2018-08-20
  • 2019-07-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多