前面我们输出的灰度图是没有鼻孔的(只能是上小下大),这里我们把它转换为点云。
流程简图:
由于保存192*192*200个点数据比较慢,我们从双线性插值前的48*48*200的数据导出,后面的到C++中处理。
# coding=gbk
from tensorflow.core.framework import graph_pb2
from num_save_mat import K_save_mat
import cv2
import tensorflow as tf
import numpy as np
import time
start_time = time.time()
with open('vrn-unguided-keras.h5.pb', "rb") as f:
output_graph_def = graph_pb2.GraphDef()
output_graph_def.ParseFromString(f.read())
_ = tf.import_graph_def(output_graph_def, name="")
#print(output_graph_def)
end_time = time.time()
print('载入模型用时: %f秒' % (end_time - start_time)) # 23.96
start_time = time.time()
sess = tf.Session()
x = sess.graph.get_tensor_by_name('input_1:0')
y = sess.graph.get_tensor_by_name('conv_276/add:0')
img = cv2.imread('joey.jpg')
img = cv2.resize(img, (192, 192))
b,g,r = cv2.split(img)
img = cv2.merge([r,g,b])
img = np.swapaxes(img, 2, 0)
img = np.swapaxes(img, 2, 1)
img = np.array([img])
out_layer_name='pred0'
pred = sess.run(y, feed_dict={x: img})
vol = pred[0]
end_time = time.time()
print('运行模型用时: %f秒' % (end_time - start_time)) #38.86秒
start_time = time.time()
print(vol.shape)
K_save_mat('vol',vol)
end_time = time.time()
print('保存体素到vol用时: %f秒' % (end_time - start_time)) #3.9秒
然后在C++中处理并转化为点云:
void tmp()
{
int wid=48;
int hei=48;
卷积层 vol(wid,hei,200);//亮度
vol.data=new float[wid * hei*200 ];
load_mat2卷积层2("vol.txt",&vol);
//缩放到 192x192
卷积层 di(192,192,200);
di.data=new float[192*192*200];
双线性插值(vol,di);// 1137
cout<
体素转点云流程:
对每一个点,检查上、下、左、右(前、后(这里没有检测))有空白的点吗?
有则保留(体素表面)。
并转化:x,y,z 坐标值。
就是说只保存体素表面点(去掉内部所有的点)。
void 体素到点云并保存(卷积层 & si)
{
int di=100000;//最多10万个点
int *x=new int[di];
int *y=new int[di];
int *z=new int[di];
int wid=si.width;
int hei=si.height;
int wh=wid*hei;
float *d=si.data;
int n=0;
for (int c=0;c1)
{
//只取边界,上,下,左,右有一个是0
bool b=false;
if (j-1>0) //上
if(d[i*wid+j-1+c*wh]<1)
b=true;
if (b==false)//下
if (j+10)
if(d[(i-1)*wid+j+c*wh]<1)
b=true;
if (b==false)//右
if (i+1100000)
break;
} //end
cout<
保存ply文件(由于只有xyz坐标,保存为xyz文件也是可以的):
void SavePly(char *name,int n,int * x,int * y,int * z,int m=3,bool color=false)
{
FILE *fp1;
int j;
//float * p=p0;
cout<<"保存为: "<
然后把这个ply文件用meshlab打开:
1。计算点集的法线
2。曲面重建:泊松
如果是黑的,
3。反转面方向
结果图就是这样了,好象也没有鼻孔,只有点凹。先这样吧
------------------------------------------分隔线------------------------------------------------------------------------
上图中的这个鼻子太高了,不象中国人,要压缩一半:
z[n]=c/2; //压缩一半
下面给点云上色,由于体素本来就是和输入图的点对齐的,我们只要把该位置的颜色给该点就可以了。
修改函数“体素到点云并保存”:
void 体素到点云并保存(卷积层 & si)
{
...省略同上
cout<
上色函数:
void 体素上色并保存(int n,int * x,int * y,int * z)
{
Resizeloadjpg("joey.jpg");//载入输入图
卷积层 rgb(192,192,3);
rgb.data=new float[192*192*3];
bmp2RGB(rgb);
float *d=rgb.data;
int wh = 192*192;
int *r=new int[n];
int *g=new int[n];
int *b=new int[n];
int *r0=r;
int *g0=g;
int *b0=b;
int *x0=x;
int *y0=y;
int c;
for (int j=0;j
保存有色点云:
void SavePly(char *name,int n,int * x,int * y,int * z,int * r,int * g,int * b,int m=6,bool color=true)
{
FILE *fp1;
int j;
cout<<"保存为: "<
还是用meshlab把这个ply文件打开:
把稍稍把点调大一点就可以看到颜色了,会比较暗,点右边"None"会亮起来,
或者
1。计算点集的法线(先去掉外围多余的点,会影响点的方向)也会亮起来
2。曲面重建:滚球法。
3。闭合孔(补上一些小孔)
效果图:
按一下右边的None显得好看一点
视频更能看出效果:
结束。