Can I digitized color map into contour values according to it color bar?
조회 수: 46 (최근 30일)
이전 댓글 표시
Dear All ;
I have the in the attched file a color contour map..So, Can I digitized color map into contour values according to it color bar?
In other word I need to to read the map (Image) color levels with aid of color bar and transform into the corresponding contour values (x, y, z)
where x, y are the coordinate of point and z is the contour value at this coordinate
Thanks in advance,
Best regards;
M.Dahab
댓글 수: 0
채택된 답변
DGM
2024년 11월 12일 17:47
편집: DGM
2024년 11월 12일 21:25
No, not accurately. There are a number of problems. You can try anyway.
Filled contour plots are ambiguous. The only parts of a contour plot that are unambigous are the boundaries between flat color regions -- i.e. the contour lines. It's not clear what the Z-level of a given pixel is if it does not lie on a contour line. It's something in between the Z-levels of the neighboring contour lines. The data is reduced to discrete levels, so information is necessarily lost.
The image is a 4:2:0 JPG, so most of the actual color data has been also lost. There isn't really any hope to find the contour lines or even to accurately estimate the original discrete color table.
The plot area is littered with dark bands which are either compression artifacts or they're semitransparent overlaid curves. Either way, they will only pollute the estimated Z data.
To make matters worse, the Z-scale described by the colorbar ticks is nonlinear and incomplete. The spacing between Z ticks varies between 0.2 and 0.9 in no apparent pattern. Extrapolating the ends is going to be purely guesswork, and I'm not confident there was intent behind the nonlinear scale. With only 2 digits worth of precision and all the other sources of error, I suppose we're not losing much.
Since we can't recover the contour lines, I'm just going to treat this as a low-quality pseudocolor height map. The only represented Z-levels are the midpoints between the Z-levels of the original contour lines. In other words, we're sampling between the original contours, not on them, and we're presuming that the Z-scaling is at least piecewise-linear.
% a JPG of an ambiguous chart
inpict = imread('Color map.jpg');
% chart position
Rchart = [34.51 27.51 442.98 288.98]; % [x y w h]
% chart tick positions/values
chtxv = [44+10/60 44+20/60];
chtxp = [164; 443.9];
chtyv = [32+15/60 32+10/60]; % y is flipped
chtyp = [92.96; 249];
% generate XData,YData
xrange = Rchart(1) + [0 Rchart(3)];
xrange = rescalelin(xrange,chtxp,chtxv);
yrange = Rchart(2) + [0 Rchart(4)];
yrange = rescalelin(yrange,chtyp,chtyv);
% colorbar tick values
% I almost suspect that the inconsistent scaling isn't even intended (rounding?).
z = [-1.2 -0.3 0.2 0.4 0.7 0.9 1.1 1.3 1.5 1.8 2.0 2.2 2.4 2.7 2.9 3.1 3.5 3.9 4.1];
% dz = diff(z) % z-spacing varies by a factor of up to 4.5
% find the colorbar sample positions
cby = linspace(28.6,348.8,39);
cbx = repmat(528.5,1,numel(cby));
% find the colorbar tick positions
cbyt = linspace(40.33,345,19);
cbxt = repmat(528.5,1,numel(cbyt));
% show where we're sampling
imshow(inpict); hold on
plot(cbx,cby,'ok')
plot(cbxt,cbyt,'xk')
% try to sample the colorbar in the rough center of each discrete patch
% CT0 is an estimation of the original discrete Z-level colors
nct0 = numel(cby);
CT0 = zeros(nct0,3);
for k = 1:nct0
sampx = round(cbx(k)) + [-1 1]*2;
sampy = round(cby(k)) + [-1 1];
sample = im2double(inpict(sampy,sampx,:));
CT0(k,:) = mean(mean(sample,1),2); % vector dim doesn't work that way in 14b
end
CT0 = flipud(CT0);
% presume that we can accurately map the chart colors to the CT
% this is a false assumption, but let's pretend.
sampz = interp1(flip(cbyt),z,flip(cby),'linear','extrap'); % z-value of cb samples
chartpict = imcrop(inpict,Rchart);
Z = rgb2ind(chartpict,CT0,'nodither');
Z = sampz(Z + 1); % offset by 1 due to class
% try to guess what parts of the chart are valid
% even though chroma data has been completely mutilated
% don't expect this to be clean
[H S V] = rgb2hsv(chartpict);
mask = S > 0.4 & V > 0.5;
mask = bwareafilt(mask,1); % bwareafilt() was introduced in 14b, so that should be okay
mask = imfill(mask,'holes');
% show the estimated Z-data
figure
hi = imagesc(xrange,yrange,Z);
set(hi,'AlphaData',mask); % i think this should work in 14b
set(gca,'ydir','normal')
% use a unique CT, since the old one is trash
% and using it will be misleading, since it's not linear
caxis(sampz([1 end])) % clim() doesn't exist in 14b
CTf = parula(nct0); % parula() was introduced in 14b, so that should be okay
colormap(CTf)
colorbar
function outpict = rescalelin(inpict,inrg,outrg)
% this is a simplified version of MIMT imrescale()
% without all the conveniences that make it unique
inpict = double(inpict);
inrg = double(inrg);
outrg = double(outrg);
outpict = (outrg(2)-outrg(1))*(inpict-inrg(1))/(inrg(2)-inrg(1))+outrg(1);
end
Note that we're not reusing the original color table, since it won't line up like it used to when it was mapped nonlinearly.
There are probably other issues, but that's a start.
댓글 수: 2
DGM
2024년 11월 12일 21:00
편집: DGM
2024년 11월 12일 21:26
The function is included above. If you're running R2014b, you'll have to save the function by itself in a separate file, since scripts can't have local functions in R2014b.
EDIT: I just saved a copy and attached it to this comment. It's the same as above, but this is more convenient.
There are going to be some other changes due to the version. I updated the example above to accomodate the older version.
추가 답변 (0개)
참고 항목
카테고리
Help Center 및 File Exchange에서 Contour Plots에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!