【问题标题】:Is there any way to only extract "corner" vertex points from a PNG?有没有办法只从 PNG 中提取“角”顶点?
【发布时间】:2020-09-05 15:57:57
【问题描述】:

我目前正在尝试从特定 PNG 文件中提取数据点的想法。作为参考,PNG 文件如下所示: Picture of PNG

我用来提取数据的当前代码如下所示,我正在使用 Python 图像库来识别图像的点:

def imageProcess(filename) :
    #Declaring data object
    data = []
    #Loading image for modification
    with Image.open(filename) as im:
        px = im.load()
        #Grabbing values
        width,height = im.size
        print(width , height)

        #For loop
        for x in range(width) :
            for y in range(height) :
                #Removes white space from the image
                if px[x,y] != (255,255,255,0) :
                    data.append({"x" : x*5, "y" : y*5,"color" :  px [ x , y ]})

        print(type(data))

        return data

虽然这段代码运行良好,但我正在尝试丢弃代表 PNG 文件中的一行的数据点,我只希望角落是特定的。为了更好地了解我想要什么:

而不是:

{'x': 518, 'y': 741, 'color': (226, 226, 226, 17)}
# All of the data below is a waste, I don't need it
{'x': 518, 'y': 742, 'color': (226, 226, 226, 17)}
{'x': 518, 'y': 743, 'color': (226, 226, 226, 17)}
{'x': 518, 'y': 744, 'color': (226, 226, 226, 17)}
{'x': 518, 'y': 745, 'color': (226, 226, 226, 17)}
{'x': 518, 'y': 746, 'color': (226, 226, 226, 17)}
{'x': 518, 'y': 747, 'color': (226, 226, 226, 17)}
{'x': 518, 'y': 748, 'color': (226, 226, 226, 17)}
{'x': 518, 'y': 749, 'color': (226, 226, 226, 17)}
{'x': 518, 'y': 750, 'color': (226, 226, 226, 17)}
{'x': 518, 'y': 751, 'color': (226, 226, 226, 17)}
{'x': 518, 'y': 752, 'color': (226, 226, 226, 17)}
{'x': 518, 'y': 753, 'color': (226, 226, 226, 17)}
{'x': 518, 'y': 754, 'color': (226, 226, 226, 17)}
{'x': 518, 'y': 755, 'color': (226, 226, 226, 17)}
{'x': 518, 'y': 756, 'color': (226, 226, 226, 17)}
{'x': 518, 'y': 757, 'color': (226, 226, 226, 17)}
{'x': 518, 'y': 758, 'color': (226, 226, 226, 17)}
{'x': 518, 'y': 759, 'color': (226, 226, 226, 17)}
{'x': 518, 'y': 760, 'color': (226, 226, 226, 17)}
{'x': 518, 'y': 761, 'color': (226, 226, 226, 17)}
{'x': 518, 'y': 762, 'color': (226, 226, 226, 17)}
{'x': 518, 'y': 763, 'color': (226, 226, 226, 17)}
{'x': 518, 'y': 764, 'color': (226, 226, 226, 17)}
{'x': 518, 'y': 765, 'color': (226, 226, 226, 17)}
{'x': 518, 'y': 766, 'color': (226, 226, 226, 17)}
# The point below represents the corner
{'x': 518, 'y': 767, 'color': (244, 244, 244, 2)} 

我只想要第一个和最后一个值,因为它代表角:

#This is what I want to achieve
{'x': 518, 'y': 741, 'color': (226, 226, 226, 17)}
{'x': 518, 'y': 767, 'color': (244, 244, 244, 2)} 

如果需要解决这个问题,我欢迎使用除 PIL 之外的不同 python 库。非常感谢。

编辑:这是一个(抱歉低分辨率)picture 解释我需要获取哪些数据点以及需要丢弃所有数据点。我已经用红点标出了我需要获得的分数。谢谢。

【问题讨论】:

  • 也许您可以添加第二张标记图像,用红色或圆圈标识您要查找的点?
  • @MarkSetchell 我正在尝试识别角落,例如i.stack.imgur.com/mfpdz.png。我为低分辨率道歉。我只需要此 PNG 图像中一行的起点和终点。谢谢。
  • 您的实际图像有那么差(低分辨率)吗?您能否看到您正在寻找的许多角点实际上并不存在 - 在这些点图像中存在间隙。

标签: python image-processing python-imaging-library png


【解决方案1】:

抱歉,我没有时间像往常那样写出正确的 Python 答案,但不向您展示如何做到这一点似乎很残酷。我使用了 “Hit and Miss Morphology”,您可以在 OpenCVscikt-imagewand 中找到它。我在终端中使用 ImageMagick 来生成:

这是命令,它在 wand 中非常相似,因为这是一个 Python ImageMagick 绑定:

magick plan.png -alpha off -threshold 99%  \
    \( +clone -define morphology:showkernel=1 -morphology HMT "3x3>: nan,0,0 0,nan,nan 0,nan,nan " -morphology Dilate Ring -background red -alpha shape  \) -composite result.png

其中的关键部分是 “Hit and Miss” 内核,它在这里:

"3x3>: nan,0,0 0,nan,nan 0,nan,nan "

这意味着我正在寻找这个 3x3 形状:

ANY    BLACK  BLACK
BLACK  ANY    ANY
BLACK  ANY    ANY

希望您能看到在 3x3 形状的左上角交汇的水平和垂直黑线,其中实际角不一定是黑色,因为您的图表中缺少这些位!如果您想在 3x3 网格中的某个位置坚持使用白色像素,您可以使用 1。如果你想保持平衡,你会使用更大的网格。或者确定您正在处理较长线路的一角。

> 表示如果将其旋转 90、180 和 270 度,我想在 4 个位置中的任何一个位置找到那个角,所以我正在寻找左上角、右上角、底部 -右下角和左下角。

如果我打印显示内核的调试输出角,您可以看到很多:

Kernel #0 "User Defined" of size 3x3+1+1 with values from 0 to 0
Forming a output range from 0 to 0 (Zero-Summing)
 0:       nan         0         0
 1:         0       nan       nan
 2:         0       nan       nan
Kernel #1 "User Defined@90" of size 3x3+1+1 with values from 0 to 0
Forming a output range from 0 to 0 (Zero-Summing)
 0:         0         0       nan
 1:       nan       nan         0
 2:       nan       nan         0
Kernel #2 "User Defined@180" of size 3x3+1+1 with values from 0 to 0
Forming a output range from 0 to 0 (Zero-Summing)
 0:       nan       nan         0
 1:       nan       nan         0
 2:         0         0       nan
Kernel #3 "User Defined@270" of size 3x3+1+1 with values from 0 to 0
Forming a output range from 0 to 0 (Zero-Summing)
 0:         0       nan       nan
 1:         0       nan       nan
 2:       nan         0         0

请注意,-morphology Dilate Ring -background red -alpha shape 仅用于在点周围绘制红色圆圈,以便您可以看到它们。你可以省略这个,你只会得到一个空白画布上的点。

如果您对这种方法感兴趣,Anthony Thyssen here 有一个很好的描述,但如果您不熟悉形态学,请从页面顶部开始。

【讨论】:

  • 好答案!您还可以使用与 L 形内核及其旋转的互相关(卷积)来查找角度。
  • @AlexAlex 确实。在此答案中调整过滤器以查找 P[1]、P[2]、P[3] 和 P[6] 为零也非常简单......stackoverflow.com/a/55558489/2836621
【解决方案2】:

看起来您想访问返回的data 列表中的第一个和最后一个元素。你可以这样做:

[data[0]] + [data[-1]]

这是如何工作的?

data[0]

检索数据列表中的第一个元素,并且

data[-1]

检索数据列表中的最后一个元素。 将两者包装在 [] 中会创建两个单元素列表,然后我们使用 + 运算符将它们连接在一起!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-29
    • 2020-10-25
    • 1970-01-01
    • 2019-06-07
    • 2015-04-13
    • 2011-07-22
    • 1970-01-01
    相关资源
    最近更新 更多