仅使用 NumPy 的 Python 图像卷积

我正在尝试仅使用 NumPy 来实现图像卷积代码,类似于cv2.filter2D(...)的做法。


import numpy as np

import time


# kernal

H = np.array([[0,1,0],[1,-4,1],[0,1,0]])


# image

SEED = 23

img = np.random.RandomState(SEED).randint(10, size=(4, 4))


# shapes

Hi, Wi = img.shape

Hk, Wk = H.shape

hk = Hk//2

wk = Wk//2


# padding

new_img = np.pad(img, (hk, wk), 'constant', constant_values=0)

pHi, pWi = new_img.shape


print('img: ')

print(new_img)


print('kernal: ')

print(H)

print('\n')


# image convolution

##################################################

# Method 1

st = time.time()


out = np.zeros((Hi, Wi))

for i in range(hk, pHi-hk):

    for j in range(wk, pWi-wk):

        batch = new_img[i-hk:i+hk+1, j-wk:j+wk+1]

        out[i-hk][j-wk] = np.sum(batch*H)


print('out: ')

print(out)


print("[*] process time : %f" % (time.time()- st))

print('\n')

##################################################

# Method 2

st = time.time()

Hi, Wi = img.shape


out = np.zeros((Hi, Wi))


H_1d = H.ravel()

hl = len(H_1d)


for i in range(Wi):

    img_slice = new_img[:, i:Hk+i]

    for j in range(Hi):

        out[j][i] = np.sum(img_slice[j:j+Hk,:]*H)


    il = len(img_slice)

    h1 = 0

    h2 = hl

    

    while h2 <= il:

        index = h1//Hk

        # print(index)

        out[index][i] = np.sum(img_slice[h1:h2]*H_1d)

        h1 = h1 + Hk

        h2 = h2 + Hk


print('out: ')

print(out)


print("[*] process time : %f" % (time.time()- st))

print('\n')


##################################################

它有效,但我需要更快、更有效的实施。为了使算法更快,我尝试在此处查看图像的卷积过程中找到模式,但仍然无法弄清楚应该做什么。


有人可以帮助我改进当前的代码,使其更快,仅使用 NumPy 吗?


慕仙森
浏览 121回答 1
1回答

交互式爱情

这是使用 strides 的更快方法(请注意,view_as_windows在底层使用 numpy strides。如果您必须严格使用 numpy,只需使用 numpy 包中的 strides 即可。了解 numpy 中的等效实现view_as_windows):from skimage.util import view_as_windowsout = view_as_windows(new_img, (Hk,Wk))out = np.einsum('ijkl,kl->ij',out,H)输出:out: [[  0  -5 -10 -19] [-10  -7  -2 -18] [  5  -7  11   7] [-12  -9  11 -18]]输入的时间:#Method 1[*] process time : 0.000615#Method 2[*] process time : 0.000475#proposed method in this answer[*] process time : 0.000348较大阵列的计时使用benchit:(方法2对于较大的数组有错误)方法 3 比方法 1 快几个数量级。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python