【问题标题】:Nx3 column data to 2d matrix for image processingNx3 列数据到 2d 矩阵用于图像处理
【发布时间】:2012-05-01 19:46:59
【问题描述】:

我试图在我从文本文件中读取的格式 ('x','y','value') 的 Nx3 数据中找到局部最大值和计数; 'x' 和 'y' 形成一个等间距的网格,'x','y' 的每个组合都有一个值,看起来像这样:

  3.0, -0.4, 56.94369888305664        
  3.0, -0.3, 56.97200012207031        
  3.0, -0.2, 56.77149963378906        
  3.0, -0.1, 56.41230010986328        
  3.0,  0,   55.8302001953125       
  3.0,  0.1, 55.81560134887695        
  3.0,  0.2, 55.600399017333984        
  3.0,  0.3, 55.51969909667969        
  3.0,  0.4, 55.18550109863281         
  3.2, -0.4, 56.26380157470703 
  3.2, -0.3, 56.228599548339844
  ...

问题是我尝试使用的图像代码(link)要求数据采用不同的二维矩阵格式进行图像处理。这是代码的相关部分:

# Construct some test data
x, y = np.ogrid[-np.pi:np.pi:100j, -np.pi:np.pi:100j]
r = np.sin(np.exp((np.sin(x)**3 + np.cos(y)**2)))

# Find contours at a constant value of 0.8
contours = measure.find_contours(r, 0.8)

有人可以帮助我将数据转换为所需的“网格”格式吗?

编辑:我终于选择了熊猫,但在一般情况下我发现选择的答案更好。这就是我所做的:

from pandas import read_csv
data=read_csv(filename, names=['x','y','values']).pivot(index='x', columns='y',
              values='values')

在此之后data.values 以我想要的二维“图像形式”保持表格。

y   -0.4        -0.3        -0.2        -0.1
x               
3.0  86.9423     87.6398     87.5256     89.5779
3.2  76.9414     77.7743     78.8633     76.8955
3.4  71.4146     72.8257     71.7210     71.5232

【问题讨论】:

  • 我不太明白你的原始数据是什么。它看起来像一个元组列表,但又一次缺少元组之间的逗号。这就是你的数据在文本文件中的样子吗?
  • 这是numpy.loadtxt的输出,文本文件中的数据是这样的:3 -0.4 -0.0494273 56.9437 1.88357; 3 -0.3 -0.0258483 56.972 2.03781; 3 -0.2 -0.00939226 56.7715 1.90159; 3 -0.1 0.00208286 56.4123 1.56543;这 ';'代表行尾,我只选择第 1、2、4 列。
  • 我明白了,我似乎完全误解了这个问题,对不起。

标签: python image-processing numpy scikits


【解决方案1】:

最好的解决方案实际上取决于您不提供的细节。顺便说一句,你应该真的给出你的代码,或者至少给出 np.loadtxt 指令。 在下文中,“数据”是使用从文件加载的数组:

data = np.loadtxt('file.txt', [('x',float), ('y',float), ('value',float)])

1) 直接重塑:

按照@tom10 所说的
如果您知道您的 (x,y,value) 数据是按特定顺序存储的:

[(x0,y0,v00), (x0,y1,v01), .... , (x1,y0,v10),(x1,y1,v11), ... ,(xN,yM,vNM)]

并且所有 (x,y) 对的值都已给出。那么最好的办法是从您的值列表中创建一个 1D numpy 数组并对其进行整形:

x = np.unique(data['x'])
y = np.unique(data['y'])
r = data['value'].reshape((x.size,y.size))

2) 一般情况:

请参阅Populate arrays in python (numpy)? 了解类似问题和使用字典的其他解决方案

如果你不能保证除了 (x,y,value) 元组之外的任何东西:

# indexing: list of x and y coordinates, and functions that map them to index
x  = np.unique(data['x']).tolist()
y  = np.unique(data['y']).tolist()
ix = np.vectorize(lambda i: x.index(i), otypes='i')
iy = np.vectorize(lambda j: y.index(j), otypes='i')

# create output array
r  = np.zeros((x.size,y.size), float)   # default value is 0
r[ix(data['x']), iy(data['y'])] = data['value']

注意:在上面给出的参考资料中,给出了另一种使用字典的方法。我认为这更具可读性,但我没有测试它们的相对速度。

3) 中间案例?

您可能有一个中间情况,在以特定顺序给出的常规网格坐标和完全没有约束之间。一般情况下可能非常慢,您应该设计您的算法以利用您的数据遵循的任何规则。

一个例子是,如果您知道 x-y 索引遵循特定规则,但不一定按顺序给出。例如,如果您知道 x 和 y 是等距的“网格”坐标,格式如下:

coordinate = min_coordinate + i*step

然后找到 min_coordinatestep(对于 x 和 y),并通过求解这个方程找到 i。这样,您就避免了昂贵的索引映射 np.vectorized(... list.index(...)):

x  = np.unique(data['x'])
y  = np.unique(data['y'])
ix = (data['x']-x.min())/(x[1]-x[0])
iy = (data['y']-y.min())/(y[1]-y[0])

# create output array
r  = np.ones((x.size,y.size), float)*np.nan   # default value is NaN
r[ix.astype(int), iy.astype(int)] = data['value']

【讨论】:

  • 很好的答案,谢谢!对了,你有没有发现 numpy.loadtxt 比较慢?
  • 谢谢。我很少使用 loadtxt,也从不使用大文件,所以我不知道它的效率。我本来希望它和加载文本数据一样快。
【解决方案2】:

对于您正在使用的程序,您只需要将数据是z 值的矩形数组(在他们给出的示例中,他们只使用 x 和 y 来构造 z,但以后不再使用它们)。看起来你有 9 x N 的数组(其中 N 是你没有显示的东西)。一种简单的方法是将数据作为 z 值的平面集合读取,跳过 x,y 值reshape 以设置您想要的形状。 (我真的无法为此编写代码,因为您没有提供足够的信息,但这应该不难。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-04
    相关资源
    最近更新 更多