删除存储为数组的图像中的像素



我有一个 numpy 数组I,它存储大小为P(像素数(的N张图像。每个图像的大小都是P = q*q.

N = 1000 # number of images
q = 10 # length and width of image
P = q*q # pixels of image
I = np.ones((N,P)) # array with N images of size P

现在我想删除所选索引IDX周围的大小ps的补丁(将所有值设置为零(。

ps = 2 # patch size (ps x ps)
IDX = np.random.randint(0,P,(N,1))

我的方法是使用reshape(q,q)重塑每个图像并删除IDX周围的像素。在这里我遇到了一个问题,我不知道如何计算给定图像IDX内的位置。此外,我必须检查索引是否不在图像之外。

如何解决这个问题,有没有办法对这个过程进行矢量化?

编辑:

在@Brenlla的帮助下,我做了以下工作来删除补丁。我的方法的问题是,它需要三个for循环,我必须重新塑造每个图像两次。有什么方法可以提高性能吗?这部分会大大减慢我的代码速度。

import numpy as np
import matplotlib.pyplot as plt
def myplot(I):
imgs = 10
for i in range(imgs**2):
plt.subplot(imgs,imgs,(i+1))
plt.imshow(I[i].reshape(q,q), interpolation="none")
plt.axis("off")
plt.show()
N = 10000
q = 28
P = q*q
I = np.random.rand(N,P)
ps = 3
IDX = np.random.randint(0,P,(N,1))
for i in range(N):
img = I[i].reshape(q,q)
y0, x0 = np.unravel_index(IDX[i,0],(q,q))
for x in range(ps):
for y in range(ps):
if (x0+x < q) and (y0+y < q):
img[x0+x,y0+y] = 2.0
I[i] = img.reshape(1,q*q)
myplot(I)

是的,这是可以做到的,但它涉及大量使用 np.broadcasting。

生成数据以及I的硬拷贝:

import time
N = 10000
q = 28
P = q*q
ps = 3 
I = np.random.rand(N,P)
IDX = np.random.randint(0,P,(N,1))
I_copy = I.copy()

现在运行循环解决方案。我切换了x0y0

t0=time.clock()
for i in range(N):
img = I[i].reshape(q,q)
x0, y0 = np.unravel_index(IDX[i,0],(q,q))
for x in range(ps):
for y in range(ps):
if (x0+x < q) and (y0+y < q):
img[x0+x,y0+y] = 2.0
I[i] = img.reshape(1,q*q)
print('With loop: {:.2f} ms'.format(time.clock()*1e3-t0*1e3))

在我的机器上大约 276 毫秒。现在播出:

t0 = time.clock()
x_shift, y_shift = np.meshgrid(range(ps), range(ps))
x, y = np.unravel_index(IDX, (q,q))
#roi for region of interest
roix = x[:,:,None]+x_shift; 
roiy = y[:,:,None]+y_shift;
roix[roix>q-1] = q-1; roiy[roiy>q-1] = q-1;
I_copy.reshape(N,q,q)[np.arange(N)[:, None, None], roix, roiy] = 2.0
print('No loop: {:.2f} ms'.format(time.clock()*1e3-t0*1e3))
print(np.array_equal(I, I_copy))

速度大约快 80 倍

最新更新