我应该如何将它从Matlab转换为Python:
A = sparse(row_idx, col_idx, values, len, s1 * s2);
scales = zeros(size(A, 1), 1);
scales(sub2ind([s1 s2], floor(frames(2, :)), floor(frames(1, :)))) = ...
frames(3, :);
eq = A \ scales;
我的尝试是:
from scipy.sparse import csr_matrix # to replace sparse matrix
import numpy as np # to replace \ with np.linalg.lstsq
A = csr_matrix((values, (row_idx , col_idx )), shape=(length, width * height))
scales = np.zeros((A.shape[0]));
for kp in kps:
x,y = int(kp.pt[0]), int(kp.pt[1])
scales[y][x] = int(kp.size) # error
scales[y*x] = int(kp.size) # again, error:(
...
eq = np.linalg.lstsq(A, scales)
我更改了变量名称(len -> length
,(s1,s2) -> (width, height)
),并在关键点类中访问size
成员而不是matlab中的frames[3]
,但这些都是微小的变化。
我不确定的是,我应该如何处理scales
创建和索引访问。我似乎想念一些但却找不到什么。
我得到TypeError: 'numpy.float64' object does not support item assignment
这并不让我感到惊讶,因为scales
是1-dim数组,我不应该用[][]
访问它。
然而,将它改为scales[y*x] = int(kp.size)
提出了以下几点:LinAlgError: 0-dimensional array given. Array must be two-dimensional
。
根据我的理解,Matlab代码采用稀疏矩阵,创建一个列向量(scales
)然后填充,使得来自(x,y)
的任何索引frame
(即每个帧的索引(在我的Python代码中为= keypoint
))并插入一个新的所述指数的价值(值为size
的frame(3)
)。看起来很容易,但我不知道我哪里出错了。
任何帮助将不胜感激,谢谢:)
问题是np.linalg.lstsqr
是一个numpy函数,并不了解稀疏矩阵。 Numpy函数如果将作业委托给方法,则会起作用,但如果他们首先尝试将稀疏矩阵转换为数组则不行。
举个简单的例子:
In [345]: R = np.arange(1,6)
In [346]: M = sparse.csr_matrix(([1,1,1],([0,2,4],[0,1,2])),shape=(5,3))
In [347]: M.A
Out[347]:
array([[1, 0, 0],
[0, 0, 0],
[0, 1, 0],
[0, 0, 0],
[0, 0, 1]], dtype=int64)
In [348]: np.linalg.lstsq(M,R, rcond=None)
...
-> 1977 _assertRank2(a, b)
1978 _assertNoEmpty2d(a, b) # TODO: relax this constraint
1979 m = a.shape[0]
/usr/local/lib/python3.6/dist-packages/numpy/linalg/linalg.py in _assertRank2(*arrays)
193 if a.ndim != 2:
....
LinAlgError: 0-dimensional array given. Array must be two-dimensional
它认为M
的维数是0-d,而不是2-d。那是因为,当用np.array
(或`asarray)包装时,稀疏矩阵会产生一个0d对象数组:
In [351]: np.array(M)
Out[351]:
array(<5x3 sparse matrix of type '<class 'numpy.int64'>'
with 3 stored elements in Compressed Sparse Row format>, dtype=object)
In [352]: _.shape
Out[352]: ()
正确的方法是使用自己的方法将稀疏矩阵变为密集:
In [354]: np.linalg.lstsq(M.A,R, rcond=None)
....
Out[354]: (array([1., 3., 5.]), array([20.]), 3, array([1., 1., 1.]))
在MATLAB中,稀疏矩阵被集成到主代码中。在numpy
,他们是一个单独的scipy.sparse
包。稀疏矩阵不是np.ndarray
的子类。
有一个稀疏的线性代数子包:
In [355]: from scipy.sparse import linalg as spla
In [356]: spla.lsqr(M, R)
Out[356]:
(array([1., 3., 5.]),
2,
1,
4.47213595499958,
4.47213595499958,
1.0,
1.0,
4.082652109348718e-16,
5.916079783099617,
array([0., 0., 0.]))