体素转换为点云(VRN)

前面我们输出的灰度图是没有鼻孔的(只能是上小下大),这里我们把它转换为点云。

流程简图:

体素转换为点云(VRN)_第1张图片
由于保存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。反转面方向

体素转换为点云(VRN)_第2张图片

 结果图就是这样了,好象也没有鼻孔,只有点凹。先这样吧

------------------------------------------分隔线------------------------------------------------------------------------

上图中的这个鼻子太高了,不象中国人,要压缩一半:

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。闭合孔(补上一些小孔)

效果图:

体素转换为点云(VRN)_第3张图片输入图

 

体素转换为点云(VRN)_第4张图片

按一下右边的None显得好看一点

体素转换为点云(VRN)_第5张图片

视频更能看出效果:

体素转换为点云(VRN)_第6张图片

结束。

 

你可能感兴趣的:(杂类)