Clear Filters
Clear Filters

How to convert an image back to a data matrix?

9 views (last 30 days)
Darcy Cordell
Darcy Cordell on 12 Apr 2022
Edited: DGM on 12 Apr 2022
I have a color PNG figure with contours which displays some data matrix as a colorplot. The figure was made elsewhere and cannot be reproduced in MATLAB. I am trying to extract the data from this plot in MATLAB based on the colors. I'm not sure if this is an incredibly easy problem, or effectively impossible.
For a simple example, see the attached figure. You do not know what data matrix was used to produce this figure. Here is how I am trying to tackle the problem:
A = imread('example.png');
N = 100;
[X,cmap] = rgb2ind(A,N,'nodither');
pcolor(X(end:-1:1,:)); shading flat; hold on
What you can see is that I am able to load the image as a matrix and reproduce the image almost exactly using rgb2ind. But, the "data" stored in variable X is completely random numbers linked to a random colormap cmap. You can see this is the case by comparing the colorbar in the original image to the plotted colorbar.
Looking at the original figure, it is clear that blues should correspond to values near 0.2, greens should correspond to values near 1.0, and yellows should correspond to values around 1.8. But how can I convert the matrix stored in X back to a matrix which corresponds to the original data?
Any help is appreciated.

Answers (1)

DGM on 12 Apr 2022
Edited: DGM on 12 Apr 2022
AA = imread('');
% get position information from the image
cbx = 903;
cby = [65 748];
datx = [185 869];
daty = [64 748];
tickstep = 81;
blocksize = [7 14]; % [x y]
% get plot region
ROI = AA(daty(1):daty(2),datx(1):datx(2),:);
% find contours
ROIlab = rgb2lab(ROI);
[L A B] = imsplit(ROIlab);
C = sqrt(A.^2 + B.^2);
mk = C<45 & L<=40;
badpix = imdilate(mk,ones(3));
% get rid of contours
for c = 1:3
ROI(:,:,c) = regionfill(ROI(:,:,c),badpix);
% resize ROI to data resolution
ROI = imresize(ROI,[size(ROI,1)/blocksize(2) size(ROI,2)/blocksize(1)]);
% get color table and convert image
CT = unique(permute(AA(cby(1):cby(2),cbx,:),[1 3 2]),'rows');
CT = im2double(CT);
ROIidx = rgb2ind(ROI,CT);
% assume the center of the z-scale is 1
zspan = 0.2*range(cby)/tickstep;
zextent = 1 + [-1 1]*zspan/2;
zmap = linspace(zextent(1),zextent(2),size(CT,1));
% apply zmap to ind image to get zdata estimate
Z = flipud(zmap(ROIidx));
% get corresponding X,Y vectors
X = linspace(-1,1,size(Z,2));
Y = linspace(-1,1,size(Z,1));


Find more on Colormaps in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!