我应该如何将它从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)
),并在matlab中访问了关键点类中的size
成员而不是frames[3]
,但这些都是微小的变化。< / p>
我不确定的是,我应该如何处理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)
)。似乎很容易,但我不知道我哪里出错了。
非常感谢任何帮助,谢谢:)
答案 0 :(得分:2)
问题是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.]))