计算XY散射轮廓的质心

时间:2017-10-01 17:27:59

标签: python python-2.7 centroid

我正在开发一个项目来使用python计算州/国家的质心。

到目前为止我做了什么:

  1. 获取状态的轮廓并通过ImageJ运行它以创建边框的x,y坐标的csv。这给了我一个包含以下数据的.csv文件:

    556243

    557243

    557250

    556250

    556252

    555252

    555253

    554253

    等等,

  2. 大约2500个数据点。

    1. 将此列表导入Python脚本。

    2. 计算x和y坐标数组的平均值。这一点是质心。 (Idea similar to this)

    3. 使用matplotlib绘制点和质心。

    4. 这是我的代码:

      #####################################################
      #                     Imports                       #
      #####################################################
      import csv
      import matplotlib.pyplot as plt
      import numpy as np
      import pylab
      
      
      #####################################################
      #                       Setup                       #
      #####################################################
      
      #Set empty list for coordinates
      x,y =[],[]
      
      #Importing csv data 
      with open("russiadata.csv", "r") as russiadataFile:
          russiadataReader = csv.reader(russiadataFile)
      
          #Create list of points
          russiadatalist = []
      
          #Import data
          for row in russiadataReader:
              #While the rows have data, AKA length not equal to zero. 
              if len(row) != 0: 
                  #Append data to arrays created above
                  x.append(float(row[0]))
                  y.append(float(row[1]))
      
      #Close file as importing is done
      russiadataFile.closejust flipped around the 
      
      
      
      
      #####################################################
      #                  Data Analysis                    #
      #####################################################
      
      #Convert list to array for computations
      x=np.array(x)
      y=np.array(y)
      
      
      #Calculate number of data points
      x_len=len(x)just flipped around the 
      y_len=len(y)
      
      #Set sum of points equal to x_sum and y_sum
      x_sum=np.sum(x)
      y_sum=np.sum(y)
      
      #Calculate centroid of points
      x_centroid=x_sum/x_len
      y_centroid=y_sum/y_len
      
      
      
      #####################################################
      #                     Plotting                      #
      #####################################################
      
      
      #Plot all points in data
      plt.xkcd()
      plt.plot(x,y, "-.")
      
      #Plot centroid and label it
      plt.plot(x_centroid,y_centroid,'^')
      
      
      plt.ymax=max(x)
      #Add axis labels
      plt.xlabel("X")
      plt.ylabel("Y")
      plt.title("russia")
      
      #Show the plot
      plt.show()
      

      我遇到的问题是,州的某些方面比其他方面有更多的点,因此质心被加权到具有更多点的区域。这不是我想要的。我试图找到具有x,y坐标顶点的多边形的质心。

      这就是我的情节:

      https://imgur.com/a/ZdukA

      正如您所看到的,质心的加权更多地朝向具有更多密度的点的部分。 (作为旁注,是的,那就是俄罗斯。我对情节的问题向后倾斜并拉伸/压扁。)

      换句话说,是否有更准确的方法来获得质心?

      提前感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

您可以在维基百科上找到关闭多边形的正确公式:https://en.wikipedia.org/wiki/Centroid#Centroid_of_a_polygon

另一个公式有助于处理加里宁格勒州(exclave)和岛屿(如果你想要非常精确):https://en.wikipedia.org/wiki/Centroid#By_geometric_decomposition

尽管如此,这些问题可能更适合https://math.stackexchange.com

答案 1 :(得分:0)

听起来我不喜欢你的质心是用分散的密度来计算的。

如果您只想使用表面区域,那么我将消除散点当前轮廓中包含的任何点。稍微更精确的方法可能是假装最外面的点有一个框,然后检查所有点的x坐标和y坐标,并消除掉在框内的任何内容。落在当前轮廓内的任何点都不会影响形状,只会影响密度。

我认为最技术和最准确的方法会非常复杂,而且我认为这需要:根据彼此距离最远的距离来获得最外面的点,并且距离所有其他点的距离最远。通过“连接”,我的意思是假装一条线穿过,并在两个点结束。它应该在数学上定义。  然后,对于每个点,计算它是否落在此轮廓的内部或外部,并消除掉落在内部的所有内容(它们已经是形状内部的多余部分)。