赞
踩
应小姐姐所邀
原因是小姐姐拿到供应商的一张图表,但是没有具体的数值,更糟糕的是她还想对图中的几条曲线求和。。。。
在这个提供了一种使用matlab提取曲线的方式;
1、首先根据图表颜色筛选出曲线的像素点坐标(彩色图像)
2、根据图像的像素和实际标注额尺寸进行坐标变换;
3、将较宽的曲线求均值(将曲线做细)
4、补充曲线被打断或者遮挡的部分(差值);
5、最后进行更复杂的运算,这里只做了求和。
图是这样的
提取到的图是这样的
最终效果是这样的(因为后面的曲线完全重合了,可以直接幅值就行,这里没有处理,后面有机会再加吧。。。)
程序如下
clc;clear; close all; % 读图 pic = imread("pic.jpg"); [m,n,p] = size(pic); figure,imshow(pic); imgr = pic(:,:,1); imgg = pic(:,:,2); imgb = pic(:,:,3); % 图表的起始和终止像素 xsta = 22; ysta = 65; xsto = 368; ysto = 768; % 图表的像素比例 rangex = 1/(xsto-xsta); rangey = 700/(ysto-ysta); indexr = []; indexg = []; indexb = []; cntr = 0; cntg = 0; cntb = 0; % 按照颜色提取像素点 for num1 = xsta:xsto for num2 = ysta:ysto if imgr(num1,num2)<100 && imgg(num1,num2)<100 mid = [num1,num2]; indexb = [indexb;mid]; cntb = cntb+1; end if imgb(num1,num2)<100 && imgg(num1,num2)<100 mid = [num1,num2]; indexr = [indexr;mid]; cntr = cntr+1; end if imgb(num1,num2)<100 && imgr(num1,num2)<100 mid = [num1,num2]; indexg = [indexg;mid]; cntr = cntr+1; end end end % 变换坐标,使横纵坐标对称 value.bx = (indexb(:,2)-ysta)*rangey+300; value.by = abs((indexb(:,1)-xsta)*rangex-1); value.rx = (indexr(:,2)-ysta)*rangey+300; value.ry = abs((indexr(:,1)-xsta)*rangex-1); value.gx = (indexg(:,2)-ysta)*rangey+300; value.gy = abs((indexg(:,1)-xsta)*rangex-1); figure,plot(value.bx,value.by,'b.'); hold on,plot(value.rx,value.ry,'r.'); plot(value.gx,value.gy,'g.'); % 由于线条较粗,单个数值占用了好几个像素,所以需要将曲线细化(这里取的像素点均值) sta = 350; sto = 800; ave.bx = []; ave.by = []; ave.gx = []; ave.gy = []; ave.rx = []; ave.ry = []; for cir = sta:sto posr = find(round(value.rx) == cir); if isempty(posr) continue; else ave.rx = [ave.rx cir]; ave.ry = [ave.ry mean(value.ry(posr))]; end posg = find(round(value.gx) == cir); if isempty(posg) continue; else ave.gx = [ave.gx cir]; ave.gy = [ave.gy mean(value.gy(posg))]; end posb = find(round(value.bx) == cir); if isempty(posb) continue; else ave.bx = [ave.bx cir]; ave.by = [ave.by mean(value.by(posb))]; end end strangePoint = find(ave.gx == 383); ave.gy(strangePoint) = (ave.gy(strangePoint-1)+ave.gy(strangePoint+1))/2; figure,plot(ave.bx,ave.by,'b',ave.gx,ave.gy,'g',ave.rx,ave.ry,'r'); % 蓝色和绿色曲线有被红色曲线切断的地方,这里做了差值补齐缺失点,便于后续对应不同横坐标对齐,然后求和 wl = sta:1:sto; rline = interp1(ave.rx,ave.ry,wl); gline = interp1(ave.gx,ave.gy,wl); bline = interp1(ave.bx,ave.by,wl); figure,subplot(2,1,1),plot(wl,rline,'r',wl,gline,'g',wl,bline,'b'); title('提取的三条曲线'); subplot(2,1,2),plot(wl,rline+gline+bline,'k'); title('求和后的曲线');
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。