How to extract the cdata of a 2D surface from 3D surface and save it as a matrix?

Hello, I generated a 3D surface. The task is to extract the cdata of a 2D surface from the 3D surface and save it as png files. For example, extract the surface (0,90). I attached the X and Y and Z values here. You can use the below codes to generate a 3D surface in my example:
%generate a 3D surface
figure(1);subplot(1,2,1);
surf(X,Y,Z);colormap jet;
shading interp;
%see the (0,90) 2D surface;
view(0,90);subplot(1,2,2);
3D 2D
This is my method to extract the 2D surface:
view(0,90);
c=getframe(gca);
imwrite(c.cdata,'myimage.png');
I know this is good method to get the gca cdata. However, I have to generate millions of images. This method is a little slow. Could I know a direct method to generate a cdata matrix from some calculation with X Y and Z instead of using getframe()??
By the way, could I know how to write the cdata matrix to png files using the function writematrix()?
Thank you very much!!!!!!!!

 Accepted Answer

You can just assign the matrix directly, like (untested)
load("X.mat");
load("Y.mat");
load("Z.mat");
tic
outputImage = zeros(1, 500, 'uint8');
xs = round(rescale(X, 1, 500));
ys = round(rescale(Y, 1, 500));
zs = round(rescale(Z, 0, 255));
for k = 1 : numel(xs)
outputImage(ys(k), xs(k)) = zs(k);
end
imshow(outputImage, 'ColorMap', jet(256), ...
'XData', [min(X, [], 'all'), max(X, [], 'all')], ...
'YData', [min(Y, [], 'all'), max(Y, [], 'all')] ...
);
axis('on', 'image')
toc

9 Comments

Hello, I fixed some variable names. But when I run that, there's an error:
>>dierctassignMatrix
Index in position 1 is invalid. Array indices must be positive integers or logical values.
Error in dierctassignMatrix (line 9)
outputImage(Y(k), X(k)) = zs(k);
This is the code with fixed variable names: Could you help me fixe that? Thanks!!!!!!!!!!
load("X.mat");
load("Y.mat");
load("Z.mat");
outputImage = zeros(1, 500, 'uint8');
xs = round(rescale(X, 1, 500));
ys = round(rescale(Y, 1, 500));
zs = round(rescale(Z, 0, 255));
for k = 1 : length(xs)
outputImage(Y(k), X(k)) = zs(k);
end
imshow(outputImage, 'ColorMap', jet(256), ...
'XData', [min(X, [], 'all'), max(X, [], 'all')], ...
'YData', [min(Y, [], 'all'), max(Y, [], 'all')] ...
);
Try this:
load("X.mat");
load("Y.mat");
load("Z.mat");
tic
outputImage = zeros(1, 500, 'uint8');
xs = round(rescale(X, 1, 500));
ys = round(rescale(Y, 1, 500));
zs = round(rescale(Z, 0, 255));
for k = 1 : numel(xs)
outputImage(ys(k), xs(k)) = zs(k);
end
imshow(outputImage, 'ColorMap', jet(256), ...
'XData', [min(X, [], 'all'), max(X, [], 'all')], ...
'YData', [min(Y, [], 'all'), max(Y, [], 'all')] ...
);
axis('on', 'image')
toc
Elapsed time is 0.217745 seconds.
Thanks, I generated the image successfully. However, comparing to my goal image, the color looks wrong. My code used shading interp to make the 3D surface more clear. Is there any way can make your code's matrix like that?
I'm a refresher, I don't know how to realized that. By the way, I typed:
imwrite(outputImage,'myimage.png');
To save the image, however, the image is gray. Is any good method to make it as RGB? Thanks!!!
That's probably what is taking so long. My code doesn't do any interpolation so it looks like there are some rows and columns that did not get anything assigned to them. Are you really 100% sure that it is necessary? I mean we still get the idea. If you need shading and interpolation of the missing pixels, then you'll probably have to live with surf() or pcolor() and the extra time that they take to do the shading interpolation.
Of course I just used an arbitrary colormap. You can choose whatever colormap you want or even create a custom one.
Hello, these images are used to train CNN, I don't know whether the color will affect the accuracy or not. So I tried to make them as same as possible. By the way, in this period, I fixed the gray image problem. Just :
imwrite(ind2rgb(im2uint8(mat2gray(outputImage)), jet(256)),'myimage.png');
Could I know how to interpolate the matrix? I mean if I interpolate the matrix and realize a same matrix just like surf() with shading interp does. I can generate a same image. Do you know some methods about that? Thanks.
The color is arbitrary. You should not use it (some arbitrarily pseudoclored image) for CNN training. If you have a gray scale image with values Z, and your network requires color, you should just get a color version of Z with cat() and use that for training.
Z = cat(3, Z, Z, Z);
You could use scatteredInterpolant() to fill in the holes but it will take a long time. Attached is a demo you can adapt.
Could you pleas explain your statement with my code further? How to use
Z=cat(3,Z,Z,Z);
I run that and get a 854*361*3 matrix. But how to use this? Thanks
I ran your code thanks. By the way, Could I know how to change the color in the four cornors to white? Thanks!
If you're doing deep learning, those Z images are just sitting in a folder that you have an imageDataStore set up to point to.
To set the corners to white, set the values to 255
Z(1,1) = 255;
Z(1,end) = 255;
Z(end, 1) = 255;
Z(end, end) = 255;
Z=cat(3,Z,Z,Z);
% Then save to disk so your imageDatastore will point to it.

Sign in to comment.

More Answers (0)

Products

Release

R2021b

Community Treasure Hunt

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

Start Hunting!