我试图弄清楚CNN中的步幅是如何编码的,我似乎无法有效地实现它 - 脚本需要很长时间才能完成计算或我遇到错误
from PIL import Image
img = Image.open('C:\sample_pic.jpeg').convert("RGB") #800 x600 dimensions
pixels =np.array(img) # However PIL inverts height and width so #600 X800
print(pixels.shape) # (600L, 800L, 3L)
理想情况下,我不想展平图像,但是当正确使用1的步幅时,我无法弄清楚如何将600 x 800 x 3图像与2x3x3的滤镜相乘。所以我试图压扁阵列,因为我觉得它会更容易。
flat = pixels.flatten()
filter1= np.array([1,1,0],)
pixels2 = np.array([])
for i in range(0, len(flat),2):
pixels2 =np.append(pixels2,np.sum((flat[i:i+3] * filter1)))
所以我试图将每个像素的RGB值乘以滤波器,然后取总和然后滑动2.我试图看到CNN的第一个卷积层。 在这里,我无法弄清楚如果i + 3元素可用,如何告诉循环只迭代。我认为这就是我收到以下错误的原因
ValueError: operands could not be broadcast together with shapes (2,) (3,)
此外,还有一种计算速度更快的方法可将滤镜值与图像的像素值相乘,因为它需要花费很长时间才能在笔记本电脑上进行计算。 (英特尔i-7 3610QM @ 2.30 Geforce 650M GT 2GB)
编辑:为了清晰起见进行编辑。如果可以将600x800x3阵列与2x3x3的滤波器相乘,那么我想使用1的步幅。 我希望过滤器看起来像这样,
[[[1,1,0]
[1,1,0]
[1,1,0]]
[[1,1,0]
[1,1,0]
[1,1,0]]]
每行2列,每列3列,有三个值[1,1,0]
原始图像为600行(高),800列(宽)和3个值(RGB值)。
对不起有任何困惑。
图片我正在使用:
答案 0 :(得分:1)
不是最佳解决方案,因为它会在 1 中产生副本。但是:stack
,
from scipy.signal import convolve2d
res = np.stack([
convolve2d(pixels[...,i], filter[...,i], mode='valid')
for i in range(3)
], axis=-1)
或消除幻数3
:
res = np.stack([
convolve2d(plane, filterp, mode='valid')
for plane, filterp in zip(np.rollaxis(pixels, -1), np.rollaxis(filter, -1))
], axis=-1)
1 - 实际上,由于convolve2d没有out
参数,所以没有其他选择
答案 1 :(得分:1)
这是一种Scipy's 2D convolution
并采用步幅 -
from scipy.signal import convolve2d as conv2
def filter_images3D(img3D, filter3D, stride=1):
M1,N1 = img3D.shape[:2]
M2,N2 = filter3D.shape[:2]
O1,O2 = (M1-M2+stride)//stride, (N1-N2+stride)//stride
n = img3D.shape[-1]
out = np.empty((O1,O2,n))
for i in range(n):
out[...,i] = conv2(img3D[...,i],filter3D[...,i],'valid')[::stride,::stride]
return out