Given a 3D .obj model, for example a rabbit. How can we make a depth map out of it? Any idea or help would be much appreciated.
5 Answers
Something like this perhaps:
model = ExampleData[{"Geometry3D", "StanfordBunny"}];
region = BoundaryDiscretizeGraphics[model];
Rasterize @ RegionPlot3D[region, ColorFunction -> (Glow[GrayLevel[#3]] &),
ViewPoint -> {0, 0, 10}, Background -> Black, Boxed -> False, Lighting -> None]
Mostly the same as @SimonWoods, but it runs on V9:
data = ExampleData[{"Geometry3D", "StanfordBunny"}, "VertexData"];
ListSurfacePlot3D[data, MaxPlotPoints -> 50,
ColorFunction -> (Glow[GrayLevel[#3]] &), Mesh -> None,
Background -> Black, Boxed -> False, ViewPoint -> {0, 0, 10},
Axes -> False]
-
2$\begingroup$ To avoid perspecitve distortion, change
ViewPoint
to{0, 0, Infinity}
. $\endgroup$– shrxCommented Aug 13, 2014 at 19:47 -
1$\begingroup$ @shrx the rabbit coordinates go from
0.03
to0.2
, so10
is almostInfinity
$\endgroup$ Commented Aug 14, 2014 at 14:05
The ability of adjusting the viewpoint and position of a model before obtaining its depth-map is necessary in most cases. By adopting the answers provided by the nice guys here, I obtained an alternative method in which the viewpoint and position of the model can be adjusted right before producing its depth-map. And function DiscretizeGraphics
was used instead of BoundaryDiscretizeGraphics
to avoid the boundary curves self-intersect problem.
Import your model first, for example a cow:
model = ExampleData[{"Geometry3D", "Cow"}];
or download a model from a link here, for example a turtle, then import into Mathematica:
Import["c:\\turtle.obj"];
Prepare a graph for viewpoint and position adjustment:
vp = OptionValue[Graphics3D, ViewPoint];
vv = OptionValue[Graphics3D, ViewVertical];
vpoint = {};
vvertical = {};
Show[model, Background -> Black,
ViewPoint -> Dynamic[
vp, (vp = #; vpoint = # ) &],
ViewVertical -> Dynamic[
vv, (vv = #; vvertical = # ) &],
ImageSize -> {300, 300}]
(Drag for rotation, Shift-Drag for position, Crt-Drag for zooming)
And run the following code for the depth-map when you are happy with the adjustments:
region = DiscretizeGraphics[model];
Rasterize@RegionPlot3D[region, ColorFunction -> (Glow[GrayLevel[#3]] &),
ViewPoint -> vpoint,
ViewVertical -> vvertical,
Background -> Black,
Boxed -> False,
Lighting -> None]
-
$\begingroup$ You should probably incorporate the code from Timothy Wofford's answer as well, otherwise you're still colouring by the original $z$-coordinates of the model rather than the depth from the camera. i.sstatic.net/wFmRm.png $\endgroup$– user484Commented Aug 21, 2014 at 5:24
-
$\begingroup$ and maybe a
ViewCenter
andViewAngle
to complete the camera specification? $\endgroup$ Commented Aug 21, 2014 at 13:51
Here's a variation to help with different points of view.
data = ExampleData[{"Geometry3D", "StanfordBunny"}, "VertexData"];
viewPoint = {-1, -1, -1};
{min, max} = {Min@#, Max@#} &@(EuclideanDistance[#, viewPoint] & /@ data)
ListSurfacePlot3D[data, MaxPlotPoints -> 50,
ViewPoint -> viewPoint,
ColorFunction -> (Glow[GrayLevel[
(max - EuclideanDistance[{#1, #2, #3}, viewPoint])/(max - min)
]] &),
ColorFunctionScaling -> False,
Mesh -> None, Background -> Black, Boxed -> False,
Axes -> False]
Thanks to Rahul Narain for pointing out my oversight, and thanks to Timothy Wofford for his suggestion. Here, I revised my code as below. I still keep on using the function DiscretizeGraphics
because I can't get rid of the ugly boundaries produced by ListSurfacePlot3D
.
Code for viewpoint & position adjustment:
model = Import["c:\\turtle.obj"];
vp = OptionValue[Graphics3D, ViewPoint];
vv = OptionValue[Graphics3D, ViewVertical];
vc = OptionValue[Graphics3D, ViewCenter];
va = OptionValue[Graphics3D, ViewAngle];
vpoint = {-0.5 , 0.8 , 3 };
vvertical = {0.1 , 2 , 0.5};
vcenter = {{0.5 , 0.5 , 0.5 }, {0.5 , 0.5 }};
vangle = 0.2;
Show[model, Background -> Black,
ViewPoint -> Dynamic[vp, (vp = #; vpoint = #) &],
ViewVertical -> Dynamic[vv, (vv = #; vvertical = #) &],
ViewCenter -> Dynamic[vc, (vc = #; vcenter = #) &],
ViewAngle -> Dynamic[va, (va = #; vangle = #) &],
ImageSize -> {300, 300}]
(Drag for rotation, Shift-Drag for position, Alt-Drag for zooming)
Code for producing the depth-map after the adjustment:
region = DiscretizeGraphics[model];
vdata = Import["c:\\turtle.obj" , "VertexData"];
viewPoint = vpoint;
{min, max} = {Min@#, Max@#} &@(EuclideanDistance[#, viewPoint] & /@ vdata);
Rasterize@RegionPlot3D[region,
ColorFunction -> (Glow[
GrayLevel[ (max - EuclideanDistance[{#1, #2, #3}, viewPoint])/(max - min)]] &),
ViewPoint -> vpoint,
ViewVertical -> vvertical,
ViewCenter -> vcenter,
ViewAngle -> vangle,
Background -> Black,
Boxed -> False,
Lighting -> None]