【发布时间】:2017-08-15 22:29:44
【问题描述】:
我要解决的问题是这样的:给定图像中的一个斑点,我想获得它的方向来指导我画线来填充该区域。我希望线条遵循该区域的长轴,使用尽可能少的线条。
我四处搜索,发现 PCA(主成分分析)是一种很好的方法来获取 blob 的方向,通过为 PCA 算法提供所有点坐标:
但是复制确切的算法,我得到了非常令人惊讶的结果。给定形状相似的区域,PCA 算法返回完全不同的特征向量。它们看起来是垂直的:
上面的线条是按照PCA算法给出的斜率渲染的,有轻微的随机变化。
我对数据处理了解不多,这里发生了什么?我该如何解决这个问题?
代码:
import numpy as np
# I tried passing different set of points to pca:
# 1. Only points at the perimeter of the area
# 2. Random sample of points within the area
# 3. All points in the area
# points are like [(x1, y1), (x2, y2), ... ]
def pca(points):
xs, ys = zip(*points)
x = np.array(xs)
y = np.array(ys)
# Subtract mean from each dimension. We now have our 2xm matrix.
x = x - np.mean(x)
y = y - np.mean(y)
coords = np.vstack([x, y])
# Covariance matrix and its eigenvectors and eigenvalues
cov = np.cov(coords)
vals, evecs = np.linalg.eig(cov)
# Sort eigenvalues in decreasing order (we only have 2 values)
sort_indices = np.argsort(vals)[::-1]
evec1, evec2 = evecs[:, sort_indices] # Eigenvector with largest eigenvalue
eval1, eval2 = vals[sort_indices[0]], vals[sort_indices[1]]
print("PCA:", evec1, evec2, eval1, eval2)
return evec1, evec2, eval1, eval2
我尝试将不同的点集传递给 pca:
- 仅指向该区域的周边
- 区域内点的随机样本
- 区域内的所有点
不过没关系,每次点选,我的算法都可以产生以上2种模式。虽然看起来右边的那个(不正确的那个)产生的频率更高。
【问题讨论】:
-
如果您准确地复制了代码,那么您分析的是白点,而不是黑点。您需要反转图像。您可能还想应用阈值。
-
你能添加你的代码吗?此外,“给定形状相似的区域,PCA 算法返回完全不同的特征向量” - 您是否有可能跳过排序步骤,因为在右侧图像上看起来您使用的是短轴特征向量而不是长轴特征向量。
-
区域坐标全部正确。我的问题中的图像用线条填充以填充斑点,通过遵循 PCA 给出的轴,我还随机调整了斜率以更清楚地看到。我也没有忘记按特征值对特征向量进行排序。我会尽快发布代码和返回值。
标签: algorithm numpy pca data-analysis