Python 图像中每个像素的 select 7*7 个相邻像素的最快方法
fastest way to select 7*7 neighbor pixels for every pixel in an image in Python
需要将图像读取为数组,每个像素 select 7*7 个相邻像素然后重新整形并作为训练集的第一行:
import numpy as np
from scipy import misc
face1=misc.imread('face1.jpg')
face1
尺寸为(288, 352, 3)
,需要为每个像素找到7*7个相邻像素,所以49*3颜色然后将其整形为(1,147)
数组并将其堆叠成所有像素的数组,我采用了以下方法:
X_training=np.zeros([1,147] ,dtype=np.uint8)
for i in range(3, face1.shape[0]-3):
for j in range(3, face1.shape[1]-3):
block=face1[i-3:i+4,j-3:j+4]
pxl=np.reshape(block,(1,147))
X_training=np.vstack((pxl,X_training))
结果 X_training
形状是 (97572, 147)
最后一行全为 0,则:
a = len(X_training)-1
X_training = X_training[:a]
上面的代码适用于一张图片,但是 Wall time: 5min 19s
我有 2000 张图片,所以对所有图片都需要很长时间。我正在寻找一种更快的方法来遍历每个像素并执行上述任务。
编辑:
这就是我所说的相邻像素的意思,对于每个像素 face1[i-3 : i+4 ,j-3:j+4]
以下是我笔记本电脑上的 < 1s:
import scipy as sp
im = sp.rand(300, 300, 3)
size = 3
ij = sp.meshgrid(range(size, im.shape[0]-size), range(size, im.shape[1]-size))
i = ij[0].T.flatten()
j = ij[1].T.flatten()
N = len(i)
L = (2*size + 1)**2
X_training = sp.empty(shape=[N, 3*L])
for pixel in range(N):
si = (slice(i[pixel]-size, i[pixel]+size+1))
sj = (slice(j[pixel]-size, j[pixel]+size+1))
X_training[pixel, :] = im[si, sj, :].flatten()
X_training = X_training[-1::-1, :]
当我想不出单行矢量化版本时,我总是有点难过,但至少它对你来说更快。
一种有效的方法是使用 stride_tricks
在图像上创建二维滚动 window,然后将其展平:
import numpy as np
face1 = np.arange(288*352*3).reshape(288, 352, 3) # toy data
n = 7 # neighborhood size
h, w, d = face1.shape
s = face1.strides
tmp = np.lib.stride_tricks.as_strided(face1, strides=s[:2] + s,
shape=(h - n + 1, w - n + 1, n, n, d))
X_training = tmp.reshape(-1, n**2 * d)
X_training = X_training[::-1] # to get the rows into same order as in the question
tmp
是图像的 5D 视图,其中 tmp[x, y, :, :, c]
相当于颜色通道 c
.
中的邻域 face1[x:x+n, y:y+n, c]
使用scikit图像:
import numpy as np
from skimage import util
image = np.random.random((288, 352, 3))
windows = util.view_as_windows(image, (7, 7, 3))
out = windows.reshape(-1, 7 * 7 * 3)
需要将图像读取为数组,每个像素 select 7*7 个相邻像素然后重新整形并作为训练集的第一行:
import numpy as np
from scipy import misc
face1=misc.imread('face1.jpg')
face1
尺寸为(288, 352, 3)
,需要为每个像素找到7*7个相邻像素,所以49*3颜色然后将其整形为(1,147)
数组并将其堆叠成所有像素的数组,我采用了以下方法:
X_training=np.zeros([1,147] ,dtype=np.uint8)
for i in range(3, face1.shape[0]-3):
for j in range(3, face1.shape[1]-3):
block=face1[i-3:i+4,j-3:j+4]
pxl=np.reshape(block,(1,147))
X_training=np.vstack((pxl,X_training))
结果 X_training
形状是 (97572, 147)
最后一行全为 0,则:
a = len(X_training)-1
X_training = X_training[:a]
上面的代码适用于一张图片,但是 Wall time: 5min 19s
我有 2000 张图片,所以对所有图片都需要很长时间。我正在寻找一种更快的方法来遍历每个像素并执行上述任务。
编辑:face1[i-3 : i+4 ,j-3:j+4]
以下是我笔记本电脑上的 < 1s:
import scipy as sp
im = sp.rand(300, 300, 3)
size = 3
ij = sp.meshgrid(range(size, im.shape[0]-size), range(size, im.shape[1]-size))
i = ij[0].T.flatten()
j = ij[1].T.flatten()
N = len(i)
L = (2*size + 1)**2
X_training = sp.empty(shape=[N, 3*L])
for pixel in range(N):
si = (slice(i[pixel]-size, i[pixel]+size+1))
sj = (slice(j[pixel]-size, j[pixel]+size+1))
X_training[pixel, :] = im[si, sj, :].flatten()
X_training = X_training[-1::-1, :]
当我想不出单行矢量化版本时,我总是有点难过,但至少它对你来说更快。
一种有效的方法是使用 stride_tricks
在图像上创建二维滚动 window,然后将其展平:
import numpy as np
face1 = np.arange(288*352*3).reshape(288, 352, 3) # toy data
n = 7 # neighborhood size
h, w, d = face1.shape
s = face1.strides
tmp = np.lib.stride_tricks.as_strided(face1, strides=s[:2] + s,
shape=(h - n + 1, w - n + 1, n, n, d))
X_training = tmp.reshape(-1, n**2 * d)
X_training = X_training[::-1] # to get the rows into same order as in the question
tmp
是图像的 5D 视图,其中 tmp[x, y, :, :, c]
相当于颜色通道 c
.
face1[x:x+n, y:y+n, c]
使用scikit图像:
import numpy as np
from skimage import util
image = np.random.random((288, 352, 3))
windows = util.view_as_windows(image, (7, 7, 3))
out = windows.reshape(-1, 7 * 7 * 3)