简体   繁体   English

Matlab与Python 2D卷积性能

[英]Matlab vs Python 2D convolution performance

I like to prototype algorithms in Matlab, but I have the requirement of putting them on a server that also runs quite a bit of Python code. 我喜欢在Matlab中对算法进行原型设计,但我要求将它们放在也运行大量Python代码的服务器上。 Hence I quickly converted the code to Python and compared the two. 因此,我迅速将代码转换为Python并进行了比较。 The Matlab implementation runs ~1000 times faster (from timing function calls - no profiling). Matlab实现的运行速度快了约1000倍(通过计时函数调用-无性能分析)。 Anyone know off hand why the performance of Python is so slow? 有人知道为什么Python的性能这么慢吗?

Matlab Matlab的

% init random data
w = 800;
h = 1200;
hmap = zeros(w,h);

npts = 250;
for i=1:npts
    hmap(randi(w),randi(h)) = hmap(randi(w),randi(h))+1;
end

% Params
disksize = 251;
nBreaks = 25;
saturation = .9;
floorthresh =.05;

fh = fspecial('gaussian', disksize, disksize/7);
hmap = conv2(hmap, fh, 'same');

% Scaling, paritioning etc
hmap = hmap/(max(max(hmap)));
hmap(hmap<floorthresh) = 0;
hmap = round(nBreaks * hmap)/nBreaks;
hmap = hmap * (1/saturation);

% Show the image
imshow(hmap, [0,1])
colormap('jet')

Python 蟒蛇

import numpy as np
from scipy.signal import convolve2d as conv2

# Test data parameters
w = 800
h = 1200
npts = 250

# generate data
xvals = np.random.randint(w, size=npts)
yvals = np.random.randint(h, size=npts)

# Heatmap parameters
gaussianSize = 250
nbreaks = 25

# Preliminary function definitions
def populateMat(w, h, xvals, yvals):
    container = np.zeros((w,h))

    for idx in range(0,xvals.size):
        x = xvals[idx]
        y = yvals[idx]
        container[x,y] += 1

    return container

def makeGaussian(size, fwhm):

    x = np.arange(0, size, 1, float)
    y = x[:,np.newaxis]

    x0 = y0 = size // 2

    return np.exp(-4*np.log(2) * ((x-x0)**2 + (y-y0)**2) / fwhm**2)


# Create the data matrix
dmat = populateMat(w,h,xvals,yvals)
h = makeGaussian(gaussianSize, fwhm=gaussianSize/2)

# Convolve
dmat2 = conv2(dmat, h, mode='same')

# Scaling etc
dmat2 = dmat2 / dmat2.max()
dmat2 = np.round(nbreaks*dmat2)/nbreaks
# Show
imshow(dmat2)

Ok, problem solved for me thanks to suggestion from @Yves Daust's comments; 好了,感谢@Yves Daust的评论为我解决了问题;

The filter scipy.ndimage.filters.gaussian_filter utilises the separability of the kernel and reduces the running time to within a single order of magnitude of the matlab implementation. 过滤器scipy.ndimage.filters.gaussian_filter利用内核的可分离性,并将运行时间减少到matlab实现的单个数量级内。

import numpy as np
from scipy.ndimage.filters import gaussian_filter as gaussian


# Test data parameters
w = 800
h = 1200
npts = 250

# generate data
xvals = np.random.randint(w, size=npts)
yvals = np.random.randint(h, size=npts)

# Heatmap parameters
gaussianSize = 250
nbreaks = 25

# Preliminary function definitions
def populateMat(w, h, xvals, yvals):
    container = np.zeros((w,h))

    for idx in range(0,xvals.size):
        x = xvals[idx]
        y = yvals[idx]
        container[x,y] += 1

    return container


# Create the data matrix
dmat = populateMat(w,h,xvals,yvals)

# Convolve
dmat2 = gaussian(dmat, gaussianSize/7)

# Scaling etc
dmat2 = dmat2 / dmat2.max()
dmat2 = np.round(nbreaks*dmat2)/nbreaks

# Show
imshow(dmat2)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM