Многооконная Реконструкция
3D-объект может быть восстановлен на основе нескольких 2D изображений. Функция ImageDisplacements используется для определения параллакса от одного изображения к другому. Чем больше сдвиг параллакса, тем ближе объект позади соответствующего пикселя. С помощью этой информации, вы можете определить вершины объекта сетки, полученного с помощью функций ImageMesh и TriangulateMesh. Результат отображается путем наложения текстуры на 3D сетку.
Получим объект-маску центрального изображения.
mask = Erosion[Binarize[imgs[[2]], 0], 1];
Определим параллакс в левом и правом изображениях относительно центрального изображения.
parallaxL = First@ImageDisplacements[imgs[[{2, 1}]]];
parallaxR = First@ImageDisplacements[imgs[[{2, 3}]]];
Сочетаем перемещения, выполненные в предыдущем шаге, в общем параллаксе.
parallax = parallaxL - parallaxR;
В данном случае, Х-компонент параллакса примерно пропорционален глубине соответствующего источника пикселей.
depth = Blur@
Opening[ImageMultiply[ImageAdjust@Image[parallax[[All, All, 1]]],
mask], DiskMatrix[4]]
Построим функцию глубины.
depthFunction = ListInterpolation[Transpose@Reverse@ImageData[depth]];
Получим более точный объект-сетку, с уточнением, зависящим от значимости этого объекта.
resolution = ImageAdjust@ImageSaliencyFilter[imgs[[2]]];
resolutionFunction =
ListInterpolation[Transpose@Reverse@ImageData@resolution];
\[CapitalOmega] = TriangulateMesh[
ImageMesh[Erosion[mask, DiskMatrix[2]]],
MeshRefinementFunction ->
Function[{vertices, area},
area > 32 + 512 (1 - resolutionFunction @@ Mean[vertices])^6]
]
Осуществим выдавливание объекта-сетки с помощью функции глубины.
Graphics3D[
GraphicsComplex[
Apply[{##, depthFunction[##]} &,
MeshCoordinates[\[CapitalOmega]], {1}],
{EdgeForm[], MeshCells[\[CapitalOmega], 2]}
],
PlotRange -> Append[Thread[{0, ImageDimensions[mask]}], {0, 1}],
BoxRatios -> {1, 1, 2/3},
ViewPoint -> Top
]
Определим текстуру объекта на основе центрального изображения.
texture = SetAlphaChannel[imgs[[2]], mask]
Наложим полученную текстуру на 3D объект.
Graphics3D[
{Texture[texture],
GraphicsComplex[
Apply[{##, depthFunction[##]} &,
MeshCoordinates[\[CapitalOmega]], {1}],
{EdgeForm[], MeshCells[\[CapitalOmega], 2]},
VertexTextureCoordinates ->
Map[#/ImageDimensions[texture] &, MeshCoordinates[\[CapitalOmega]]]
]
},
PlotRange -> Append[Thread[{0, ImageDimensions[mask]}], {0, 1}],
BoxRatios -> {1, 1, 2/3},
Lighting -> {{"Ambient", White}},
ViewPoint -> Top,
Boxed -> False
]