我正在将我的matlab代码传输到python。有很多东西我试图在python和numpy中找到替换
Matlab代码:
[m,n]=size(Image);
canvas=zeros(m,n);
U_res_sel=squeeze(loading);
[s1,s2]=size(U_res_sel);
if mod(s1,2)==0
dy=s1/2-1;
else
dy=(s1-1)/2;
end
if mod(s2,2)==0
dx=s2/2-1;
else
dx=(s2-1)/2;
end
xmin=dx+1;
ymin=dy+1;
xmax=n-(s2-dx-1);
ymax=m-(s1-dy-1);
[x,y]=meshgrid(xmin:xmax,ymin:ymax);
ind=sub2ind([m,n],y(:),x(:));
nps=repmat(((-dx+(0:s2-1))*m-dy),s1,1)+repmat((0:(s1-1)).',1,s2);
ind=repmat(ind,1,numel(nps))+repmat(nps(:).',numel(ind),1);
A=(Image(ind)-repmat(mean(Image(ind),2),1,numel(nps)));
B=repmat((U_res_sel(:)-mean(U_res_sel(:))).',size(ind,1),1);
canvas(ymin:ymax,xmin:xmax)=reshape(sum(A.*B,2)./sqrt(sum((A.^2),2).*sum((B.^2),2)),ymax-ymin+1,[]);
canvas = canvas(y1+1:z1+y1+1,y2+1:z2+y2+1);
我想我会逐行解释问题的发生。
我正在使用
将numpy导入为np
用于numpy函数
1
变量工作正常,直到我到达python中的meshgrid行。
[x,y] = np.mgrid[xmin:xmax,ymin:ymax]
matlab中的x使用测试数据的大小为517,517 python中的x的大小有516乘516所以我用
更改了代码的python部分 xmax=n-(s2-dx-1) + 1
ymax=m-(s1-dy-1) + 1
[y,x] = np.mgrid[xmin:xmax,ymin:ymax]
使其与matlab代码具有相同的数据集。但我不确定索引是否合理。如果我在matlab中使用完全相同的矩阵到numpy数组它们是等价的吗?
2
下一个matlab系列让我弄清楚。
ind=sub2ind([m,n],y(:),x(:));
表示x(:)和y(:)我正在使用
x = np.reshape(x,(x.size,1))
y = np.reshape(y,(y.size,1))
x = np.int64(x)
y = np.int64(y)
我在python中使用的sub2ind函数
ind = np.ravel_multi_index((y,x), dims=(m,n) )
但这里是数字搞乱的地方。
在matlab中的我得到一个范围为3723到278760的列向量,用于某个数据集 并为相同的数据集 在python中,我得到一个4264到279292的列向量,其间有不同的步进。
它们两者的大小相同(267289,1)。
3
这条线我在matlab和python中运行良好我只是把它放在这里所以我可以简洁自己。
MATLAB:
nps=repmat(((-dx+(0:s2-1))*m-dy),s1,1)+repmat((0:(s1-1)).',1,s2);
蟒:
dtx = (-dx + np.arange(0,s2,1))
dtx_2 = np.arange(0,s1,1)
dtx_2 = np.reshape(dtx_2,(dtx_2.size,1))
nps = np.tile( dtx*m-dy,(s1,1) ) + np.tile( dtx_2 ,(1,s2) )
(4)。
for matlab中的行
ind=repmat(ind,1,numel(nps))+repmat(nps(:).',numel(ind),1);
在python中我正在尝试
a = np.tile(ind,(1,nps.size))
b = np.tile( np.transpose(dtind) , (ind.size,1) )
ind = a + b
我把它分成a和b,使其更具可读性。
但这并没有真正按预期工作。
(5)。
我不确定如何在python中通过索引访问变量。
在matlab中我可以做Image(ind),但是现在我的代码在python中没用了,因为我找不到替代方案吗?
如果您尝试运行matlab代码,请注意,如果您在大数据集上运行它,它将导致您的计算机和matlab冻结并崩溃而不会发出警告。我通过将代码放在一个包装器中来解决这种情况,该包装器索引数据的较小部分以获得防止内存溢出的最终大图像。
我希望我的代码混乱得足够清楚。这段代码在matlab中运行得很好,但是matlab在我的项目基础上非常糟糕,主要是因为我无法将代码提供给其他人。
编辑:
这个函数是一个矢量化程序,它基本上可以:(这是伪代码,所以索引可能不是我的头脑)
此段中也没有填充。我使用的加载变量是高斯矩阵或Lapacian,其范围可以从6x6到64x64。它可以是任何尺寸,只要它小于图像。
correlation_coeficcient_surface = function(Image,loading)
[m,n] = size(image)
[u1,u2] = size(loading)
canvas = zeros(size(image))
for yii = 1:n
for xii = 1:m
image_segment = Image(yii-floor(u1/2):yii+ceil(u1/2),xii-floor(u2/2):xii+ceil(u2/2));
if(size(image_segment) == size(loading)
canvas(yii-floor(u1/2):yii+ceil(u1/2),xii-floor(u2/2):xii+ceil(u2/2)) = corr2(Image_segment,loading);
end
end
end
end
它必须被矢量化,因为迭代每个元素使得在大图像上花费很长时间。
修改编辑:
这是我的过滤器实际上做的事情。
这是一个示例图像
http://i.imgur.com/o9kV3nK.png
这是我用来与
关联的示例加载形状http://i.imgur.com/oYW3k2K.png
这是在我的matlab过滤器完成之后,图像没有对齐,我只是通过裁剪示例来向您展示它的形状。
http://i.imgur.com/aa4ljue.png
这是scipy.signal.convolve2d,它做了我不想要的事情。
答案 0 :(得分:2)
我认为你应该放慢一点,阅读一些关于python数组基础知识的资料,比如索引和广播。首先,我在http://www.sam.math.ethz.ch/~raoulb/teaching/PythonTutorial/intro_numpy.html阅读了基础教程。另外http://mathesaurus.sourceforge.net/matlab-numpy.html包含一个表,其中包含某些numpy和matlab操作之间的对应关系。但是,总的来说,我会保持开放的心态,并意识到matlab方式通常不是最好的方式。
我没有直接回答你的所有问题,但以下是一些想法。
arr(1:100)
与numpy arr[0:100]
相同。通常,repmat
的功能由智能广播处理,不需要手动调用tile
。例如,下面的代码生成一个随机的100x100数组,计算行平均值,并从行中减去行均值(例如,将数据居中):
arr = np.random.rand(100,100)
mu = arr.mean(axis=1)
centered = arr - mu[:,None]
mu[:,None]
数组的大小(100,1),而numpy
足够聪明,以及#34;广播"它的大小(100,100)来计算centered
。继续这个例子,mu[:,None,None]
的大小(100,1,1)。
Matlab' size(arr)
与numpy' arr.shape
相同。
编辑:例如,您可以更简洁地完成#3:
nps = (-dx+np.arange(s2)*m -du)[None,:] + np.arange(s1)[:,None]
和#4:
ind= ind[:, None] + nps.ravel()[None, :]
答案 1 :(得分:2)
关于x
和y
- 值的顺序不同,如果您尝试展平它们,您会看到:
x(:)'
1 1 ... 2 2 ....
x.flatten()
array([ 1, 2, ... 10, 1, 2,...])
那就是MATLAB数组的排列方式类似于'F'numpy数组,而不是默认的'C'。
对于小尺寸,我可以将octave和numpy与:
匹配"""
octave:47> [x,y]=meshgrid(1:3,3:4)
x =
1 2 3
1 2 3
y =
3 3 3
4 4 4
octave:48> ind=sub2ind([5,5],y,x)
3 8 13
4 9 14
"""
Y,X=np.mgrid[2:4,0:3]
"""
array([[2, 2, 2],
[3, 3, 3]])
array([[0, 1, 2],
[0, 1, 2]])
"""
ind = np.ravel_multi_index((X,Y),(5,5))
# np.ravel_multi_index((Y,X),(5,5),order='F')
"""
array([[ 2, 7, 12],
[ 3, 8, 13]])
我对Image(ind)
问题感到困惑。 Image
是[m,n]数组,对吧?
答案 2 :(得分:1)
除了使用我的其他答案中的提示从头开始翻译代码之外,这看起来像卷积,你可能只使用convolve2d(这里没有填充):
scipy.signal.convolve2d(Image, loading, mode='full', fillvalue=0.0)
如果你想做一些比零填充更有趣的事情,请参见http://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.convolve2d.html。
修改:有关卷积的详情,请参阅2D Convolution in Python similar to Matlab's conv2
编辑2:以下代码应计算滑动窗口上的局部相关系数。它应该正确处理边界。
from scipy.signal import correlate2d
import numpy as np
# Generate random image
Image = np.random.rand(100,100)
# make kernel
x = np.arange(-10,11)
loading = np.exp( -(x[:,None]**2 + x[None,:]**2 )/10)
Image = np.tile(loading, (10,10))
m,n = loading.shape
oneskernel = np.ones(loading.shape)
# get number of points within each box of the sliding window
num = correlate2d(np.ones(Image.shape), oneskernel, mode='same')
# get mean over sliding window
Image_mu = correlate2d(Image, oneskernel, mode='same')/num
# Get sig of sliding window
Image_sig = np.sqrt(correlate2d((Image - Image_mu)**2,
oneskernel, mode='same')
/ num)
loading_mu =loading.mean() # mean of kernel
loading_sig = loading.std() # sig of kenrel
# calculate sliding corrcoeff
C = correlate2d(( Image-Image_mu) / Image_sig , (loading -loading_mu)/loading_sig, mode='same') / num