首页 > 解决方案 > 从 PNG 中提取数字信息

问题描述

如果这个问题不适合本网站,我深表歉意。

我有几百张图表;每张图都是一个PNG。它们都如下所示:

在此处输入图像描述

x 轴标有所有可能的类别(等级)。y 轴显示获得特定成绩的孩子的百分比。所有图表都遵循这种格式;没有偏差。

使用 Python,从这样的图像中提取数据的最有效方法是什么?我的目标是提取每个年级类别的百分比值,以便我可以做一些进一步的分析 - 我正在尝试查看哪些课程的 A+/A 成绩百分比最高,以便我可以为下学期做计划。

当然,我真正需要的是条形的相对高度,我可以根据这些信息计算比率。这可以通过使用 OpenCV 之类的 Otsu 阈值来实现;有没有更简单的方法来做我想做的事?我敢肯定这已经做过了;如果有人能指出我(最好是 Python)回购或教程,那就太好了。

标签: pythonimage-processing

解决方案


假设所有图表都具有相同的尺寸、列数等,一种方法是获取每列的高度(以像素为单位),然后进行比较。要获取每列的高度,您可以使用库PIL

首先,根据您上传的图像,每列的底部位于像素 y = 523(图像顶部为 y = 0),第一列的中心位于 x = 136。此外,中心每列在最后一列之后是 45 或 46 像素(交替),并且有 15 列。

基于此,您可以使用此脚本来获取图表中每一列的高度:

from PIL import Image
def col_heights(filename):
    img = Image.open(filename)
    cols = []
    sy = 523  # The y level of the bottom of each column
    x = 136  # The x position of the first column
    add_45_or_46 = False  # False to increment by 45, True for 46
    
    num_cols = 15
    for _ in range(num_cols):
        y = sy
        while img.getpixel((x, y)) != (255, 255, 255, 255):
            y -= 1  # Work upwards
        cols.append(sy - y)
        
        x += 46 if add_45_or_46 else 45
        add_45_or_46 = not add_45_or_46
    
    img.close()
    return cols

那么这有什么作用呢?它首先打开图像,然后设置x(第一列 x 位置)、sy(每列的起始 y 水平)的起始值以及是否添加 45 或 46 以到达下一列。然后,对于每一列,它向上工作,直到找到与列底部的像素不匹配的像素(即不是白色),然后将该列的高度添加到列高列表中。

例如,对于您上传的图表,每列的高度为[220, 430, 242, 143, 54, 32, 0, 10, 0, 10, 0, 0, 43, 176, 21].


推荐阅读