0
votes

I need to create a random surface (which I created using peaks) and save it under certain lighting conditions (which I added using light). The plot itself is created using surf. Then I set the required viewing angle using view(2).

[X,Y] = meshgrid(-2:.025:2);
Z = peaks(X,Y);
h = surf(X,Y,Z);

% Necessary for task
h.AmbientStrength = 0.;
h.SpecularStrength = 0.;
h.DiffuseStrength = 1.;
h.BackFaceLighting = 'unlit';
h.FaceLighting = 'gouraud';

view(2);
l = light('Position',[-2, -2, 50],'Style','local','Color',[1 1 1]);

The Z matrix has dimensions 161x161. I want to save a 161x161 matrix that corresponds to the lighting/shading in the figure. Any ideas?

A sample generated plot:

A sample generated plot

Edit: I do intend to work with the saved image. The overall goal is to perform photometric stereo (something on these lines). Hence, I need to generate several images of the surface under different lighting conditions.

PS: Thanks for h.LineStyle='none';

2
I assume you want it without hthe black lines? With h.LineStyle='none';? - Ander Biguri

2 Answers

1
votes

I assume you want this for other reasons than processing the data, as getting data from a plot is the worst case. Assuming too that you forgot h.LineStyle='none';, else you will just not see them.

This code will approximately do the job:

% get the frame plotted in the figure
test=getframe(gca);
% the size of the image will be arbitrary, depends on the size of the figure on screen and your screen resolution. Lets interpolate, so we can get the values at the exact points you want. I use the same bounds as in your description
[Xi,Yi]=meshgrid(linspace(-2,2,size(test.cdata,2)),linspace(-2,2,size(test.cdata,1)));

% Only works if grayscale, repeat x3 for each dimension if you have color
img=interp2(Xi,Yi,double(test.cdata(:,:,1)),X,Y)/255;

figure;imshow(img);
0
votes

The Zmatrix only contains the 3D data to represent the surface, it is not affected by the lighting / shading setting you are applying later-on to its visualization.

If you want to reproduce the figure you've obtained by loading "some saved data", you have to save the Z matrix (it should be better to save also X and Y) along the values of the lighting setting.

To do this you first have to modify your code by assigning the lightig values to a corresponding set of variables, then you have to use this vatiables to set the lighting.

At the end you have to save all these variables.

[X,Y] = meshgrid(-2:.025:2);
Z = peaks(X,Y);
h = surf(X,Y,Z);

% Necessary for task

%h.AmbientStrength = 0.;
%h.SpecularStrength = 0.;
%h.DiffuseStrength = 1.;
%h.BackFaceLighting = 'unlit';
%h.FaceLighting = 'gouraud';

% Assign the setting values to a set of varialbles
AmbientStrength_val=0.;
SpecularStrength_val=0.;
DiffuseStrength_val=1.;
BackFaceLighting_val='unlit';
FaceLighting_val='gouraud';


h.AmbientStrength = AmbientStrength_val;
h.SpecularStrength = SpecularStrength_val;
h.DiffuseStrength = DiffuseStrength_val;
h.BackFaceLighting = BackFaceLighting_val;
h.FaceLighting = FaceLighting_val;

view_val=2;
%view(2);
view(view_val);

light_pos=[-2, -2, 50]
light_style='local'
light_color=[1 1 1]
%l = light('Position',[-2, -2, 50],'Style','local','Color',[1 1 1]);
l = light('Position',light_pos,'Style',light_style,'Color',light_color);

save('data_peaks.mat','X','Y','Z','AmbientStrength_val','SpecularStrength_val', ...
                     'DiffuseStrength_val','BackFaceLighting_val', ...
                     'FaceLighting_val','light_pos','light_style', ...
                     'light_color','view_val')

To reproduce the figure, in the future, you can have a script like the following:

% Load the saved values
load data_peaks
% Plot the surface
h = surf(X,Y,Z);
% Set the parameters
h.AmbientStrength = AmbientStrength_val;
h.SpecularStrength = SpecularStrength_val;
h.DiffuseStrength = DiffuseStrength_val;
h.BackFaceLighting = BackFaceLighting_val;
h.FaceLighting = FaceLighting_val;

view(view_val);

l = light('Position',light_pos,'Style',light_style,'Color',light_color);