【问题标题】:How to get the x, y of each pixel of the graph?如何得到图的每个像素的x,y?
【发布时间】:2021-11-24 10:15:10
【问题描述】:

我有以下图片:

我需要完成 2 个步骤。

1 步。 获取图形每个像素的值 (x, y)。结果:图形的数量等于图形的每个像素包含对象 {'x': x, 'y': y} 的数组的数量。 https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html

第 2 步。 每个图的每个像素数组都需要在 scipy.find_peaks 中运行并获取峰值(每个图的最大点数)。

from PIL import Image
import cv2

img_gray = cv2.imread('photo.jpg', cv2.IMREAD_GRAYSCALE)
img_binary = cv2.threshold(img_gray, 150, 255, cv2.THRESH_BINARY)[1]
cv2.imwrite('save.jpg', img_binary)

image = cv2.imread('save.jpg')
cv2.imwrite('save.jpg', image)


im = Image.open("save.jpg")
im = im.convert('RGB')

col_black = (0, 0, 0)
col_white = (255, 255, 255)

for y in range(im.size[1]):
    for x in range(im.size[0]):
        if sum(im.getpixel((x, y))) < 128:
            im.putpixel((x, y), (0, 0, 0))
        else:
            im.putpixel((x, y), (255, 255, 255))

point_start_array = []
for x in range(im.size[0]):
    for y in range(im.size[1]):
        if im.getpixel((x, y)) == col_black and im.getpixel((x, y + 1)) == col_white:
            if len(point_start_array) > 4:
                break
            else:
                point_start_array.append({'x': x, 'y': y})

print(point_start_array)

输出: [{'x': 19, 'y': 161}, {'x': 19, 'y': 238}, {'x': 19, 'y ': 260}, {'x': 19, 'y': 269}, {'x': 19, 'y': 282}]

是否有可能每个图抛出 1 个数组 x,第二个 y 抛出 scipy.find_peaks 并获得峰值?

【问题讨论】:

  • 所以您的数组每个包含 4 个点并且想要输入 scipy.find_peaks?
  • unclear... 我理解的方式是:输入的是图像,但也许不是这样?
  • @Manaclan,我还没有收到每个图的像素数组。但我需要这样做并在 scipy 中为每个 graph.find_peaks 运行 2 个数组(x,y)以找到峰值(最大点)。有可能实现吗?
  • @Vadim:请让您的问题更加集中:您在这里至少有 2 个非常不同的步骤。从图像中获取数值数据并找到峰值。另外,请提供读取图像和设置所有内容的最少代码。
  • @mozway,是的,输入端有图像。

标签: python scipy python-imaging-library


【解决方案1】:

您可以使用 opencv connectedComponents 来获取图形的点和一些 numpy 技巧来获取 y 数组。

import cv2
import numpy as np
import scipy
from scipy.signal import find_peaks

im = cv2.imread('temp.png')
im = cv2.cvtColor(im,cv2.COLOR_BGRA2GRAY)
binary = cv2.threshold(im, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
binary = ~binary
# Get connected components
ret, labels = cv2.connectedComponents(binary)
graphs = []
for label in range(1,ret):
    mask = np.array(labels, dtype=np.uint8)
    mask[labels == label] = 255
    mask = mask.reshape((mask.shape[0], mask.shape[1], 1))
    X,Y = np.where(np.all(mask == 255,axis=2))
    graphs.append(Y)

for ys in graphs:
  peaks, _ = find_peaks(ys, height=0)

但请注意,图像中的一个图形不是完全连接的,即:缺少一个像素来连接图形。所以不是 5 个,而是 6 个图表。我建议使用腐蚀等图像处理技术来连接图形,但会牺牲一些准确性

import cv2
import numpy as np
import scipy
from scipy.signal import find_peaks

im = cv2.imread('temp.png')
im = cv2.cvtColor(im,cv2.COLOR_BGRA2GRAY)
binary = cv2.threshold(im, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
# Erode the images to connect seperated parts
kernel = np.ones((3, 3), np.uint8)  
binary = cv2.erode(binary, kernel, cv2.BORDER_REFLECT) 
# Get connected components
binary = ~binary
ret, labels = cv2.connectedComponents(binary)
graphs = []
for label in range(1,ret):
    mask = np.array(labels, dtype=np.uint8)
    mask[labels == label] = 255
    cv2.imwrite(f'{label}.jpg',mask)
    mask = mask.reshape((mask.shape[0], mask.shape[1], 1))
    X,Y = np.where(np.all(mask == 255,axis=2))
    graphs.append(Y)
for ys in graphs:
  peaks, _ = find_peaks(ys, height=0)

【讨论】:

  • 谢谢,你好,是否可以使用线性插值以某种方式链接此图(缺少 1 px)?
  • 在我的第二个代码 sn-p 中,我使用 erode 加入图表。我能想到的其他方法是编写自己的使用自定义邻居网格查找连接组件的实现
猜你喜欢
  • 2020-07-02
  • 2018-04-08
  • 2017-06-30
  • 2018-12-31
  • 2011-06-21
  • 1970-01-01
  • 2013-02-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多