- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试仅使用代码将 2D 图像转换为可 3D 打印的雕塑。首先我想知道是否可以只用一个脚本来完成?我已经了解 Python 和 C,如果我可以使用其中之一来做我想做的事,那当然会很棒。
这里有两个链接可以让您明白我所说的“将任何 2D 图像变成可 3D 打印的雕塑”的意思(但这些都是使用软件):
https://www.youtube.com/watch?v=ngZwibfaysc
https://www.youtube.com/watch?v=-fe2zxcKSic
更具体地说,我想插入一张图片,然后等待获得 3D 雕塑的结果。
最佳答案
有点好奇所以我编写了一个照明表面编码的小例子
height = (color_intensity)*scale
这是我测试过的输入图像(Google 搜索中的第一张不错的油画):
这是结果(点云3D预览)
左边是 gif 动画,所以如果动画已经停止,请重新加载/刷新页面以查看动画,或者下载 gif 并以更合适的方式打开,然后用 brownser 进行 gif 预览...右边是彩色点云预览(静态图片)
这是计算这个的 C++ 代码:
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<pic.ys;y++)
for (x=0;x<pic.xs;x++,a++)
zed.txr[a]=pic0.p[y][x].dd>>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<pic.ys;picy++,zedy++)
for (a++, zedx=-(pic.xs>>1),picx=1;picx<pic.xs;picx++,zedx++,a++)
{
vector_ld(p0,zedx-1,zedy ,-zed.txr[a -1]); // 3 neighboring points
vector_ld(py,zedx ,zedy-1,-zed.txr[a+zed.xs ]);
vector_ld(px,zedx ,zedy ,-zed.txr[a ]);
vector_sub(px,p0,px); // 2 vectors (latices of quad/triangle)
vector_sub(py,p0,py);
vector_mul(n,px,py); // cross product
vector_one(n,n); // unit vector normalization
pnx[a]=n[0]; // store vector components to textures
pny[a]=n[1];
pnz[a]=n[2];
}
这里是 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<pic.ys;picy++,zedy++)
for (a++, zedx=-(pic.xs>>1),picx=1;picx<pic.xs;picx++,zedx++,a++)
{
//glColor4ubv((BYTE*)&pic.p[picy][picx].dd); // this is coloring with original image colors but it hides the 3D effect
glNormal3f(pnx[a],pny[a],pnz[a]); // normal for lighting
glVertex3i(zedx ,zedy ,-zed.txr[a]); // this is the point cloud surface point coordinate
}
glEnd();
scr.exe(); // finalize OpenGL calls and swap buffers ...
scr.rfs();
矩阵设置如下:
// 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
[注释]
我正在使用自己的图片类,所以这里有一些成员:
xs,ys
图像大小(以像素为单位)p[y][x].dd
是(x,y)位置的像素,为32位整数类型p[y][x].db[4]
是按色带 (r,g,b,a) 访问像素我还使用自定义 OpenGl scr
和纹理类:
xs,ys
缓冲区大小(以像素为单位)Texture::txr
是32位像素指针(图像分配为线性一维数组)唯一剩下要做的就是:
还有其他方法可以将光照编码到表面:
你可以做一些像菲涅尔透镜表面
需要更少的体积/ Material
动画前半部分是正常的高度编码然后切换到菲涅耳表面编码/打包进行比较
不是将光照编码为高度图,而是编码为粗糙度图
这从角度也可以看到,并且可以相对较薄,因此需要很少的 Material (比以前的子弹少得多)
真实高度图(真实3D网格表示)
这是非常棘手的,你需要标准化颜色、阴影和照明伪影,所以只剩下正常的阴影(因为表面来自单一 Material 、颜色、光泽度、粗糙度......)然后才提取高度图。为此,您需要很多东西,例如分割、自适应阈值处理、过滤等等......最后添加空的内部并添加支撑墙,以便网格在打印时/打印后保持在一起。
关于python - 使用代码将任何 2D 图像变成可 3D 打印的雕塑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31322052/
有没有更好的方法用 PHP 将数据输出到 html 页面? 如果我想在 php 中用一些 var 制作一个 div,我会写类似的东西 print (''.$var.''); 或 echo "''.$v
我可以使用 java awt print 来打印文档/文件而不是使用 javax print 吗?我发现在 java awt print 中有一个选项可以使用 AttributedString 将内容
目前我通过以下方式运行 R 脚本: R --slave argument1 argument2 ... 我想知道 R 中关于如何退出脚本并发出警告的最佳实践,q() 会这样做吗? if(!file.
谁能告诉我如何编写一个程序,用 gcc 编译时打印 c ,用 g++ 编译时打印 c++? 最佳答案 #ifdef __cplusplus printf("c++\n"); #else
我需要支持在 KitKat 设备上打印,但我的目标 SDK 是 13(无法更改)。 特别是我需要打印一个 webview。 这是用于打印 webview 的 API: http://developer
我正在尝试创建一个简单的函数,其中 python 将根据您的年份输入计算年龄。我已经尝试了几种方法,但我没有运气 atm。 附:对不起,我是新手。 ame = input(" Enter your n
JavaFX 2.0 是否支持打印?我有一个文本区域,我从中获取文本然后我想打印它,但似乎没有这个功能。 当然,这里我说的是打印到打印机。 :) 最佳答案 尚不支持。作为一种解决方法,您可以使用 Ja
我试图找出printOn的重点。我查看了一些实现它的类,看起来它只是帮助打印不同数据类型的单位。这是准确的吗? 如果是这样,有人能指出我如何为我自己的类(class)实现这一点的正确方向吗?我将在可能
我无法让 IE 打印我的 Canvas (使用 excanvas 生成)...我使用的是最新版本的 excanvas。 http://dl.dropbox.com/u/997831/canvas.ht
我搜索了很多但没有人回答我的问题,我读到在这样的信号处理程序中使用 cout 是不安全的: void ctrlZHandler(int sig_num) { //SIGTSTP-18
我有兴趣打印一系列查询。我有以下代码。 start = datetime.datetime(2012, 2, 2, 6, 35, 6, 764) end = datetime.datetime(201
public class javaClass { public static void main(String [] arg) { String row1 = "A____A"
我需要写入前一行的命令,例如不带\n 的 print()。 下面是一些示例代码: a=0 print("Random string value") if a==0: print_to_prev
我有一个使用 UIKit 和 Objective C 的旧 iOS 应用程序,我目前正在将其移植到 SwiftUI 和 Swift。一切都很顺利,我喜欢 Swift 和 SwiftUI。该应用程序已经
我创建了一个求和函数,它接受一个开始编号和一个结束编号,并返回这两点之间的总和答案 def print_sum_equations(start_number,end_number):
在 Perl 6 中,print 和有什么区别? , put和 say ? 我怎么看 print 5不同,但 put 5和 say 5看起来一样。 最佳答案 put $a就像 print $a.Str
我正在使用 here 中的 getOrgChart 库,我正在尝试打印整个图表,而不仅仅是可见部分。不幸的是,当使用标准库打印功能时,它只会打印出第一部分,而我不知道如何打印整个图表(该图表相当宽,大
我制作了一个非常适合 A4 页面的 View 。现在我想打印它。请注意,我没有使用drawRect或类似的东西,只是一个带有 subview 和文本标签的普通 View 。我的问题是,我对该 View
由于 Cocoa-Java 已弃用,我正在将 Cocoa-Java 代码迁移到 Cocoa + JNI。该代码打印存储在文件中的图像。新的 Cocoa 代码基本上是: NSImage *image =
这个问题已经有答案了: Printing a TDBGrid (4 个回答) 已关闭 6 年前。 如何在不安装或下载组件的情况下打印 DBGrid? 或者 如何将 DBGrid 的数据放入 RichE
我是一名优秀的程序员,十分优秀!