How to render an accurate image of a 3D model
Show older comments
I want to create an accurate image of a 3D model as if it were seen by a camera. I am using functions such as "plot3" but the rendered points in the image are a little displaced from where I would predict. The simplest example is to try to create an image of a single point, as seen by a camera using a simple pinhole camera model.
After running the code below, it renders an image of a point located at (x,y) = (416,248). However, I predict that the point should appear at (x,y) = ( 450.5,256). Any ideas?
% Create a window to hold an image of size 512x512 pixels
figure('Position',[1 1 512 512]);
% Define the XYZ location of a point with respect to camera
P = [1; 0; 10];
% This creates the rendered image of the point
plot3(P(1),P(2),P(3),'.');
fov = 15; % Define field of view of the camera in degrees
camva(15); % Set the camera field of view
campos([0 0 0]); % Put the camera at the origin
camtarget([0 0 1]); % The camera looks along the +Z axis
camproj('perspective');
axis off
axis vis3d
daspect([1 1 1])
F = getframe(gcf); % Grab the rendered frame
I=rgb2gray(F.cdata); % This is the rendered image
figure, imshow(I,[]), impixelinfo;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Calculate where I expect the point to appear
% Calculate effective focal length using pinhole camera model.
focal = 256/tand(fov/2);
% Use perspective projection equations to predict image point (x,y)
x = focal * P(1)/P(3) + 256
y = focal * P(2)/P(3) + 256
Accepted Answer
More Answers (2)
John Barber
on 15 Sep 2011
1 vote
A few thoughts:
1) I concur with Walter's point about getting the actual figure position. You should also be familiar with a number of axes properties - see the MATLAB documentation for 'Axes Properties' for details.
2) For absolute pixel accuracy, be aware that the drawn position of a particular plot object is quantized into integer pixels. I have noticed occasional offsets of 1 pixel between a drawn point and a tick mark at the exact same location. This behavior may be different for different settings of the figure's 'Renderer' property.
3) If you really want to get a peek behind the curtain, the following undocumented axes properties will be of interest:
- XForm
- x_RenderTransform
- x_NormRenderTransform
- x_ViewTransform
- x_ViewPortTransform
- x_RenderScale
- x_RenderOffset
- x_ProjectionTransform
The code in the following MATLAB functions will help with understanding the above properties:
- viewmtx
- legendcolorbarlayout (see the 'topixels' subfunction)
1 Comment
Yair Altman
on 15 Sep 2011
Re XForm, see the following: http://www.mathworks.com/matlabcentral/newsreader/view_thread/253563
Walter Roberson
on 15 Sep 2011
When you use
figure('Position',[1 1 512 512]);
the figure might not actually be placed at the location you expect, and might not be the size you expect. MATLAB (or Java, or something) displaces the figure in order to allow operating system margins such as the Windows Task Bar, and might end up making it a bit smaller.
You should get() the figure position to see what you really ended up with; likewise you should check the actual image size that you obtained through getframe() as MATLAB has been known to grab slightly different sizes (for reasons that are as yet unclear.)
Categories
Find more on MATLAB Support Package for USB Webcams 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!