0%

首先要确保编辑器环境的编码为utf8,打开编码和保存编码都是utf8;其次如果py文件中含有中文字符的话,需要在py文件中对编码进行声明。

A) 设置编辑器编码:UTF-8

B) 修改python文件编码:在py文件首行加上#coding=utf-8,一定要在首行才可以

npm安装没反应及RollbackFailedOptional Verb Npm-Session错误

Npm安装报错 RollbackFailedOptional Verb Npm-Session
设置了cmd、git、npm代理,结果还是报错,最后换了一下源,更换为淘宝的源

1
npm config set registry http://registry.npm.taobao.org

参考https://www.cnblogs.com/zwrsnrt/p/12492482.html

hexo使用theme无法渲染页面问题

新版本hexo在使用主题时,生成页面发现无法正常显示,出现以下未渲染成功的源代码

1
'{% extends ‘_layout.swig‘ %} {% import ‘_macro/post.swig‘ as post_template %}'

查看显示的代码以及主题目录下的layout模板,发现hexo在新版本使用 Nunjucks 来渲染页面,但是很多主题还是旧版本hexo时编写的,使用的是Swig,所以页面没有正常使用swig渲染好,我们使用以下命令装上swig就好了

1
npm i hexo-renderer-swig

参考:
https://blog.csdn.net/qq_39898645/article/details/109181736
https://segmentfault.com/p/1210000010636536/read

hexo Error Deployer not found: git

20201027001057
https://blog.csdn.net/weixin_36401046/article/details/52940313

npm install –save hexo-deployer-git

Template render error: (unknown path)

有两种可能,一种是config.yml中没使用正确的缩进空格,一种是文章中有

1
{{}},{% %}

这种hexo无法转义的字符

config.yml

官方的示例如下
The error one:

1
2
3
plugins:
- hexo- generator-feed
- hexo-generator-sitemap

The correct one:

1
2
3
plugins:
- hexo-generator-feed
- hexo-generator-sitemap

文章有无法转义字符

将无法转义的句子用代码块括住

起因

之前搭建过hexo的博客,但是因为换电脑了,导致hexo的生成文件都丢了,就转战CSDN了,结果最近一篇ssr的文章审核不通过…还是用自己的博客吧…这是个hexo搭建github pages的记录博客,把搭建的流程、遇到的问题和解决方法记录下来,方便下次搭建(希望不会有下次)

设想:

  1. hexo搭建流程
  2. npm安装hexo报错问题
  3. hexo的文件双备份(在github的仓库新建branch,用于同步文件)

    搭建流程

    安装相关软件

    安装 Hexo 相当简单,只需要先安装下列应用程序即可:
    1
    2
    Node.js (建议使用 Node.js 12.0 及以上版本)  
    Git

    安装hexo

    所有必备的应用程序安装完成后,即可使用 npm 安装 Hexo。
    1
    npm install -g hexo-cli
    对于熟悉 npm 的进阶用户,可以仅局部安装 hexo 包。
    1
    npm install hexo
    以下是我遇见的问题:
    Npm安装无反应,设置了cmd、git、npm代理后报错 RollbackFailedOptional Verb Npm-Session
    ,最后换了一下源,更换为淘宝的源
    1
    npm config set registry http://registry.npm.taobao.org
    参考https://www.cnblogs.com/zwrsnrt/p/12492482.html

    建立站点项目

    安装 Hexo 完成后,请执行下列命令,Hexo 将会在指定文件夹中新建所需要的文件。
    1
    2
    3
    hexo init <folder>
    cd <folder>
    npm install

新建完成后,指定文件夹的目录如下,如下图所示:

1
2
3
4
5
6
7
8
9
.
├── scaffolds
├── node_modules
├── source
├── themes
├── _config.yml
├── package.json
├── package-lock.json
└── .gitignore

文件树形结构
其中各个文件夹的作用;

_config.yml 网站的配置信息,您可以在此配置大部分的参数。
_config.yml 配置文档:https://hexo.io/zh-cn/docs/configuration

node_modules 存放npm安装的依赖

package.json 应用程序的信息。EJS, Stylus 和 Markdown renderer 已默认安装,您可以自由移除。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package.json
{
"name": "hexo-site",
"version": "0.0.0",
"private": true,
"hexo": {
"version": ""
},
"dependencies": {
"hexo": "^3.8.0",
"hexo-generator-archive": "^0.1.5",
"hexo-generator-category": "^0.1.3",
"hexo-generator-index": "^0.2.1",
"hexo-generator-tag": "^0.2.0",
"hexo-renderer-ejs": "^0.3.1",
"hexo-renderer-stylus": "^0.3.3",
"hexo-renderer-marked": "^0.3.2",
"hexo-server": "^0.3.3"
}
}

scaffolds
模版 文件夹。当您新建文章时,Hexo 会根据 scaffold 来建立文件。

Hexo的模板是指在新建的文章文件中默认填充的内容。例如,如果您修改scaffold/post.md中的Front-matter内容,那么每次新建一篇文章时都会包含这个修改。

source
资源文件夹是存放用户资源的地方。除 _posts 文件夹之外,开头命名为 _ (下划线)的文件 / 文件夹和隐藏的文件将会被忽略。Markdown 和 HTML 文件会被解析并放到 public 文件夹,而其他文件会被拷贝过去。

themes
主题 文件夹。Hexo 会根据主题来生成静态页面。

本地运行

使用hexo s运行hexo项目在本地,浏览器输入http://127.0.0.1:4000/即可查看当前博客

github page

在github上创建一个用户名.github.io的仓库,用户名中字母要注意大小写。在setting中滑到最下方有个GitHub Pages,启用它。
20201120174706
随后访问用户名.github.io即可看到初始的博客页面

hexo to github page

在hexo博客文件夹中打开bash,输入以下命令,其中用户名和密码根据你github的注册信息修改

1
2
git config --global user.name "marshzero"
git config --global user.email "xxxxxxx@qq.com"

生成ssh key

1
ssh-keygen -t rsa -C "xxxxxxx@qq.com"

windows下打开C:/用户名/.ssh/id_rsa.pub。记事本打开并复制里面的内容,打开你的github主页,进入个人设置 -> SSH and GPG keys -> New SSH key:将刚复制的内容粘贴到key那里,名字可以写成blog或其他你能明白的名字。
输入ssh -T git@github.com,如果出现你的用户名,那就成功了。

hexo 部署到 github

首先,ssh key肯定要配置好。其次,配置_config.yml中有关deploy的部分:

1
2
3
4
deploy:
type: git
repository: git@github.com:用户名/用户名.github.io.git
branch: master

使用以下命令生成静态文件

1
hexo g

使用以下命令启动本地服务器

1
hexo s

使用以下命令提交静态页面到github

1
hexo d

常见命令

1
2
3
4
5
6
7
hexo new "postName" #新建文章
hexo new page "pageName" #新建页面
hexo generate #生成静态页面至public目录
hexo server #开启预览访问端口(默认端口4000,'ctrl + c'关闭server)
hexo deploy #部署到GitHub
hexo help # 查看帮助
hexo version #查看Hexo的版本

主题

这里我使用了Next主题,按照官方文档来配置就行,但是有一个小问题,就是Next主题在新版hexo中使用,会造成hexo无法渲染页面,这是因为两者的渲染插件不同,详情看这里

创建页面

例如创建“分类”这个页面,在博客文件夹打开bash,执行命令

1
hexo new page categories

成功后会提示

1
INFO  Created: ~/Documents/blog/source/categories/index.md

根据上面的路径,找到index.md这个文件,打开后默认内容是这样的:

1
2
3
4
---
title: 文章分类
date: 2017-05-27 13:47:40
---

添加type: “categories”到内容中,添加后是这样的:

1
2
3
4
5
---
title: 文章分类
date: 2017-05-27 13:47:40
type: "categories"
---

给新文章添加分类或者标签属性,和下面一样就行了,其中软件配置就是分类,ubuntu和软件配置是标签

1
2
3
4
5
6
7
8
9
---
title: Ubuntu18.04双系统安装与安装后要做的事
date: 2020-10-26 23:57:15
categories:
- 软件配置
tags:
- ubuntu
- 软件配置
---

发布文章

使用以下命令创建新文章,会在source创建一个md文件,在这个文件中写内容就可以了

1
hexo new 新文章示例

备份

我是已经创建了hexo项目后,再来备份的,备份的策略是知乎上一个答主提的思路,具体步骤参考的https://blog.csdn.net/qq_21040559/article/details/109702142

创建新分支

我们的hexo项目会在github上有一个gitpages的仓库对应,在这个仓库上创建一个新分支hexo,并设置成默认分支(这里不用担心hexo自己的git push,hexo会制定master来push的,设置hexo为默认分支是为了后面使用git命令时方便)
20201120171947
刚创建好时hexo分支的内容和master内容看起来一样,这里我也没搞懂,但是不影响后面的,不管它

复制.git文件夹

在其他任意位置使用git clone将hexo分支下载下来,将其中的.git文件夹复制到我们的博客文件夹内,此时在博客文件夹中打开bash即可看到hexo的提示,这一部很妙,不用手动配置本地仓库和远程仓库对应(没有.git文件夹时不会提示这是个仓库,注意不要使用git init命令,这会将博客文件夹初始为一个新仓库。)
20201120172416
博客文件夹中需要一个.gitignore文件,用来在上传时候忽略一些文件,即不上传.gitignore中忽略的文件。如果有最好,没有的话自己手动添加。

1
2
3
4
5
6
7
.DS_Store
Thumbs.db
db.json
*.log
node_modules/
public/
.deploy*/

注意,如果你之前克隆过theme中的主题文件,那么应该把主题文件中的.git文件夹删掉,因为git不能嵌套上传,最好是显示隐藏文件,检查一下有没有,否则上传的时候会出错,导致你的主题文件无法上传,这样你的配置在别的电脑上就用不了了。

备份

在hexo博客的根目录下依次执行

1
2
3
git add .
git commit -m "Backup"
git push origin hexo

这样就能看到github上有我们要备份的hexo项目啦,
20201120172902
使用hexo d是将静态页面备份到github上的master,使用git push origin hexo是将hexo项目文件夹备份到github上的hexo分支。

恢复

将两个分支的内容下载并合并,安装相应的软件即可(未尝试)

在另一台电脑上使用hexo项目

https://blog.csdn.net/mrwangweijin/article/details/79364030

Python-api pickle模块学习

前言

python3.9-doc-pickle:https://docs.python.org/3/library/pickle.html
在做实验时,可能需要将数据打包成pickle文件,方便后续的读取。pickle是一个python模块,源代码在Lib/pickle.py,可将python对象进行序列化和反序列化。以下内容参考python文档和网上博客。

介绍

1
The pickle module implements binary protocols for serializing and de-serializing a Python object structure. “Pickling” is the process whereby a Python object hierarchy is converted into a byte stream, and “unpickling” is the inverse operation, whereby a byte stream (from a binary file or bytes-like object) is converted back into an object hierarchy. Pickling (and unpickling) is alternatively known as “serialization”, “marshalling,” 1 or “flattening”; however, to avoid confusion, the terms used here are “pickling” and “unpickling”.

与其他相似库的比较

与marshal比较

Python有一个更原始的序列化模块,称为marshal,但通常pickle应该始终是序列化Python对象的首选方式。 marshal存在主要是为了支持Python的.pyc文件。该pickle模块marshal在以下几个重要方面有所不同:

  • 该pickle模块跟踪已序列化的对象,因此以后对同一对象的引用将不会再次序列化。marshal并不这样做。这对于递归对象和对象共享都有影响。递归对象是包含对其自身的引用的对象。marshal无法处理递归对象,尝试使用marsha处理递归对象将使您的Python解释器崩溃。当要序列化的对象层次结构中的不同位置存在对同一对象的多个引用时,就会发生对象共享。 pickle仅将此类对象存储一次,并确保所有其他引用都指向主副本。共享的对象保持共享状态,这对于可变对象非常重要。

  • marshal不能用于序列化用户定义的类及其实例。 pickle可以透明地保存和恢复类实例,但是类定义必须是可导入的,并且与对象存储时位于同一模块中。

  • 该marshal序列化格式是不能保证整个Python版本移植。因为它的主要工作是支持 .pyc文件,所以Python实现者保留在需要时以非向后兼容的方式更改序列化格式的权利。pickle选择了兼容的pickle协议,并且如果您的数据越过了唯一的突破性更改语言边界,则pickling和unpickling可以处理Python 2到Python 3类型的差异,则可以确保序列化格式在Python版本之间向后兼容。

    与json比较

    pickle协议和JSON (JavaScript Object Notation)之间有基本的区别:

  • JSON是一种文本序列化格式(虽然大多数时间然后将其编码为utf-8,但它输出unicode文本),而pickle是一种二进制序列化格式;

  • JSON是人类可读的,而pickle则不是;

  • JSON是可互操作的,并且在Python生态系统之外被广泛使用,而pickle是特定于Python的;

  • 默认情况下,JSON只能表示Python内置类型的子集,而不能表示自定义类。pickle可以表示大量的Python类型(通过巧妙地使用Python的自省功能,其中的许多会自动实现;可以通过实现特定的对象API解决复杂的情况);

  • 与pickle不同,反序列化不受信任的JSON本身并不会创建代码执行漏洞。

这里也有python的json模块:一个标准的库模块,允许JSON序列化和反序列化。

Data stream format 数据流格式

所使用的数据格式pickle是特定于Python的。这样做的优点是不受外部标准(例如JSON或XDR)的限制(不能表示指针共享);但是,这意味着非Python程序可能无法重建pickling后的Python对象。

默认情况下,pickle数据格式使用相对紧凑的二进制表示形式。如果需要最佳的大小特征,则可以有效地压缩pickling的数据。

该模块pickletools包含用于分析生成的数据流的工具pickle。 pickletools源代码对pickle协议使用的操作码有大量注释。

当前有6种不同的协议可用于pickling。使用的协议越高,读取生成的pickle所需的Python版本越新。

  • Protocol version 0是原始的“人类可读”协议,并且与Python的早期版本向后兼容。

  • Protocol version 1是旧的二进制格式,也与Python的早期版本兼容。

  • Protocol version 2是在Python 2.3中引入的。它提供了更高效的新型es酸洗。参考PEP 307,了解有关协议2带来的改进的信息。

  • Protocol version 3是在Python 3.0中添加的。它具有对bytes对象的显式支持, 并且不能被Python 2.x unpickled。这是Python 3.0–3.7中的默认协议。

  • Protocol version 4是在Python 3.4中添加的。它增加了对非常大的对象的支持,pickling更多种类的对象以及一些数据格式优化。从Python 3.8开始,它是默认协议。参考PEP 3154,获取有关协议4带来的改进的信息。

  • Protocol version 5已在Python 3.8中添加。它增加了对带外数据的支持和对带内数据的加速。参考PEP 574,了解有关协议5带来的改进的信息。

Module Interface 模块接口

pickle提供以下属性:

1
2
3
4
5
6
7
8
9
pickle.HIGHEST_PROTOCOL
An integer, the highest protocol version available. This value can be passed as a protocol value to functions dump() and dumps() as well as the Pickler constructor.

pickle.DEFAULT_PROTOCOL
An integer, the default protocol version used for pickling. May be less than HIGHEST_PROTOCOL. Currently the default protocol is 4, first introduced in Python 3.4 and incompatible with previous versions.

Changed in version 3.0: The default protocol is 3.

Changed in version 3.8: The default protocol is 4.

The pickle module provides the following functions to make the pickling process more convenient:

前言

论文LSANet看的差不多,对其代码进行分析,看看是怎么实现论文中的模型。

1
2
论文地址:https://arxiv.org/abs/1905.05442
代码地址:https://github.com/LinZhuoChen/LSANet

SFE模块

20201028152630
pointnet_util.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
def sample_and_group(npoint, radius, nsample, xyz, points, bn, is_training, bn_decay, mlp, knn=False, use_xyz=True, xyz_feature=None, end=False, use_edge_feature=False):
'''
Input:
npoint: int32 点的数量
radius: float32 半径
nsample: int32 采样点的数量
xyz: (batch_size, ndataset, 3) TF tensor BxNx3的点的xyz信息
points: (batch_size, ndataset, channel) TF tensor, if None will just use xyz as points BxNxC的点的特征信息,如果为空则用xyz
knn: bool, if True use kNN instead of radius search 如果为True则使用knn替代球查询
use_xyz: bool, if True concat XYZ with local point features, otherwise just use point features
xyz_feature: 上一个SFE即sample_and_group的输出Feature_out(xyz_feature)
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
output_feature: 图中的Feature_sfe
xyz_feature: 图中的Feature_out
grouped_xyz: 图中绿色的BxN'xKx3 (batch_size, npoint, nsample, 3) TF tensor, normalized point XYZs
(subtracted by seed point XYZ) in local regions
'''
# new_xyz = (N,Fin)
new_xyz = gather_point(xyz, farthest_point_sample(npoint, xyz)) # (batch_size, npoint, 3)
if knn: #看用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) = (b,N',K,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) = (b,N',K,Fin)
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 # new_points = 拼接特征和坐标的结果 #这里不是SFE

############################# 对比pointnet++增加的部分
# 使用edge特征
if use_edge_feature == False:
return new_xyz, new_points, idx, grouped_xyz
# [batch_size, npoint, 1, F]
if xyz_feature == None:
xyz_feature = xyz

xyz_feature = group_point(xyz_feature, idx) # xyz_feature = (N',K,Fin) 若xyz_feature == None所以和下面的edge_feature一样
edge_feature = grouped_xyz # (batch_size, npoint, nsample, 3) = (N',K,3) 图中绿色部分
for i, num_out_channel in enumerate(mlp):
edge_feature = tf_util.conv2d(edge_feature, num_out_channel, [1, 1],
padding='VALID', stride=[1, 1],
bn=bn, is_training=is_training,
scope='xyz_feature_%d' % (i), bn_decay=bn_decay)
output_feature = tf.concat([xyz_feature, edge_feature], axis=-1) # 拼接两个特征,在进行mlp和maxpool
if end == False:
xyz_feature = tf_util.conv2d(output_feature, mlp[-1], [1, 1],
padding='VALID', stride=[1, 1],
bn=bn, is_training=is_training,
scope='xyz_feature2', bn_decay=bn_decay)
# we can try sum and mean
xyz_feature = tf.reduce_max(xyz_feature, axis=[2], keep_dims=True, name='maxpool')
xyz_feature = tf.squeeze(xyz_feature, [2])

############################# output_feature是Feature_sfe,xyz_feature是Feature_out
return new_xyz, new_points, idx, output_feature, xyz_feature, grouped_xyz

LSA layer

20201028163403
20201028163416

1

SDWs模块

整体结构

LSA layer:在下面代码函数中,会调用SFE的代码即sample_and_group()函数,随之调用LSA layer模块,也就是说LSA_layer()函数包括了SFE和LSA layer两个操作,在model的代码中通过定义多个层数来进行图示的多个layer的操作
20201028152601

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
def LSA_layer(xyz, points, npoint, radius, nsample, mlp, mlp2, group_all, is_training, bn_decay,
scope, xyz_feature=None, bn=True, pooling='max', knn=False, use_xyz=True, use_nchw=False,
end=False):
''' LSA layer
Input:
xyz: (batch_size, ndataset, 3) TF tensor BxNx3的点的xyz信息
points: (batch_size, ndataset, channel) TF tensor BxNxC的点的特征信息,如果为空则用xyz
npoint: int32 -- #points sampled in farthest point sampling 点的数量
radius: float32 -- search radius in local region 采样分组的半径
nsample: int32 -- how many points in each local region 采样点的数量
mlp: list of int32 -- output size for MLP on each point 每个点在mlp中输出的通道大小
mlp2: list of int32 -- output size for MLP on each region 每个局部区域在mlp中输出的通道大小
group_all: bool -- group all points into one PC if set true, OVERRIDE
npoint, radius and nsample settings
is_training: bool -- whether train this LSA layer
bn_decay: float32 -- batch norm decay
scope: scope in tensorflow
xyz_feature: float32 -- feature from SFE 即是Feature_out
use_xyz: bool, if True concat XYZ with local point features, otherwise just use point features
use_nchw: bool, if True, use NCHW data format for conv2d, which is usually faster than NHWC format
Return:
new_xyz: (batch_size, npoint, 3) TF tensor 新的xyz
new_points: (batch_size, npoint, mlp[-1] or mlp2[-1]) TF tensor 新的points
idx: (batch_size, npoint, nsample) int32 -- indices for local regions 局部点的索引
xyz_feature: LSA layer 的Feature_out
'''
data_format = 'NCHW' if use_nchw else 'NHWC'
with tf.variable_scope(scope) as sc:
# Sample and Grouping 采样并分组
if group_all:
nsample = xyz.get_shape()[1].value
new_xyz, new_points, idx, output_feature, xyz_feature, grouped_xyz = sample_and_group_all(xyz, points, bn, is_training, bn_decay, mlp2, use_xyz, xyz_feature, end, use_edge_feature=True)
else:
new_xyz, new_points, idx, output_feature, xyz_feature, grouped_xyz = sample_and_group(npoint, radius, nsample, xyz, points, bn, is_training, bn_decay, mlp2, knn, use_xyz, xyz_feature, end, use_edge_feature=True)
# xyz Feature Embedding
# 这里将output_feature和新点云的信息拼接到一起了 总体架构中的C操作
new_points = tf.concat([new_points, output_feature], axis=-1)

# SDWs模块
channel = new_points.get_shape()[-1].value
## spatial encoder
attention_xyz_1 = tf_util.conv2d(grouped_xyz, 64, [1, 1],
padding='VALID', stride=[1, 1],
bn=bn, is_training=is_training,
scope='xyz_attention_1', bn_decay=bn_decay,
data_format=data_format) # Spi
## Region Spatial Encoder
attention_xyz_2 = tf_util.conv2d(grouped_xyz, 64, [1, 1],
padding='VALID', stride=[1, 1],
bn=bn, is_training=is_training,
scope='xyz_attention_2', bn_decay=bn_decay,
data_format=data_format)
attention_xyz_2 = tf.reduce_mean(attention_xyz_2, axis=[2], keep_dims=True, name='meanpool')
attention_xyz_2 = tf.tile(attention_xyz_2, [1, 1, nsample, 1]) # Sg
attention_xyz = tf.concat([attention_xyz_1, attention_xyz_2], axis=-1) #Si
## shared MLP+MLP_
for i, num_out_channel in enumerate(mlp):
# 假设是第一轮循环
## shared MLP_1(in LSA hierarchical encoding)
new_points = tf_util.conv2d(new_points, num_out_channel, [1, 1],
padding='VALID', stride=[1, 1],
bn=bn, is_training=is_training,
scope='conv%d' % (i), bn_decay=bn_decay,
data_format=data_format)
## shared MLP(in SDWs)
attention_xyz = tf_util.conv2d(attention_xyz, num_out_channel, [1, 1],
padding='VALID', stride=[1, 1],
bn=bn, is_training=is_training,
scope='xyz_attention%d' % (i), bn_decay=bn_decay,
data_format=data_format, activation_fn=tf.sigmoid)
# LSA layer中的X操作,即元素相乘
new_points = tf.multiply(new_points, attention_xyz)
# LSA pooling
new_points = tf.reduce_max(new_points, axis=[2], keep_dims=True, name='maxpool2')

new_points = tf.squeeze(new_points, [2]) # (batch_size, npoints, mlp2[-1]) # 删掉为1的维度
# new_points = tf.concat([new_points, xyz_feature], axis=-1)
return new_xyz, new_points, idx, xyz_feature

细节分析

前言

最近要下载一个很大的数据集,然而国内的网访问只有几十k/s,没办法只能用小飞机了。下载数据集的是一个python脚本,那只能配置全局代理了。

安装小飞机

1. 安装shadowsocks

网址:https://github.com/shadowsocks/shadowsocks
从官网下载软件,并使用自己的账号进行配置。
配置/etc/shadowsocks.json(没有就新建一个)

1
2
3
4
5
6
7
{
"server":"代理服务器IP",
"server_port":代理服务器ss服务端口,
"password":"密码",
"timeout":300,
"method":"加密类型"
}

启动服务(本地的用sslocal,不用ssserver)

1
sudo sslocal -c /etc/shadowsocks.json

这时配置系统代理为127.0.0.1:8080即可科学上网

2. 安装shadowsocksR

网址:https://github.com/qingshuisiyuan/electron-ssr-backup
根据以上网址安装并配置,并使用命令启动,在图形化界面配置账号信息

配置全局代理

Terminal只支持http、https协议,而ShadowSocks使用的是socks协议,ssr同理。我们可以使用Privoxy来将http和socks相互转换。
首先,使用下面的命令安装Privoxy:

1
sudo apt-get install privoxy

安装完毕后,打开Privoxy的配置文件/etc/privoxy/config:

1
sudo gedit /etc/privoxy/config

第一步定位到4.1. listen-address 这一段,找到监听的端口,我的是在第783行:
IMG_4309
可以看到端口一般都是8118。
接着找到5.2. forward-socks4, forward-socks4a, forward-socks5 and forward-socks5t这一节,加上如下配置(图中是ssr的配置):

1
forward-socks5 / 127.0.0.1:1080 .

IMG_4310

保存后,重启一下Privoxy:

1
sudo /etc/init.d/privoxy restart

接着配置终端的环境,打开终端配置文件:

1
sudo gedit ~/.bashrc

在末尾追加下面代码:

1
2
export http_proxy="127.0.0.1:8118"
export https_proxy="127.0.0.1:8118"

保存文件后,重启终端或者执行下面的命令重新读取配置文件:

1
source ~/.bashrc

使用下面代码来测试穿墙是否成功:

1
wget http://www.google.com

穿墙成功,接着将Privoxy添加到开机启动,在/etc/rc.local中添加如下命令,注意在exit 0之前:

1
sudo /etc/init.d/privoxy start

在/etc/profile的末尾添加如下两句:

1
2
export http_proxy="127.0.0.1:8118"
export https_proxy="127.0.0.1:8118"

到这里就可以使用Terminal来科学上网了,注意这部分是根据ss中默认本地端口为1080的情况,如果是ssr,端口是12333,要配置成相应的12333端口。其本质就是ss或ssr进行listen,系统设置代理后,出网的数据要流到127.0.0.1:1080(或12333),ss和ssr listen 后接收数据并通过自己的信道传输。加上privoxy后,就是系统代理发到privoxy,然后privoxy再发到ss ssr上,这中间privoxy可以转发sock5的,也就实现了terminal的穿墙

参考文章:
https://www.pianshen.com/article/8287306670/

ply文件介绍

PLY是一种三维mesh模型数据格式,全名为多边形档案(Polygon File Format)或 斯坦福三角形档案(Stanford Triangle Format)。

该格式主要用以储存立体扫描结果的三维数值,透过多边形片面的集合描述三维物体,与其他格式相较之下这是较为简单的方法。它可以储存的资讯包含颜色、透明度、表面法向量、材质座标与资料可信度,并能对多边形的正反两面设定不同的属性。

在档案内容的储存上PLY有两种版本,分别是纯文字(ASCII)版本与二元码(binary)版本,其差异在储存时是否以ASCII编码表示元素资讯。
ply文件的基本格式如下

1
2
3
4
5
6
This is the structure of a typical PLY file:

Header
Vertex List
Face List
(lists of other elements)

从ply到end_header是头部,element可以有多个property,例如vertex可以有xyz三个property。ply示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
ply
format ascii 1.0 { ascii/binary, 编码类型 }
comment made by Greg Turk { comments keyword specified, like all lines }
comment this file is a cube
element vertex 8 { 定义 "vertex" 元素, 8 代表这个文件有八个顶点信息 }
property float x { vertex contains float "x" coordinate }
property float y { y coordinate is also a vertex property }
property float z { z coordinate, too }
element face 6 { 定义 "face" 元素, 6 代表这个文件有六个面信息 }
property list uchar int vertex_index { "vertex_indices" is a list of ints }
end_header { delimits the end of the header }
0 0 0 { start of vertex list }
0 0 1
0 1 1
0 1 0
1 0 0
1 0 1
1 1 1
1 1 0
4 0 1 2 3 { start of face list }
4 7 6 5 4
4 0 4 5 1
4 1 5 6 2
4 2 6 7 3
4 3 7 4 0

这里是一个对ply文件的解释
http://paulbourke.net/dataformats/ply/
这里有一个ply文件的示例
http://paulbourke.net/dataformats/ply/example1.ply

代码示例

1
2
3
from plyfile import PlyData
import os
import numpy as np

使用plydata.read读取ply文件,可以看到ply_data是头部信息

1
2
ply_data = PlyData.read('../repo/bun_zipper.ply')
print(ply_data)
# 输出
ply
format ascii 1.0
comment zipper output
element vertex 35947
property float x
property float y
property float z
property float confidence
property float intensity
element face 69451
property list uchar int vertex_indices
end_header

读取顶点信息

1
2
vertex = ply_data['vertex']
print(vertex)

可以看到输出的是顶点vertex及它的property的信息

# 输出
element vertex 35947
property float x
property float y
property float z
property float confidence
property float intensity

读取面的信息

1
2
face = ply_data['face']
print(face)
# 输出
element face 69451
property list uchar int vertex_indices

将三个坐标合在一起并输出

1
2
3
4
5
6
x = np.asarray(vertex['x'])
y = np.asarray(vertex['y'])
z = np.asarray(vertex['z'])
points = np.stack([x, y, z], axis=1)
print(x.shape)
print(points.shape)
#输出
(35947,)
(35947, 3)