从曲线图片恢复数据

11 篇文章 0 订阅
6 篇文章 1 订阅

很多应用是将传感器采集的数据绘制成曲线,如随时间变化的电流、电压或者功率。
目前有个应用反过来,有数百张存放在pdf文档上的曲线截图,这些历史图片缺失了原始数据,需要根据分辨率很低的图片将数据恢复过来。
这类应用通常是AI大数据分析的前端,恢复效果直接影响数据的质量。

原始图片:
功率图

以上图为例,是一幅功率图,由2条不同颜色的曲线组成,红色表示实际值和青色表示平均值。
横坐标是时间轴,0-7.25秒,纵坐标表示功率,最大功率1800瓦。

恢复数据的难点:
1、两种颜色的曲线有叠加的地方,分离不容易;
2、背景很多干扰,需要去除这些噪音,比如文字,格子线,选择十字线。

实现方法
使用OpenCV3,采样C/C++编程。
一、为了方便批处理,手工采集图片时文件名包含更多的信息:
如:Wrc_7.52_1800_场地信息_序号_日期时间.png
最重要的横坐标、纵坐标的信息包含在里面。
二、分离不同颜色曲线
因为图片是多条不同颜色的曲线叠加,需要将其逐一分离。
基本原理是将图像由BGR转为HSV空间,再根据不同颜色有不同的H值,将这个范围的H值保留。

void colorFilter(char color, Mat& inputImage, Mat& outputImage)
{
	int low0 = -1;
	int low1 = -1;
	int high0 = -1;
	int high1 = -1;

	if (color == 'r') {  // 红色
		low0 = 0;
		low1 = 20;
		high0 = 120;
		high1 = 180;
	}
	else if (color == 'g') {  // 绿色
		high0 = 35;
		high1 = 77;
	}
	else if (color == 'b') {  // 蓝色
		high0 = 100;
		high1 = 124;
	}
	else if (color == 'y') {  // 黄色
		high0 = 26;
		high1 = 34;
	}
	else if (color == 'c') {  // 青色
		high0 = 78;
		high1 = 99;
	}
	else {
		printf("color err: %c\n", color);
		outputImage = inputImage;
		return;
	}

	Mat hsv;
	cvtColor(inputImage, hsv, CV_BGR2HSV);
	int width = hsv.cols;
	int height = hsv.rows;
	for (int i = 0; i < height; i++) {
		for (int j = 0; j < width; j++) {
			int H = hsv.at<Vec3b>(i, j)[0];
			int S = hsv.at<Vec3b>(i, j)[1];
			if (!((low0>=0 && H >= low0 && H <= low1) || (H >= high0 && H <= high1))) {
				hsv.at<Vec3b>(i, j)[0] = 0;
				hsv.at<Vec3b>(i, j)[1] = 0;
				hsv.at<Vec3b>(i, j)[2] = 0;
			}

		}
	}
	cvtColor(hsv, outputImage, CV_HSV2BGR);
}

效果如下:
在这里插入图片描述
在这里插入图片描述

三、定位坐标
二值化后进行处理。
从上到下扫描到第一根横线,作为y轴的顶点线
从下到上扫描到第一根横线,作为x轴,也就是y轴的起点线。
从左到右扫描到第一根竖线,作为y轴,也就是x轴的0点。
图片的最右,作为x轴的终点。
定位好了后,有了这些值,就可以算出比率,即值和像素之比了。

四、值的转换
根据采样率,计算x轴的采样间隔。
y轴,根据像素距离和比率,就可以还原出实际的值。

五、异常的处理
如果在某些位置有多种颜色粘连重叠,无法准确分离,则可以取原始图片的二值化后的值。
有些图片的十字虚线(原始绘图软件的选择线),线型比较粗,往往二值化后消除不掉,会对识别产生干扰,需要判断当前点是不是处于虚线上。
有些位置,二值化后曲线出现断裂,即读取不到值,可以取前一个值。

上述图片经处理后获取的数据:
r:
0,0,0,0,0,79,116,417,491,1333,1179,841,724,589,565,522,509,497,491,491,485,473,466,442,436,423,423,423,423,430,442,466,466,473,460,454,442,430,423,423,423,430,436,442,442,442,454,466,460,448,454,460,460,460,466,473,473,479,485,485,491,491,491,497,497,503,503,503,509,509,509,516,516,516,522,522,522,522,528,534,534,540,540,546,546,546,552,552,552,559,559,565,571,571,571,571,571,577,577,577,583,583,583,589,595,595,602,602,602,608,608,614,614,614,614,614,602,589,565,583,595,602,602,608,595,571,559,540,546,577,620,663,681,694,724,761,786,804,798,774,755,737,712,700,663,638,614,565,540,534,522,522,522,350,313,264,227,221,190,172,135,116,110,110,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,86,73,55,24,18,0,0,0,0
c:
0,0,0,0,43,30,67,0,958,872,1455,1449,749,700,657,583,552,540,528,522,516,509,503,485,473,448,442,436,442,460,473,497,503,509,509,509,491,479,466,454,454,454,454,454,454,454,436,454,448,466,479,479,473,466,473,479,460,466,466,473,479,479,485,485,485,491,485,485,491,491,497,503,503,503,503,503,503,503,503,509,509,516,516,516,516,516,516,522,522,522,522,528,522,522,528,528,522,522,522,522,522,522,522,522,522,528,528,528,528,528,528,528,528,528,534,534,534,534,534,534,540,534,528,522,516,503,503,509,509,503,503,534,571,583,583,583,571,540,540,540,540,534,528,522,516,491,491,485,479,479,479,473,430,282,270,239,202,196,147,141,116,104,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,86,92,36,30,12,0,0,0,0,0

为了方便验证,如果可以将其保存为csv文件(逗号分隔的文本文件),然后用Excel打开,选择插入/曲线,效果如下:
在这里插入图片描述
从Excel绘制出的图片来看,效果还是不错的,和原图几乎一模一样。
软件最后做成了可以扫描目录,逐个文件进行批处理操作。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值