Hi,
i’m new with plotly and i’m using it for a 3D mesh generator. I would like to know if it’s possible to map a texture (taken from a 2D image) into a 3D surface through a correspondence matrix (For each vertex in 3D assing a 2D point into the image, from which i can take the texture data (RGB)). I’ve did something like this with the function ‘plot_mesh’ from the toolbox graph on matlab and now i need to do the same thing in python but i don’t find anything like this, someone can help me?
Thanks in advance
@barloccia This notebook illustrates how you can map a 2d image onto a surface:
https://plot.ly/~empet/14172/mapping-an-image-on-a-surface/
Unlike matlab you cannot map a multicolor (rgb) image because plotly can color a surface only using a colormap.
The link does not work anymore
The notebook illustrating how to map a graycolor onto a surface has been removed because meanwhile
it was developed a method to map a color image: https://github.com/empet/Texture-mapping-with-Plotly.
But if you need the simplest case, let me know, and I’ll repost the removed notebook.
I have the following and want to render the texture of the satellite image to this hight profile. I have tried the linked method, but it did not work.
@Klegi Without giving details about the mapped image on your surface, that seems to be a rough (unsmooth) surface, it’s hard to have an opinion, just by looking at the posted image.
If the mapped image has a low resolution then the result is not as expected.
What I see is an image with dark colors that probably doesn’t allow to distinguish details.
To fix such a drawback you should add lighting
and lightposition
in the go.Surface
definition, having respectively the following attributes (but changing the assigned values according to your needs)
lighting=dict(ambient=0.18,
diffuse=1,
fresnel=0.1,
specular=1,
roughness=0.05,
facenormalsepsilon=1e-8,
vertexnormalsepsilon=1e-15),
lightposition=dict(x=100,
y=200,
z=1000)
Here are more details. The upper image shows the height profile dem_np. The lower is the satellite image that should be the texture of the height like in google earth. Dem is a (541, 901, 1) and land_np is (541, 901, 3) numpy array. I will make the satellite image a bit shinier in preprocessing in the future.
fig = go.Figure(data=[go.Surface(z=dem_np, x=x, y=y[::-1], surfacecolor=land_np[...,0], lighting=lighting, lightposition=lightposition)])
fig.update_layout(scene=dict(
zaxis=dict(nticks=4, range=[np.min(dem_np), np.max(dem_np)]),
aspectratio=dict(x=1, y=1, z=0.2)
))
Edit - solved:
I have solved my problem with the github link you provided above. Thank you!
And I have found a bug in it. I changed the image2zvals function as the colorscale did not support numpy types. So I adapted the line before the return statement to
pl_colorscale = [[float(sv), f'rgb{int(color[0]), int(color[1]), int(color[2])}'] for sv, color in zip(scale, colors)]