コード例 #1
0
def sample_and_group(npoint, radius, nsample, xyz, points, knn=False, use_xyz=True):
    '''
    Input:
        npoint: int32
        radius: float32
        nsample: int32
        xyz: (batch_size, ndataset, 3) TF tensor
        points: (batch_size, ndataset, channel) TF tensor, if None will just use xyz as points
        knn: bool, if True use kNN instead of radius search
        use_xyz: bool, if True concat XYZ with local point features, otherwise just use point features
    Output:
        new_xyz: (batch_size, npoint, 3) TF tensor
        new_points: (batch_size, npoint, nsample, 3+channel) TF tensor
        idx: (batch_size, npoint, nsample) TF tensor, indices of local points as in ndataset points
        grouped_xyz: (batch_size, npoint, nsample, 3) TF tensor, normalized point XYZs
            (subtracted by seed point XYZ) in local regions
    '''

    new_xyz = gather_point(xyz, farthest_point_sample(npoint, xyz))  # (batch_size, npoint, 3)
    if knn:
        _, idx = knn_point(nsample, xyz, new_xyz)
    else:
        idx, pts_cnt = query_ball_point(radius, nsample, xyz, new_xyz)
    grouped_xyz = group_point(xyz, idx)  # (batch_size, npoint, nsample, 3)
    grouped_xyz -= tf.tile(tf.expand_dims(new_xyz, 2), [1, 1, nsample, 1])  # translation normalization
    if points is not None:
        grouped_points = group_point(points, idx)  # (batch_size, npoint, nsample, channel)
        if use_xyz:
            new_points = tf.concat([grouped_xyz, grouped_points], axis=-1)  # (batch_size, npoint, nample, 3+channel)
        else:
            new_points = grouped_points
    else:
        new_points = grouped_xyz

    return new_xyz, new_points, idx, grouped_xyz
コード例 #2
0
    def __init__(self, points, features, num_class, is_training, setting,
                 task):
        xconv_params = setting.xconv_params
        fc_params = setting.fc_params
        with_X_transformation = setting.with_X_transformation
        sorting_method = setting.sorting_method
        N = tf.shape(points)[0]

        if setting.with_fps:
            from sampling import tf_sampling

        self.layer_pts = [points]
        if features is None:
            self.layer_fts = [features]
        else:
            C_fts = xconv_params[0][-1] // 2
            features_hd = pf.dense(features, C_fts, 'features_hd', is_training)
            self.layer_fts = [features_hd]

        for layer_idx, layer_param in enumerate(xconv_params):
            tag = 'xconv_' + str(layer_idx + 1) + '_'
            K, D, P, C = layer_param

            # get k-nearest points
            pts = self.layer_pts[-1]
            fts = self.layer_fts[-1]
            if P == -1:
                qrs = points
            else:
                if setting.with_fps:
                    qrs = tf_sampling.gather_point(
                        pts, tf_sampling.farthest_point_sample(P,
                                                               pts))  # (N,P,3)
                else:
                    qrs = tf.slice(pts, (0, 0, 0), (-1, P, -1),
                                   name=tag + 'qrs')  # (N, P, 3)
            self.layer_pts.append(qrs)

            if layer_idx == 0:
                C_pts_fts = C // 2 if fts is None else C // 4
                depth_multiplier = 4
            else:
                C_prev = xconv_params[layer_idx - 1][-1]
                C_pts_fts = C_prev // 4
                depth_multiplier = math.ceil(C / C_prev)
            fts_xconv = xconv(pts, fts, qrs, tag, N, K, D, P, C, C_pts_fts,
                              is_training, with_X_transformation,
                              depth_multiplier, sorting_method)
            self.layer_fts.append(fts_xconv)

        if task == 'segmentation':
            for layer_idx, layer_param in enumerate(setting.xdconv_params):
                tag = 'xdconv_' + str(layer_idx + 1) + '_'
                K, D, pts_layer_idx, qrs_layer_idx = layer_param

                pts = self.layer_pts[pts_layer_idx + 1]
                fts = self.layer_fts[
                    pts_layer_idx +
                    1] if layer_idx == 0 else self.layer_fts[-1]
                qrs = self.layer_pts[qrs_layer_idx + 1]
                fts_qrs = self.layer_fts[qrs_layer_idx + 1]
                _, _, P, C = xconv_params[qrs_layer_idx]
                _, _, _, C_prev = xconv_params[pts_layer_idx]
                C_pts_fts = C_prev // 4
                depth_multiplier = 1
                fts_xdconv = xconv(pts, fts, qrs, tag, N, K, D, P, C,
                                   C_pts_fts, is_training,
                                   with_X_transformation, depth_multiplier,
                                   sorting_method)
                fts_concat = tf.concat([fts_xdconv, fts_qrs],
                                       axis=-1,
                                       name=tag + 'fts_concat')
                fts_fuse = pf.dense(fts_concat, C, tag + 'fts_fuse',
                                    is_training)
                self.layer_pts.append(qrs)
                self.layer_fts.append(fts_fuse)

        self.fc_layers = [self.layer_fts[-1]]
        for layer_idx, layer_param in enumerate(fc_params):
            channel_num, drop_rate = layer_param
            fc = pf.dense(self.fc_layers[-1], channel_num,
                          'fc{:d}'.format(layer_idx), is_training)
            fc_drop = tf.layers.dropout(fc,
                                        drop_rate,
                                        training=is_training,
                                        name='fc{:d}_drop'.format(layer_idx))
            self.fc_layers.append(fc_drop)

        logits = pf.dense(self.fc_layers[-1],
                          num_class,
                          'logits',
                          is_training,
                          with_bn=False,
                          activation=None)
        if task == 'classification':
            logits_mean = tf.reduce_mean(logits,
                                         axis=1,
                                         keep_dims=True,
                                         name='logits_mean')
            self.logits = tf.cond(is_training, lambda: logits,
                                  lambda: logits_mean)
        elif task == 'segmentation':
            self.logits = logits
        else:
            print('Unknown task!')
            exit()
        self.probs = tf.nn.softmax(self.logits, name='probs')
コード例 #3
0
ファイル: pointcnn.py プロジェクト: tthhee/PointCNN
    def __init__(self, points, features, is_training, setting):
        xconv_params = setting.xconv_params
        fc_params = setting.fc_params
        with_X_transformation = setting.with_X_transformation
        sorting_method = setting.sorting_method
        N = tf.shape(points)[0]

        if setting.sampling == 'fps':
            from sampling import tf_sampling

        self.layer_pts = [points]
        if features is None:
            self.layer_fts = [features]
        else:
            # expand feature dimentions
            features = tf.reshape(features, (N, -1, setting.data_dim - 3),
                                  name='features_reshape')
            C_fts = xconv_params[0]['C'] // 2
            features_hd = pf.dense(features, C_fts, 'features_hd', is_training)
            self.layer_fts = [features_hd]

        for layer_idx, layer_param in enumerate(xconv_params):
            tag = 'xconv_' + str(layer_idx + 1) + '_'
            K = layer_param['K']  # neighborhood size
            D = layer_param['D']  # dilate rate
            P = layer_param['P']  # representative point number
            C = layer_param['C']  # output channel number
            links = layer_param[
                'links']  # e.g. [-1,-2] will tell the current layer to receive inputs from the previous two layers
            if setting.sampling != 'random' and links:
                print(
                    'Error: flexible links are supported only when random sampling is used!'
                )
                exit()

            # get k-nearest points
            pts = self.layer_pts[-1]  # get the end one in list (last layer)
            fts = self.layer_fts[-1]
            # if P == -1 or p equals to last layer's p , than no sampling
            if P == -1 or (layer_idx > 0
                           and P == xconv_params[layer_idx - 1]['P']):
                qrs = self.layer_pts[-1]
            else:
                # for segmentation task
                if setting.sampling == 'fps':
                    # fps_indices: [[0_0, 0_1, ...., 0_P-1], ...., [N-1_0, N-1_1, ...., N-1_P-1]]   (NxP)
                    fps_indices = tf_sampling.farthest_point_sample(P, pts)
                    # replicating a index(0...N) for each output poit(P) -> (N, P, 1)
                    # batch_indices: [[[0],[0],...,[0]], ..., [[N-1],[N-1],...,[N-1]]]
                    batch_indices = tf.tile(
                        tf.reshape(tf.range(N), (-1, 1, 1)), (1, P, 1))
                    # tf.expand_dims(fps_indices, -1): [[[0_0], [0_1], ..., [0_P-1]], ... , [[N-1_0], [N-1_1], ... , [N-1_P-1]]]
                    # indices: [[[0, 0_0], [0, 0_1], ..., [0, 0_P-1]], ..., [[N-1, N-1_0], [N-1, N-1_1], ... , [N-1, N-1_P-1]]]
                    indices = tf.concat(
                        [batch_indices,
                         tf.expand_dims(fps_indices, -1)],
                        axis=-1)
                    qrs = tf.gather_nd(pts, indices,
                                       name=tag + 'qrs')  # (N, P, 3)
                elif setting.sampling == 'ids':
                    indices = pf.inverse_density_sampling(pts, K, P)
                    qrs = tf.gather_nd(pts, indices)
                # for classification tasks
                elif setting.sampling == 'random':
                    qrs = tf.slice(pts, (0, 0, 0), (-1, P, -1),
                                   name=tag + 'qrs')  # (N, P, 3)
                else:
                    print('Unknown sampling method!')
                    exit()
            self.layer_pts.append(qrs)

            if layer_idx == 0:
                # lift each point coordinates into C_pts_fts dimensional space
                C_pts_fts = C // 2 if fts is None else C // 4
                depth_multiplier = 4
            else:
                C_prev = xconv_params[layer_idx - 1]['C']
                C_pts_fts = C_prev // 4
                depth_multiplier = math.ceil(C / C_prev)
            # with global feature at last layer
            with_global = (setting.with_global
                           and layer_idx == len(xconv_params) - 1)
            fts_xconv = xconv(pts, fts, qrs, tag, N, K, D, P, C, C_pts_fts,
                              is_training, with_X_transformation,
                              depth_multiplier, sorting_method, with_global)
            fts_list = []
            # receive inputs from previous layers
            for link in links:
                fts_from_link = self.layer_fts[link]
                if fts_from_link is not None:
                    fts_slice = tf.slice(fts_from_link, (0, 0, 0), (-1, P, -1),
                                         name=tag + 'fts_slice_' + str(-link))
                    fts_list.append(fts_slice)
            if fts_list:
                fts_list.append(fts_xconv)
                self.layer_fts.append(
                    tf.concat(fts_list, axis=-1, name=tag + 'fts_list_concat'))
            else:
                self.layer_fts.append(fts_xconv)

        if hasattr(setting, 'xdconv_params'):
            for layer_idx, layer_param in enumerate(setting.xdconv_params):
                tag = 'xdconv_' + str(layer_idx + 1) + '_'
                K = layer_param['K']
                D = layer_param['D']
                pts_layer_idx = layer_param['pts_layer_idx']
                qrs_layer_idx = layer_param['qrs_layer_idx']

                pts = self.layer_pts[pts_layer_idx + 1]
                fts = self.layer_fts[
                    pts_layer_idx +
                    1] if layer_idx == 0 else self.layer_fts[-1]
                qrs = self.layer_pts[qrs_layer_idx + 1]
                fts_qrs = self.layer_fts[qrs_layer_idx + 1]
                P = xconv_params[qrs_layer_idx]['P']
                C = xconv_params[qrs_layer_idx]['C']
                C_prev = xconv_params[pts_layer_idx]['C']
                C_pts_fts = C_prev // 4
                depth_multiplier = 1
                fts_xdconv = xconv(pts, fts, qrs, tag, N, K, D, P, C,
                                   C_pts_fts, is_training,
                                   with_X_transformation, depth_multiplier,
                                   sorting_method)
                fts_concat = tf.concat([fts_xdconv, fts_qrs],
                                       axis=-1,
                                       name=tag + 'fts_concat')
                fts_fuse = pf.dense(fts_concat, C, tag + 'fts_fuse',
                                    is_training)
                self.layer_pts.append(qrs)
                self.layer_fts.append(fts_fuse)

        self.fc_layers = [self.layer_fts[-1]]
        for layer_idx, layer_param in enumerate(fc_params):
            C = layer_param['C']
            dropout_rate = layer_param['dropout_rate']
            fc = pf.dense(self.fc_layers[-1], C, 'fc{:d}'.format(layer_idx),
                          is_training)
            fc_drop = tf.layers.dropout(fc,
                                        dropout_rate,
                                        training=is_training,
                                        name='fc{:d}_drop'.format(layer_idx))
            self.fc_layers.append(fc_drop)
コード例 #4
0
    def __init__(self, points, features, is_training, setting):
        xconv_params = setting.xconv_params
        fc_params = setting.fc_params
        with_X_transformation = setting.with_X_transformation
        sorting_method = setting.sorting_method
        N = tf.shape(points)[0]

        if setting.sampling == 'fps':
            import sys
            #sys.path.append("/home/hasan/data/paper2/PointCNN/")
            from sampling import tf_sampling

        self.layer_pts = [points]
        if features is None:
            self.layer_fts = [features]
        else:
            features = tf.reshape(features, (N, -1, setting.data_dim - 3),
                                  name='features_reshape')
            C_fts = xconv_params[0]['C'] // 2
            features_hd = pf.dense(features, C_fts, 'features_hd', is_training)
            self.layer_fts = [features_hd]

        for layer_idx, layer_param in enumerate(xconv_params):
            tag = 'xconv_' + str(layer_idx + 1) + '_'
            K = layer_param['K']
            D = layer_param['D']
            P = layer_param['P']
            C = layer_param['C']
            links = layer_param['links']
            if setting.sampling != 'random' and links:
                print(
                    'Error: flexible links are supported only when random sampling is used!'
                )
                exit()

            # get k-nearest points
            pts = self.layer_pts[-1]
            fts = self.layer_fts[-1]
            if P == -1 or (layer_idx > 0
                           and P == xconv_params[layer_idx - 1]['P']):
                qrs = self.layer_pts[-1]
            else:
                if setting.sampling == 'fps':
                    fps_indices = tf_sampling.farthest_point_sample(P, pts)
                    batch_indices = tf.tile(
                        tf.reshape(tf.range(N), (-1, 1, 1)), (1, P, 1))
                    indices = tf.concat(
                        [batch_indices,
                         tf.expand_dims(fps_indices, -1)],
                        axis=-1)
                    qrs = tf.gather_nd(pts, indices,
                                       name=tag + 'qrs')  # (N, P, 3)
                elif setting.sampling == 'ids':
                    indices = pf.inverse_density_sampling(pts, K, P)
                    qrs = tf.gather_nd(pts, indices)
                elif setting.sampling == 'random':
                    qrs = tf.slice(pts, (0, 0, 0), (-1, P, -1),
                                   name=tag + 'qrs')  # (N, P, 3)
                else:
                    print('Unknown sampling method!')
                    exit()
            self.layer_pts.append(qrs)

            if layer_idx == 0:
                C_pts_fts = C // 2 if fts is None else C // 4
                depth_multiplier = 4
            else:
                C_prev = xconv_params[layer_idx - 1]['C']
                C_pts_fts = C_prev // 4
                depth_multiplier = math.ceil(C / C_prev)
            with_global = (setting.with_global
                           and layer_idx == len(xconv_params) - 1)
            fts_xconv = xconv(pts, fts, qrs, tag, N, K, D, P, C, C_pts_fts,
                              is_training, with_X_transformation,
                              depth_multiplier, sorting_method, with_global)
            fts_list = []
            for link in links:
                fts_from_link = self.layer_fts[link]
                if fts_from_link is not None:
                    fts_slice = tf.slice(fts_from_link, (0, 0, 0), (-1, P, -1),
                                         name=tag + 'fts_slice_' + str(-link))
                    fts_list.append(fts_slice)
            if fts_list:
                fts_list.append(fts_xconv)
                self.layer_fts.append(
                    tf.concat(fts_list, axis=-1, name=tag + 'fts_list_concat'))
            else:
                self.layer_fts.append(fts_xconv)

        if hasattr(setting, 'xdconv_params'):
            for layer_idx, layer_param in enumerate(setting.xdconv_params):
                tag = 'xdconv_' + str(layer_idx + 1) + '_'
                K = layer_param['K']
                D = layer_param['D']
                pts_layer_idx = layer_param['pts_layer_idx']
                qrs_layer_idx = layer_param['qrs_layer_idx']

                pts = self.layer_pts[pts_layer_idx + 1]
                fts = self.layer_fts[
                    pts_layer_idx +
                    1] if layer_idx == 0 else self.layer_fts[-1]
                qrs = self.layer_pts[qrs_layer_idx + 1]
                fts_qrs = self.layer_fts[qrs_layer_idx + 1]
                P = xconv_params[qrs_layer_idx]['P']
                C = xconv_params[qrs_layer_idx]['C']
                C_prev = xconv_params[pts_layer_idx]['C']
                C_pts_fts = C_prev // 4
                depth_multiplier = 1
                fts_xdconv = xconv(pts, fts, qrs, tag, N, K, D, P, C,
                                   C_pts_fts, is_training,
                                   with_X_transformation, depth_multiplier,
                                   sorting_method)
                fts_concat = tf.concat([fts_xdconv, fts_qrs],
                                       axis=-1,
                                       name=tag + 'fts_concat')
                fts_fuse = pf.dense(fts_concat, C, tag + 'fts_fuse',
                                    is_training)
                self.layer_pts.append(qrs)
                self.layer_fts.append(fts_fuse)

        self.fc_layers = [self.layer_fts[-1]]
        for layer_idx, layer_param in enumerate(fc_params):
            C = layer_param['C']
            dropout_rate = layer_param['dropout_rate']
            fc = pf.dense(self.fc_layers[-1], C, 'fc{:d}'.format(layer_idx),
                          is_training)
            fc_drop = tf.layers.dropout(fc,
                                        dropout_rate,
                                        training=is_training,
                                        name='fc{:d}_drop'.format(layer_idx))
            self.fc_layers.append(fc_drop)
コード例 #5
0
    def __init__(self, points, features, num_class, is_training, setting, task):
        xconv_params = setting.xconv_params
        fc_params = setting.fc_params
        with_X_transformation = setting.with_X_transformation
        sorting_method = setting.sorting_method
        N = tf.shape(points)[0]

        if setting.sampling == 'fps':
            from sampling import tf_sampling

        self.layer_pts = [points]
        if features is None:
            self.layer_fts = [features]
        else:
            C_fts = xconv_params[0]['C'] // 2
            features_hd = pf.dense(features, C_fts, 'features_hd', is_training)
            self.layer_fts = [features_hd]

        for layer_idx, layer_param in enumerate(xconv_params):
            tag = 'xconv_' + str(layer_idx + 1) + '_'
            K = layer_param['K']
            D = layer_param['D']
            P = layer_param['P']
            C = layer_param['C']
            links = layer_param['links']
            if setting.sampling != 'random' and links:
                print('Error: flexible links are supported only when random sampling is used!')
                exit()

            # get k-nearest points
            pts = self.layer_pts[-1]
            fts = self.layer_fts[-1]
            if P == -1 or (layer_idx > 0 and P == xconv_params[layer_idx - 1]['P']):
                qrs = self.layer_pts[-1]
            else:
                if setting.sampling == 'fps':
                    indices = tf_sampling.farthest_point_sample(P, pts)
                    qrs = tf_sampling.gather_point(pts, indices)  # (N,P,3)
                elif setting.sampling == 'ids':
                    indices = pf.inverse_density_sampling(pts, K, P)
                    qrs = tf.gather_nd(pts, indices)
                elif setting.sampling == 'random':
                    qrs = tf.slice(pts, (0, 0, 0), (-1, P, -1), name=tag + 'qrs')  # (N, P, 3)
                else:
                    print('Unknown sampling method!')
                    exit()
            self.layer_pts.append(qrs)

            if layer_idx == 0:
                C_pts_fts = C // 2 if fts is None else C // 4
                depth_multiplier = 4
            else:
                C_prev = xconv_params[layer_idx - 1]['C']
                C_pts_fts = C_prev // 4
                depth_multiplier = math.ceil(C / C_prev)
            fts_xconv = xconv(pts, fts, qrs, tag, N, K, D, P, C, C_pts_fts, is_training, with_X_transformation,
                              depth_multiplier, sorting_method, layer_idx != len(xconv_params) - 1)
            fts_list = []
            for link in links:
                fts_from_link = self.layer_fts[link]
                if fts_from_link is not None:
                    fts_slice = tf.slice(fts_from_link, (0, 0, 0), (-1, P, -1),
                                         name=tag + 'fts_slice_' + str(-link))
                    C_forward = math.ceil(fts_slice.get_shape().as_list()[-1] / (-link))
                    fts_forward = pf.dense(fts_slice, C_forward, tag + 'fts_forward_' + str(-link), is_training)
                    fts_list.append(fts_forward)
            if fts_list:
                fts_list.append(fts_xconv)
                self.layer_fts.append(tf.concat(fts_list, axis=-1, name=tag + 'fts_list_concat'))
            else:
                self.layer_fts.append(fts_xconv)

        if task == 'segmentation':
            for layer_idx, layer_param in enumerate(setting.xdconv_params):
                tag = 'xdconv_' + str(layer_idx + 1) + '_'
                K = layer_param['K']
                D = layer_param['D']
                pts_layer_idx = layer_param['pts_layer_idx']
                qrs_layer_idx = layer_param['qrs_layer_idx']

                pts = self.layer_pts[pts_layer_idx + 1]
                fts = self.layer_fts[pts_layer_idx + 1] if layer_idx == 0 else self.layer_fts[-1]
                qrs = self.layer_pts[qrs_layer_idx + 1]
                fts_qrs = self.layer_fts[qrs_layer_idx + 1]
                P = xconv_params[qrs_layer_idx]['P']
                C = xconv_params[qrs_layer_idx]['C']
                C_prev = xconv_params[pts_layer_idx]['C']
                C_pts_fts = C_prev // 4
                depth_multiplier = 1
                fts_xdconv = xconv(pts, fts, qrs, tag, N, K, D, P, C, C_pts_fts, is_training, with_X_transformation,
                                   depth_multiplier, sorting_method)
                fts_concat = tf.concat([fts_xdconv, fts_qrs], axis=-1, name=tag + 'fts_concat')
                fts_fuse = pf.dense(fts_concat, C, tag + 'fts_fuse', is_training)
                self.layer_pts.append(qrs)
                self.layer_fts.append(fts_fuse)

        self.fc_layers = [self.layer_fts[-1]]
        for layer_idx, layer_param in enumerate(fc_params):
            C = layer_param['C']
            dropout_rate = layer_param['dropout_rate']
            fc = pf.dense(self.fc_layers[-1], C, 'fc{:d}'.format(layer_idx), is_training)
            fc_drop = tf.layers.dropout(fc, dropout_rate, training=is_training, name='fc{:d}_drop'.format(layer_idx))
            self.fc_layers.append(fc_drop)

        if task == 'classification':
            fc_mean = tf.reduce_mean(self.fc_layers[-1], axis=1, keep_dims=True, name='fc_mean')
            self.fc_layers[-1] = tf.cond(is_training, lambda: self.fc_layers[-1], lambda: fc_mean)

        self.logits = pf.dense(self.fc_layers[-1], num_class, 'logits', is_training, with_bn=False, activation=None)
        self.probs = tf.nn.softmax(self.logits, name='probs')
コード例 #6
0
ファイル: pointcnn_kitti.py プロジェクト: jtpils/BDCI2018
    def __init__(self, points, features, images, image_xy, num_class,
                 is_training, setting, task):

        print("points:", points)
        print("features:", features)

        xconv_params = setting.xconv_params
        print("xconv_params:", xconv_params)

        fc_params = setting.fc_params
        print("fc_params:", fc_params)

        with_X_transformation = setting.with_X_transformation
        sorting_method = setting.sorting_method

        N = tf.shape(points)[0]
        point_num = tf.shape(points)[1]

        if setting.with_fps:
            from sampling import tf_sampling

        self.layer_pts = [points]

        if features is None:
            self.layer_fts = [features]
        else:
            C_fts = xconv_params[0][-1] // 2
            features_hd = pf.dense(features, C_fts, 'features_hd', is_training)
            self.layer_fts = [features_hd]

        for layer_idx, layer_param in enumerate(xconv_params):

            tag = 'xconv_' + str(layer_idx + 1) + '_'
            K, D, P, C = layer_param

            fts = self.layer_fts[-1]

            # get k centroid points
            pts = self.layer_pts[-1]

            if P == -1:
                qrs = self.layer_pts[-1]
            else:
                if setting.with_fps:
                    fps_indices = tf_sampling.farthest_point_sample(P, pts)
                    batch_indices = tf.tile(
                        tf.reshape(tf.range(N), (-1, 1, 1)), (1, P, 1))
                    fps_indices_g = tf.concat(
                        [batch_indices,
                         tf.expand_dims(fps_indices, -1)],
                        axis=-1)
                    qrs = tf.gather_nd(pts, fps_indices_g,
                                       name=tag + 'qrs')  # (N, P, 3)
                else:
                    qrs = tf.slice(pts, (0, 0, 0), (-1, P, -1),
                                   name=tag + 'qrs')  # (N, P, 3)

            self.layer_pts.append(qrs)

            if layer_idx == 0:
                C_pts_fts = C // 2 if fts is None else C // 4
                depth_multiplier = 4
            else:
                C_prev = xconv_params[layer_idx - 1][-1]
                C_pts_fts = C_prev // 4
                depth_multiplier = math.ceil(C / C_prev)

            fts_xconv = xconv(pts, fts, qrs, tag, N, K, D, P, C, C_pts_fts,
                              is_training, with_X_transformation,
                              depth_multiplier, sorting_method)
            self.layer_fts.append(fts_xconv)

        if task == 'segmentation':
            for layer_idx, layer_param in enumerate(setting.xdconv_params):
                tag = 'xdconv_' + str(layer_idx + 1) + '_'
                K, D, pts_layer_idx, qrs_layer_idx = layer_param

                pts = self.layer_pts[pts_layer_idx + 1]
                fts = self.layer_fts[
                    pts_layer_idx +
                    1] if layer_idx == 0 else self.layer_fts[-1]
                qrs = self.layer_pts[qrs_layer_idx + 1]
                fts_qrs = self.layer_fts[qrs_layer_idx + 1]
                _, _, P, C = xconv_params[qrs_layer_idx]

                C_pts_fts = C_prev // 4
                depth_multiplier = 1
                fts_xdconv = xconv(pts, fts, qrs, tag, N, K, D, P, C,
                                   C_pts_fts, is_training,
                                   with_X_transformation, depth_multiplier,
                                   sorting_method)
                fts_concat = tf.concat([fts_xdconv, fts_qrs],
                                       axis=-1,
                                       name=tag + 'fts_concat')
                fts_fuse = pf.dense(fts_concat, C, tag + 'fts_fuse',
                                    is_training)
                self.layer_pts.append(qrs)
                self.layer_fts.append(fts_fuse)

        self.fc_layers = [self.layer_fts[-1]]
        for layer_idx, layer_param in enumerate(fc_params):
            channel_num, drop_rate = layer_param
            fc = pf.dense(self.fc_layers[-1], channel_num,
                          'fc{:d}'.format(layer_idx), is_training)
            fc_drop = tf.layers.dropout(fc,
                                        drop_rate,
                                        training=is_training,
                                        name='fc{:d}_drop'.format(layer_idx))
            self.fc_layers.append(fc_drop)

        if task == 'classification':
            fc_mean = tf.reduce_mean(self.fc_layers[-1],
                                     axis=1,
                                     keep_dims=True,
                                     name='fc_mean')
            self.fc_layers[-1] = tf.cond(is_training,
                                         lambda: self.fc_layers[-1],
                                         lambda: fc_mean)

        self.logits = pf.dense(self.fc_layers[-1],
                               num_class,
                               'logits',
                               is_training,
                               with_bn=False,
                               activation=None)
        self.probs = tf.nn.softmax(self.logits, name='probs')
コード例 #7
0
    def __init__(self, points, features, images, image_xy, num_class,
                 is_training, setting, task):

        print("points:", points)
        print("features:", features)

        xconv_params = setting.xconv_params
        print("xconv_params:", xconv_params)

        fc_params = setting.fc_params
        print("fc_params:", fc_params)

        # 从配置文件中获取后续分支的参数
        extra_branch_xconv_params = setting.extra_branch_xconv_params
        extra_branch_fc_params = setting.extra_branch_fc_params
        mask_sample_num = setting.mask_sample_num

        with_X_transformation = setting.with_X_transformation
        sorting_method = setting.sorting_method

        N = tf.shape(points)[0]
        point_num = tf.shape(points)[1]

        if setting.with_fps:
            from sampling import tf_sampling

        self.layer_pts = [points]

        if features is None:
            self.layer_fts = [features]
        else:
            C_fts = xconv_params[0][-1] // 2
            features_hd = pf.dense(features, C_fts, 'features_hd', is_training)
            self.layer_fts = [features_hd]

        for layer_idx, layer_param in enumerate(xconv_params):

            tag = 'xconv_' + str(layer_idx + 1) + '_'
            K, D, P, C = layer_param

            fts = self.layer_fts[-1]

            # get k centroid points
            pts = self.layer_pts[-1]

            if P == -1:
                qrs = self.layer_pts[-1]
            else:
                if setting.with_fps:
                    fps_indices = tf_sampling.farthest_point_sample(P, pts)
                    batch_indices = tf.tile(
                        tf.reshape(tf.range(N), (-1, 1, 1)), (1, P, 1))
                    fps_indices_g = tf.concat(
                        [batch_indices,
                         tf.expand_dims(fps_indices, -1)],
                        axis=-1)
                    qrs = tf.gather_nd(pts, fps_indices_g,
                                       name=tag + 'qrs')  # (N, P, 3)
                else:
                    qrs = tf.slice(pts, (0, 0, 0), (-1, P, -1),
                                   name=tag + 'qrs')  # (N, P, 3)

            self.layer_pts.append(qrs)

            if layer_idx == 0:
                C_pts_fts = C // 2 if fts is None else C // 4
                depth_multiplier = 4
            else:
                C_prev = xconv_params[layer_idx - 1][-1]
                C_pts_fts = C_prev // 4
                depth_multiplier = math.ceil(C / C_prev)

            fts_xconv = xconv(pts, fts, qrs, tag, N, K, D, P, C, C_pts_fts,
                              is_training, with_X_transformation,
                              depth_multiplier, sorting_method, False)
            self.layer_fts.append(fts_xconv)

        if task == 'segmentation':
            for layer_idx, layer_param in enumerate(setting.xdconv_params):
                tag = 'xdconv_' + str(layer_idx + 1) + '_'
                K, D, pts_layer_idx, qrs_layer_idx = layer_param

                pts = self.layer_pts[pts_layer_idx + 1]
                fts = self.layer_fts[
                    pts_layer_idx +
                    1] if layer_idx == 0 else self.layer_fts[-1]
                qrs = self.layer_pts[qrs_layer_idx + 1]
                fts_qrs = self.layer_fts[qrs_layer_idx + 1]
                _, _, P, C = xconv_params[qrs_layer_idx]

                C_pts_fts = C_prev // 4
                depth_multiplier = 1
                fts_xdconv = xconv(pts, fts, qrs, tag, N, K, D, P, C,
                                   C_pts_fts, is_training,
                                   with_X_transformation, depth_multiplier,
                                   sorting_method)
                fts_concat = tf.concat([fts_xdconv, fts_qrs],
                                       axis=-1,
                                       name=tag + 'fts_concat')
                fts_fuse = pf.dense(fts_concat, C, tag + 'fts_fuse',
                                    is_training)
                self.layer_pts.append(qrs)
                self.layer_fts.append(fts_fuse)

        self.fc_layers = [self.layer_fts[-1]]
        for layer_idx, layer_param in enumerate(fc_params):
            channel_num, drop_rate = layer_param
            fc = pf.dense(self.fc_layers[-1], channel_num,
                          'fc{:d}'.format(layer_idx), is_training)
            fc_drop = tf.layers.dropout(fc,
                                        drop_rate,
                                        training=is_training,
                                        name='fc{:d}_drop'.format(layer_idx))
            self.fc_layers.append(fc_drop)

        if task == 'classification':
            fc_mean = tf.reduce_mean(self.fc_layers[-1],
                                     axis=1,
                                     keep_dims=True,
                                     name='fc_mean')
            self.fc_layers[-1] = tf.cond(is_training,
                                         lambda: self.fc_layers[-1],
                                         lambda: fc_mean)

        self.logits = pf.dense(self.fc_layers[-1],
                               num_class,
                               'logits',
                               is_training,
                               with_bn=False,
                               activation=None)
        self.probs = tf.nn.softmax(self.logits, name='probs')

        # 从分割结果获取Mask点云(车辆点云)
        probs_others = tf.slice(self.probs, [0, 0, 0], [N, point_num, 1])
        probs_instance = tf.slice(self.probs, [0, 0, 1], [N, point_num, 1])
        hold_sub_mask = tf.subtract(probs_instance,
                                    probs_others,
                                    name="hold_sub_mask")
        indices_mask = tf.py_func(pf.instance_choice,
                                  [hold_sub_mask, mask_sample_num], tf.int32)
        indices_mask.set_shape(
            [hold_sub_mask.get_shape()[0], mask_sample_num, 2])
        points_mask = tf.gather_nd(points, indices_mask, name='points_mask')

        # 计算mask点云重心
        if setting.with_xyz_res:
            points_mask_mean = tf.reduce_mean(points_mask,
                                              axis=-2,
                                              keep_dims=True,
                                              name='points_mask_mean')
            points_mask_mean_sq = tf.squeeze(points_mask_mean,
                                             name='points_mask_mean_sq')
            points_mask_centroid = tf.subtract(points_mask,
                                               points_mask_mean,
                                               name='points_mask_centroid')
            eb_pts = points_mask_centroid
        else:
            eb_pts = points_mask
        # 获取mask点云特征
        if features is None:
            features_mask_hd = None
        else:
            C_fts = extra_branch_xconv_params[0][-1] // 2
            features_mask = tf.gather_nd(features,
                                         indices_mask,
                                         name='features_mask')
            mask_features_hd = pf.dense(features_mask, C_fts,
                                        'mask_features_hd', is_training)
        eb_fts = mask_features_hd

        # Bbox分支(尺寸与位置分支)
        self.bbox_layer_fts = [eb_fts]
        self.bbox_layer_pts = [eb_pts]
        for layer_idx, layer_param in enumerate(extra_branch_xconv_params):
            tag = 'bbox_branch_xconv_' + str(layer_idx + 1) + '_'
            K, D, P, C = layer_param
            pts = self.bbox_layer_pts[-1]
            fts = self.bbox_layer_fts[-1]
            # get centroid points
            if P == -1:
                qrs = eb_pts
            else:
                if setting.eb_with_fps:
                    fps_indices = tf_sampling.farthest_point_sample(P, pts)
                    batch_indices = tf.tile(
                        tf.reshape(tf.range(N), (-1, 1, 1)), (1, P, 1))
                    fps_indices_g = tf.concat(
                        [batch_indices,
                         tf.expand_dims(fps_indices, -1)],
                        axis=-1)
                    qrs = tf.gather_nd(pts, fps_indices_g,
                                       name=tag + 'qrs')  # (N, P, 3)
                else:
                    qrs = tf.slice(pts, (0, 0, 0), (-1, P, -1),
                                   name=tag + 'qrs')  # (N, P, 3)
            self.bbox_layer_pts.append(qrs)
            if layer_idx == 0:
                C_pts_fts = C // 2 if fts is None else C // 4
                depth_multiplier = 4
            else:
                C_prev = xconv_params[layer_idx - 1][-1]
                C_pts_fts = C_prev // 4
                depth_multiplier = math.ceil(C / C_prev)
            fts_xconv = xconv(pts, fts, qrs, tag, N, K, D, P, C, C_pts_fts,
                              is_training, with_X_transformation,
                              depth_multiplier, sorting_method, False)
            self.bbox_layer_fts.append(fts_xconv)

        # HWL 预测分支 以用maxpooling特征进行预测为例
        self.hwl_fc_layers = [
            tf.reduce_max(self.bbox_layer_fts[-1], axis=1, name='hwl_fts_max')
        ]
        for layer_idx, layer_param in enumerate(extra_branch_fc_params):
            channel_num, drop_rate = layer_param
            fc = pf.dense(self.hwl_fc_layers[-1],
                          channel_num,
                          'hwl_fc{:d}'.format(layer_idx),
                          is_training,
                          with_bn=setting.hwl_branch_setting["with_bn"])
            fc_drop = tf.layers.dropout(
                fc,
                drop_rate,
                training=is_training,
                name='hwl_fc{:d}_drop'.format(layer_idx))
            self.hwl_fc_layers.append(fc_drop)
        self.logits_hwl = pf.dense(self.hwl_fc_layers[-1],
                                   3,
                                   'logits_hwl',
                                   is_training,
                                   with_bn=False,
                                   activation=None)

        # XYZ 预测分支 以用maxpooling特征进行预测为例
        self.xyz_fc_layers = [
            tf.reduce_max(self.bbox_layer_fts[-1], axis=1, name='xyz_fts_max')
        ]
        for layer_idx, layer_param in enumerate(extra_branch_fc_params):
            channel_num, drop_rate = layer_param
            fc = pf.dense(self.xyz_fc_layers[-1],
                          channel_num,
                          'xyz_fc{:d}'.format(layer_idx),
                          is_training,
                          with_bn=setting.xyz_branch_setting["with_bn"])
            fc_drop = tf.layers.dropout(
                fc,
                drop_rate,
                training=is_training,
                name='xyz_fc{:d}_drop'.format(layer_idx))
            self.xyz_fc_layers.append(fc_drop)
        if setting.with_xyz_res:
            logits_xyz_res = pf.dense(self.xyz_fc_layers[-1],
                                      3,
                                      'logits_xyz_res',
                                      is_training,
                                      with_bn=False,
                                      activation=None)
            self.logits_xyz = tf.add(points_mask_mean_sq,
                                     logits_xyz_res,
                                     name='logits_xyz')
        else:
            self.logits_xyz = pf.dense(self.xyz_fc_layers[-1],
                                       3,
                                       'logits_xyz_res',
                                       is_training,
                                       with_bn=False,
                                       activation=None)

        # Ry分支(旋转角分支)
        self.ry_layer_fts = [eb_fts]
        self.ry_layer_pts = [eb_pts]
        for layer_idx, layer_param in enumerate(extra_branch_xconv_params):
            tag = 'ry_branch_xconv_' + str(layer_idx + 1) + '_'
            K, D, P, C = layer_param
            fts = self.ry_layer_fts[-1]
            # get centroid points
            pts = self.ry_layer_pts[-1]
            if P == -1:
                qrs = eb_pts
            else:
                if setting.eb_with_fps:
                    fps_indices = tf_sampling.farthest_point_sample(P, pts)
                    qrs = tf_sampling.gather_point(pts, fps_indices)  # (N,P,3)
                else:
                    qrs = tf.slice(pts, (0, 0, 0), (-1, P, -1),
                                   name=tag + 'qrs')  # (N, P, 3)
            self.ry_layer_pts.append(qrs)
            if layer_idx == 0:
                C_pts_fts = C // 2 if fts is None else C // 4
                depth_multiplier = 4
            else:
                C_prev = xconv_params[layer_idx - 1][-1]
                C_pts_fts = C_prev // 4
                depth_multiplier = math.ceil(C / C_prev)
            fts_xconv = xconv(pts, fts, qrs, tag, N, K, D, P, C, C_pts_fts,
                              is_training, with_X_transformation,
                              depth_multiplier, sorting_method, False)
            self.ry_layer_fts.append(fts_xconv)

        # Ry 分类预测分支 以用maxpooling特征进行预测为例
        self.ry_fc_layers = [
            tf.reduce_max(self.ry_layer_fts[-1], axis=1, name='ry_fts_max')
        ]
        for layer_idx, layer_param in enumerate(extra_branch_fc_params):
            channel_num, drop_rate = layer_param
            fc = pf.dense(self.ry_fc_layers[-1],
                          channel_num,
                          'ry_fc{:d}'.format(layer_idx),
                          is_training,
                          with_bn=setting.ry_branch_setting["with_bn"])
            fc_drop = tf.layers.dropout(
                fc,
                drop_rate,
                training=is_training,
                name='ry_fc{:d}_drop'.format(layer_idx))
            self.ry_fc_layers.append(fc_drop)
        self.logits_ry = pf.dense(self.ry_fc_layers[-1],
                                  24,
                                  'logits_ry',
                                  is_training,
                                  with_bn=False,
                                  activation=None)
        self.probs_ry = tf.nn.softmax(self.logits_ry, name='probs_ry')