问题
I'm trying to take "images" of a 3D model. I am able to load an STL file through this code. What I need to do is be able rotate the object, and take "images" of it as it rotates.
stlread outputs a face and vertex structure that is compatible with patch(), so I can display the object, but I'm not sure how to actually store that image into a matrix.
回答1:
I think what you are after is the function getframe, which captures the content of an axes and store the data as a regular "image" matrix.
I made a simple GUI to illustrate the concept. Basically I took the code from the link you provided (stldemo.m
) and added a few features to take snapshots. In this case I added the command rotate3d on
to rotate the femur inside the axes and a pushbutton whose callback calls getframe
and captures the content of the axes. Basically you rotate the femur//patch object as you wish and you press the button to get a snapshot. In the code I make a new figure pop up to convince you it works, but you can of course do whatever you want with the data.
Note that using getframe
outputs a structure with a field called cdata
...that's what you are after in order to get the content of the axis as a matrix.
So here is the code and a few snapshots to illustrate:
function SnapShotSTL(~)
%// Taken from the stldemo.m file.
%% 3D Model Demo
% This is short demo that loads and renders a 3D model of a human femur. It
% showcases some of MATLAB's advanced graphics features, including lighting and
% specular reflectance.
% Copyright 2011 The MathWorks, Inc.
%% Load STL mesh
% Stereolithography (STL) files are a common format for storing mesh data. STL
% meshes are simply a collection of triangular faces. This type of model is very
% suitable for use with MATLAB's PATCH graphics object.
% Import an STL mesh, returning a PATCH-compatible face-vertex structure
handles.fv = stlread('femur.stl');
%% Render
% The model is rendered with a PATCH graphics object. We also add some dynamic
% lighting, and adjust the material properties to change the specular
% highlighting.
%// Create figure, axes and a pushbutton.
hFigure = figure('Units','Pixels','Position',[200 200 500 600]);
hAxes1 = axes('Units','pixels','Position',[50 50 450 400]);
hSnapShot = uicontrol('Style','push','Position',[50 500 60 30],'String','SnapShot','Callback',@(s,e) GetSnapshot);
patch(handles.fv,'FaceColor', [0.8 0.8 1.0], ...
'EdgeColor', 'none', ...
'FaceLighting', 'gouraud', ...
'AmbientStrength', 0.15);
% Add a camera light, and tone down the specular highlighting
camlight('headlight');
material('dull');
% Fix the axes scaling, and set a nice view angle
axis('image');
view([-135 35]);
rotate3d on %// Enable to rotate the object in the axes
guidata(hFigure,handles);
function GetSnapshot
CurrentImage = getframe(gca);
ImageData = CurrentImage.cdata; %// Access the data. I create a variable but that's not strictly necessary.
%// Here a new figure is created and the image displayed in it... you can store it and do as you like with it.
figure;
imshow(ImageData);
guidata(hFigure,handles);
end
end
So the GUI looks like this when opened:

Then after a rotation of the object/femur:

and finally after pressing the pushbutton, a snapshot is taken (i.e. getframe
is executed) and the resulting image matrix displayed in a new figure:

Note that I used imshow
to actually display the image but the data can be manipulated as well.
Moreover, you can also use the following calling syntax for getframe
in case you want to retrieve the colormap associated with your data:
F = getframe;
[X,map] = frame2im(F);
In this case, X
would be equivalent to G when using this code:
G = F.cdata;
Finally, you could set up a loop in which the actual patch object is rotated by itself and frames are taken automatically. That should not be too hard to implement :)
Hope that helps!
来源:https://stackoverflow.com/questions/28490547/taking-images-of-3d-model-using-stlread