如何使用Python或R测量条形图柱子高度以提取对应数据
完全可以实现,核心逻辑是先建立Y轴像素坐标与实际数值的映射关系,再识别每个条形的顶端像素坐标,代入映射即可得到对应数值,精度远高于手动统计。以下是两种语言的可落地实现方案:
Python实现方案
可以用OpenCV做图像识别,步骤清晰可定制:
- 先预处理图像:转灰度、二值化,分离条形和坐标轴区域,过滤背景、网格线等干扰元素
- 标定Y轴映射:手动选取两个Y轴已知刻度对应的像素坐标(注意图像像素坐标从上到下递增,和常规坐标系方向相反),生成换算公式
- 识别条形轮廓:通过颜色阈值或轮廓检测定位所有条形,取每个条形顶端的像素坐标代入换算公式得到数值
核心代码示例:
import cv2 import numpy as np # 读取本地条形图文件 img = cv2.imread("bar_chart.jpg") # 替换为你的图中Y轴实际参数:刻度值对应像素坐标 y_pixel_min = 800 # Y轴最小值(比如0)对应的像素y坐标(靠近图像底部) y_pixel_max = 100 # Y轴最大值(比如100)对应的像素y坐标(靠近图像顶部) value_min = 0 value_max = 100 # 替换为你的条形对应的HSV颜色范围,这里以蓝色条形为例 hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) lower_bar = np.array([90,50,50]) upper_bar = np.array([130,255,255]) mask = cv2.inRange(hsv, lower_bar, upper_bar) # 查找条形轮廓 contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 计算每个条形的数值 bar_values = [] for cnt in contours: x,y,w,h = cv2.boundingRect(cnt) # 过滤尺寸过小的噪点轮廓 if w>10 and h>10: top_pixel = y bar_value = value_min + (value_max - value_min) * (y_pixel_min - top_pixel) / (y_pixel_min - y_pixel_max) bar_values.append(round(bar_value,2)) print(bar_values)
R实现方案
用magick和EBImage包即可完成相同逻辑的处理:
- 先加载图像做二值化预处理,提取条形区域
- 标定Y轴的像素-数值映射关系
- 识别条形轮廓,提取顶端坐标计算数值
核心代码示例:
library(magick) library(EBImage) # 读取本地条形图文件 img <- image_read("bar_chart.jpg") # 替换为你的图中Y轴实际参数 y_pixel_min <- 800 y_pixel_max <- 100 value_min <- 0 value_max <- 100 # 二值化处理提取条形 img_binary <- img %>% image_channel("gray") %>% image_threshold("black", threshold = "50%") # 识别轮廓并计算参数 img_mat <- image_data(img_binary, "matrix") seg_res <- segmentLabels(img_mat) contour_params <- computeFeatures.shape(seg_res) # 计算每个条形的数值 bar_values <- apply(contour_params, 1, function(x) { top_pixel <- x['m.cy'] - x['s.radius'] value <- value_min + (value_max - value_min) * (y_pixel_min - top_pixel) / (y_pixel_min - y_pixel_max) return(round(value,2)) }) print(bar_values)
如果是多颜色分组的条形图,只需要调整颜色阈值分别提取不同颜色的条形即可;如果需要完全自动化处理,也可以加OCR步骤自动识别Y轴刻度值,不需要手动输入刻度参数。
内容的提问来源于stack exchange,提问作者Jeremy
相关产品推荐
相关产品推荐

