pointNet代码详解

github地址
PointNet 官方使用了 tensorflow

介绍

组成

1.PointNet classification network分类网络

  1. part segmentation network

数据集

1.point clouds sampled from 3D shapes
2.ShapeNetPart dataset.

结构

其主要分成以下三部分:

  • 数据处理
  • model构建
  • 结果选择

数据处理

将点云处理成程序可用的格式,具体实现在 provider.py 中,主要包含了数据下载、预处理(shuffle->rotate->jitter)、格式转换(hdf5->txt)

shuffle

def shuffle_data(data, labels):
    """ Shuffle data and labels.
        Input:
          data: B,N,... numpy array
          label: B,... numpy array
        Return:
          shuffled data, label and shuffle indices
    """
    idx = np.arange(len(labels))#返回一个列表
    # print('idx=',idx)#idx= [   0    1    2 ... 2045 2046 2047]
    np.random.shuffle(idx)#把idx进行shuffle
    # print('idx=', idx)
    return data[idx, ...], labels[idx], idx

rotate旋转处理

def rotate_point_cloud(batch_data):
    # print('batch data shape=',batch_data.shape)#(32, 1024, 3)
    rotated_data = np.zeros(batch_data.shape, dtype=np.float32)
    for k in range(batch_data.shape[0]):
        rotation_angle = np.random.uniform() * 2 * np.pi#生成一个随机数
        cosval = np.cos(rotation_angle)
        sinval = np.sin(rotation_angle)
        rotation_matrix = np.array([[cosval, 0, sinval],
                                    [0, 1, 0],
                                    [-sinval, 0, cosval]])
        shape_pc = batch_data[k, ...]
        rotated_data[k, ...] = np.dot(shape_pc.reshape((-1, 3)), rotation_matrix)
        #先让shape_pc的形状变成(?,3),因为旋转矩阵为(3,3)
    return rotated_data

解析:

>>>rotation_angle = np.random.uniform() * 2 * np.pi
>>> rotation_angle
3.1389077930878955
>>> cos=np.cos(rotation_angle)
>>> sin=np.sin(rotation_angle)
>>> cos
-0.9999963957642077
>>> sin
0.0026848572762735536
>>> matrix=np.array([[cos,0,sin],[0,1,0],[-sin,0,cos]])     >>> matrix
array([[-0.9999964 ,  0.        ,  0.00268486],
       [ 0.        ,  1.        ,  0.        ],
       [-0.00268486,  0.        , -0.9999964 ]])

jitter抖动处理

def jitter_point_cloud(batch_data, sigma=0.01, clip=0.05):
    B, N, C = batch_data.shape
    assert(clip > 0)
    jittered_data = np.clip(sigma * np.random.randn(B, N, C), -1*clip, clip)#将数组范围限制在(-1*clip, clip)
    jittered_data += batch_data
    return jittered_data

model构建

Feature transform net

with tf.variable_scope('transform_net1') as sc:#T-net
    transform = input_transform_net(point_cloud, is_training, bn_decay, K=3)
print('point cloud=',point_cloud)#(32, 1024, 3)
# print('input transform=',transform)#(32, 3, 3)
point_cloud_transformed = tf.matmul(point_cloud, transform)
# print('point_cloud_transformed=',point_cloud_transformed)#(32, 1024, 3)

mlp(64,128,1024)

net = tf_util.conv2d(net_transformed, 64, [1,1],
                         padding='VALID', stride=[1,1],
                         bn=True, is_training=is_training,
                         scope='conv3', bn_decay=bn_decay)
print('net3=',net)#(32, 1024, 1, 64)
net = tf_util.conv2d(net, 128, [1,1],
                         padding='VALID', stride=[1,1],
                         bn=True, is_training=is_training,
                         scope='conv4', bn_decay=bn_decay)
print('net4=',net)#(32, 1024, 1, 128)
net = tf_util.conv2d(net, 1024, [1,1],
                         padding='VALID', stride=[1,1],
                         bn=True, is_training=is_training,
                         scope='conv5', bn_decay=bn_decay)
print('net5=',net)#(32, 1024, 1, 1024)

类别投票

实现方法

batch_pred_sum.shape=(?,40) # 每个data对40个类的可能性

pred_val.shape=(?,) # 每个data所属的可能性最大的类

 pred_val = np.argmax(batch_pred_sum, 1)
 #返回沿轴axis最大值的索引,即得到预测值最大的那一类的idx(label)

argmax()函数详解

例子1:

>>> a=np.arange(12).reshape(2,6)
>>> a
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11]])
>>> np.argmax(a,1)
array([5, 5])   #第五个数数值最大

例子2:

>>> a=np.arange(24).reshape(2,3,4)
>>> a
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])
>>> np.argmax(a,1)
array([[2, 2, 2, 2],
       [2, 2, 2, 2]])
>>> np.argmax(a,1).shape
(2, 4)
                        #[[ 0,  1,  2,  3],
                        # [ 4,  5,  6,  7],
                        # [ 8,  9, 10, 11]]中[ 8,  9, 10, 11]是最大的
>>> np.argmax(a,2)
array([[3, 3, 3],       #[ 0,  1,  2,  3]中[3]是最大的
       [3, 3, 3]])
>>> np.argmax(a,2).shape
(2, 3)

评估

输出(预测label,真实label)

</dump/pred_label.txt>

4, 4    
0, 0
2, 2
8, 8
14, 23
...

<shape_names.txt>

airplane
bathtub
bed
bench
bookshelf
bottle
bowl
car
chair
cone
cup

保存预测错误的图片,并可视化

</dump/xxxx_pred_name.jpg>
命名=第几个预测错误的图片+真实label+预测label

例子 /dump/1028_label_bed_pred_sofa.jpg

image.png

三张点云图片,分别是当前点云数据旋转三个不同角度之后的样子

save code

  for i in range(start_idx, end_idx):
        l = current_label[i]
        total_seen_class[l] += 1
        total_correct_class[l] += (pred_val[i-start_idx] == l)
        fout.write('%d, %d\n' % (pred_val[i-start_idx], l))
        # print('!!!!!!!!!!','%d, %d\n' % (pred_val[i-start_idx], l))
        if pred_val[i-start_idx] != l and FLAGS.visu: # ERROR CASE, DUMP!如果预测错了
            img_filename = '%d_label_%s_pred_%s.jpg' % (error_cnt, SHAPE_NAMES[l],
                                                   SHAPE_NAMES[pred_val[i-start_idx]])
            #第几个预测错误的图片+真实label+预测label
            img_filename = os.path.join(DUMP_DIR, img_filename)
            output_img = pc_util.point_cloud_three_views(np.squeeze(current_data[i, :, :]))
            scipy.misc.imsave(img_filename, output_img)
            error_cnt += 1

画点云图的code

draw_point_cloud()
Input:
points: Nx3 numpy array
Output:
gray image

记录loss,预测精确度

/dump/log_evaluate.txt

eval mean loss: 1.816358
eval accuracy: 0.501216
eval avg class acc: 0.421297
  airplane: 0.980
   bathtub: 0.440
       bed: 0.940
     bench: 0.450
     ...
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容