如何根据离散的数据点获取线性的线段?

[
    [
        {
            "id": 444810098964868900,
            "distance": 0.20106235146522522,
            "score": 0.20106235146522522,
            "video_uuid": "夏洛特烦恼原片-5min",
            "pts": 0,
            "timeline": 0
        }
    ],
    [
        {
            "id": 444810098964868900,
            "distance": 0.19771885871887207,
            "score": 0.19771885871887207,
            "video_uuid": "夏洛特烦恼原片-5min",
            "pts": 0,
            "timeline": 0
        }
    ],
    [
        {
            "id": 444810098964868900,
            "distance": 0.17275215685367584,
            "score": 0.17275215685367584,
            "video_uuid": "夏洛特烦恼原片-5min",
            "pts": 0,
            "timeline": 0
        }
    ],
    [
        {
            "id": 444810098964868900,
            "distance": 0.20370642840862274,
            "score": 0.20370642840862274,
            "video_uuid": "夏洛特烦恼原片-5min",
            "pts": 0,
            "timeline": 0
        }
    ]
]

使用 python 把上面的 json 转成点图,把 json 是 list[list[dict]] 的,把 dict 里面的 pts 作为纵坐标,把 list 的 index 作为横坐标

然后我写了下面的代码

from mark import BASE_DIR
import json
# with

import json
import matplotlib.pyplot as plt

with open(BASE_DIR/'dev/graph/raw.json', 'r', encoding='utf-8') as file:
    data = json.loads(file.read())


# 提取pts值
pts_values = [entry[0]["pts"] if entry else 0 for entry in data]

# 创建横坐标(使用列表的索引)
x_values = list(range(len(data)))

# 创建点图
plt.scatter(x_values, pts_values, marker='o', color='b', label='Pts Values')

# 添加标题和标签
plt.title('Pts Values vs. Index')
plt.xlabel('Index')
plt.ylabel('Pts Value')

# 显示图表
plt.legend()
plt.grid(True)
plt.show()

渲染出来的图如下

图片.png

对于上面的图,我希望可以输出 [0,900]->[0,900][900,1550]->[1200,1550]

图片.png

对于上面的图,我希望可以输出 [0,900]->[0,900][1200,1550]->[1200,1550]

图片.png

对于上面的图,我希望可以输出 [0,600]->[0,600][600,1200]->[900,1500]

也就是统计图像中有一共个多少个线段,并且输出这些线段的起点坐标到终点坐标

难点在于,这些线段不一定是强连续的,可能中间会断开一个点,这些不规则的点可能会变成干扰因素

我想的是怎么统计出所有线段,并且可以排除因为一些点没有在线段上导致的干扰

忽略纵坐标为 0 的点,不纳入统计
阅读 1.4k
3 个回答

用js实现了下,思路应该是相通的

// 在一条直线上的点都满足 y = ax + b
var array = [0, 1, 2, 3, 4, 5, 6, 0, 10, 11, 12, 13, 14, 15]
var slopes = []

async function main() {
  for (let i = 0; i < array.length; i++) {
    for (let j = i + 1; j < array.length; j++) {
      if (i != j) {
        var a = (array[j] - array[i]) / (j - i)
        var b = array[i] - a * i
        var cur = slopes.find(item => item.a == a && item.b == b)
        if (cur) {
          cur.flag++
        } else {
          slopes.push({ a, b, flag: 1, points: [] })
        }
      }
    }
  }
  slopes = slopes.sort((cur, pre) => pre.flag - cur.flag)
  slopes = slopes.filter(item => item.flag > 5)
  for (const line of slopes) {
    var a = line.a
    var b = line.b
    for (let i = 0; i < array.length; i++) {
      if (array[i] == a * i + b) {
        line.points.push({ x: i, y: array[i] })
      }
    }
    line.length = line.points.length
  }

  console.log(JSON.stringify(slopes, null, 2))
}

main()

绘图之前进行数据预处理,排除掉干扰数据,这样绘图会不会好点

了解了一下,有以下现成的算法可以使用:

传统的:

  • 霍夫变换
  • Canny 边缘检测算法
  • EDlines直线检测算法
  • 直线段检测算法LSD

基于深度学习的:

  • LCNN
  • TP-LSD
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题