Estoy tratando de convertir una imagen 2D en una escultura imprimible en 3D usando solo el código. Primero me gustaría saber si se puede hacer con solo un script. Ya conozco Python y C y sería genial, por supuesto, si pudiera usar uno de estos para hacer lo que quiero.
Aquí hay dos enlaces para que veas lo que quiero decir al decir “Convertir cualquier imagen 2D en una escultura imprimible en 3D” (pero estos están usando software):
https://www.youtube.com/watch?v=ngZwibfaysc
Para ser más específico, quiero insertar una imagen y solo esperar a obtener el resultado, que será una escultura en 3D.
Fue un poco curioso, así que codifiqué un pequeño ejemplo de encoding de superficie de iluminación
height = (color_intensity)*scale
imagen de entrada height = (color_intensity)*scale
Esta es la imagen de entrada que probé (primera pintura al óleo agradable en la búsqueda de Google) :
Este es el resultado (vista previa en 3D de la nube de puntos)
A la izquierda está el gif animado, así que recargue / actualice la página para ver la animación si ya está detenida o descargue el gif y ábrala con un poco más de tendencia, luego baje el color marrón para la vista previa del gif … A la derecha está la vista previa de la nube de puntos de colores (imagen estática)
Este es el código C ++ para calcular esto:
OpenGLtexture zed,nx,ny,nz; // height map,normal maps (just 2D images) picture pic; // source image int x,y,a; // resize textures to source image size zed.resize(pic.xs,pic.ys); nx.resize(pic.xs,pic.ys); float *pnx=(float*) nx.txr; ny.resize(pic.xs,pic.ys); float *pny=(float*) ny.txr; nz.resize(pic.xs,pic.ys); float *pnz=(float*) nz.txr; // prepare tmp image for height map extraction picture pic0; pic0=pic; // copy pic0.rgb2i(); // grayscale // this computes the point cloud (this is the only important stuff from this code) // as you can see there are just 3 lines of code important from all of this for (a=0,y=0;y>3; // height = intensity/(2^3) // compute normals (for OpenGL rendering only) double n[3],p0[3],px[3],py[3]; int zedx,zedy,picx,picy; for (a=zed.xs,zedy=-(pic.ys>>1),picy=1;picy>1),picx=1;picx
Aquí el código de vista previa de OpenGL (C ++):
scr.cls(); // clear buffers scr.set_perspective(); // set camera matrix glMatrixMode(GL_MODELVIEW); // set object matrix rep.use_rep(); glLoadMatrixd(rep.rep); // directional (normal shading) float lightAmbient [4]={0.20,0.20,0.20,1.00}; float lightDiffuse [4]={1.00,1.00,1.00,1.00}; float lightDirection[4]={0.00,0.00,+1.0,0.00}; glLightfv(GL_LIGHT1,GL_AMBIENT ,lightAmbient ); glLightfv(GL_LIGHT1,GL_DIFFUSE ,lightDiffuse ); glLightfv(GL_LIGHT1,GL_POSITION,lightDirection); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); glEnable(GL_COLOR_MATERIAL); // render point cloud int zedx,zedy,picx,picy,a; glColor3f(0.7,0.7,0.7); float *pnx=(float*)nx.txr; float *pny=(float*)ny.txr; float *pnz=(float*)nz.txr; glBegin(GL_POINTS); for (a=zed.xs,zedy=-(pic.ys>>1),picy=1;picy>1),picx=1;picx
Las matrices se establecen de esta manera:
// gluProjection parameters double f=100; //[pixels] focus scr.views[0].znear= f; //[pixels] scr.views[0].zfar =1000.0+f; //[pixels] scr.views[0].zang = 60.0; //[deg] view projection angle scr.init(this); // this compute the Projection matrix and init OpenGL // place the painting surface in the middle of frustrum rep.reset(); rep.gpos_set(vector_ld(0.0,0.0,-0.5*(scr.views[0].zfar+scr.views[0].znear))); rep.lrotx(180.0*deg); // rotate it to match original image
[notas]
Estoy usando mi propia clase de imágenes, así que aquí algunos miembros:
xs,ys
tamaño de imagen en pixeles p[y][x].dd
es el píxel en la posición (x, y) como tipo entero de 32 bits p[y][x].db[4]
es el acceso a píxeles mediante bandas de color (r, g, b, a) También estoy usando OpenGl scr
y textura Clases personalizados:
xs,ys
tamaño del buffer en pixeles Texture::txr
es un puntero de píxel de 32 bits (la imagen se asigna como una matriz lineal 1D) Lo único que queda por hacer es:
Hay otras formas de codificar la iluminación en superficie:
Usted puede hacer algo como la superficie de la lente de Fresnel
Eso necesita mucho menos volumen / material.
La primera mitad de la animación es la encoding de altura normal, luego se cambia a la encoding / empaque de la superficie de Fresnel para comparación
codifique la iluminación no como mapa de altura sino como mapa de rugosidad en su lugar
Esto será visible también desde angularjs y puede ser relativamente delgado, por lo que se necesita muy poco material para esto (mucho menos que la bala anterior)
Mapa de altura real (representación de malla 3D real)
Es muy complicado que necesite normalizar los colores, las sombras y los artefactos de iluminación, por lo que solo queda el sombreado normal (ya que la superficie es de un solo material, color, brillo, rugosidad ...) y solo entonces extraiga el mapa de altura. Para eso, necesita muchas cosas como segmentación, restricción adaptativa, filtrado y mucho más ... Por último, agregue el interior vacío y agregue paredes de soporte para que la malla se mantenga unida mientras / después de la impresión.