A bit too late to the party, I found that there's no way to add texture to the rabbit using @Simon's method, thus I created one of my own. Effect first!
One rabbit only, correct texture for the rabbit for most part.
The code is as follows, and could be downloaded here:
mappedstereogram[img_Image, depth_Image, bg_Image, n_List: {5, 3},
shift_: 40, supersampling_: 2, filter_: 1] :=
Module[{imgbg, imgmap, imgdep,
dimo = Round[ImageDimensions[bg]*supersampling, 2], l, conn},
imgbg =
ImageData@
ImageAssemble@
ConstantArray[
ImageResize[ColorConvert[bg, "RGB"], dimo,
Resampling -> "Linear"], Reverse@n];
imgmap =
ImageData@
ImageCrop[
ImageResize[ColorConvert[img, "RGB"], Scaled@supersampling,
Resampling -> "Linear"], n dimo];
imgdep =
Round[dimo[[1]]/2 -
shift Clip[
ImageData@
ImageCrop[
ImageResize[ColorConvert[depth, "Grayscale"],
Scaled@supersampling, Resampling -> "Linear"], n dimo], {0,
1}]];
l = Length@imgdep[[1]];
Table[
conn =
ConnectedComponents@
Graph@Select[
Flatten[MapIndexed[{(l + #2[[1]]) <-> (#2[[1]] - #1), (l + #2[[
1]]) <-> (#2[[1]] + #1)} &, imgdep[[i]]], 1],
0 < #[[2]] <= l &];
MapThread[
With[{res =
Select[Thread@{#1, imgmap[[i, #1]]}, Max@#[[2]] != 0. &]},
imgbg[[i, #2]] =
ConstantArray[
If[Length@res != 0., SortBy[res, #[[1]] &][[1, 2]],
imgbg[[i, #2[[1]]]]], Length@#2]] &, {Pick[conn,
UnitStep[l - conn], 0] - l, Pick[conn, UnitStep[l - conn], 1]}]
, {i, Floor[(Length@imgbg -
supersampling ImageDimensions[depth][[2]])/2],
Ceiling[(Length@imgbg +
supersampling ImageDimensions[depth][[2]])/2]}];
ImageResize[MedianFilter[Image@imgbg, filter],
Scaled[1/supersampling], Resampling -> "Linear"]
]
input are a texture image img
, a corresponding depth image depth
, and a background image bg
.
First three lines of code are responsible for formatting the image to the same scale. Then we start to create the stereogram using the following equation:
$$f(x,y,h(x,y))=g(x-\alpha h(x,y),y)=g(x+\alpha h(x,y),y)$$
where $f$ and $g$ are pixel value on the object and on the image plane, $\alpha$ is the difference of viewing angle of two eyes, and $h(x,y)$ are the depth of the image.
We first find out the correlation between $f$ and $g$ by constructing a graph and calculate its connected components. A connected component like $f(x_0)\leftrightarrow g(x_1)\leftrightarrow f(x_2)\leftrightarrow g(x_3), f(x_2)\leftrightarrow g(x_4)$ means these positions should share the same pixel value!
Then by using the texture given by $f(x_0)$ to render $g(x_1), g(x_3),g(x_4)$, we can have the correct stereogram.
To avoid defects, super sampling and MedianFilter
are implemented.
This method can be used together with @Simons' to get augment visual effects: