函数图像:用python提取点

2024-04-20 10:14:45 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有这样一个图像:

enter image description here

我想得到组成这条线的点(x,y)的列表。在Python中有这样做的方法吗?如果我把图像作为一个矩阵加载,我会得到矩阵中的一些元素,表示有“黑色”。问题是这条线可能有一定的宽度,因此会有许多矩阵元素对应于这条线上的同一点。我怎样才能解决这个问题?有没有一个简单的方法来满足我的需要?你知道吗

提前谢谢。你知道吗


Tags: 方法图像元素列表宽度矩阵黑色我会
2条回答

这实际上是一个复杂的问题。您需要提取图像中所有黑色的点,然后找到一种方法将它们压缩为一组更有限的数据,粗略地跟踪路径。你知道吗

import requests
from PIL import Image
import numpy as np
import io
from sklearn.cluster import mean_shift

# get the image
url = 'https://i.stack.imgur.com/qKAk5.png'
res = requests.get(url)
# set the content as a file pointer object
fp = io.BytesIO(res.content)
# load the image to PIL
img = Image.open(fp)

# convert the image to gray-scale and load it to a numpy array
# need to transpose because the X and Y are swapped in PIL
# need [:,::-1] because pngs are indexed from the upper left
arr = np.array(img.convert('L')).T[:,::-1]
# get indices where there line is the pixel values is dark, ie <100
indices = np.argwhere(arr < 100)

到目前为止,我们有索引,或(x,y)的位置,其中一个暗像素发生。但这些比你需要的多得多。为了减少点数,我们可以使用聚类技术来减少点数。mean_shift聚类技术在这里是合适的。它将一个内核分配给一组点,然后迭代地让附近的点慢慢聚集在一起。主要参数是内核的带宽,也就是拉的宽度。你知道吗

# this shows how many clusters are formed per bandwidth
for x in np.arange(.5,5.6,.25):
    print('{:.2f}: '.format(x), end='')
    print(len(mean_shift(indices, bandwidth=x)[0]))

# returns:
0.50: 1697
0.75: 1697
1.00: 539
1.25: 397
1.50: 364
1.75: 343
2.00: 277
2.25: 247
2.50: 232
2.75: 221
3.00: 194
3.25: 175
3.50: 165
3.75: 160
4.00: 156
4.25: 138
4.50: 139
4.75: 133
5.00: 120
5.25: 111
5.50: 112

所以对于200点的近似值,你可以使用3.0的带宽。你知道吗

points, labels = mean_shift(indices, bandwidth=3.0)

# lets plot the points
import matplotlib.pyplot as plt
plt.scatter(points[:,0], points[:,1])

enter image description here

您可以使用opencv进行以下操作:

import cv2
import numpy as np
import matplotlib.pyplot as plt

image = cv2.imread('squiggly.png', cv2.IMREAD_GRAYSCALE)
ret, image = cv2.threshold(image, 128, 255, cv2.THRESH_BINARY)

scatter = np.where(image==0)
x,y = scatter[1],-scatter[0]

plt.scatter(x,y,color='blue',marker='.',s=0.2)  
plt.show()

enter image description here

相关问题 更多 >