Applications - HongkuanZhang/Technique-Notes GitHub Wiki

Conda的常用命令

  • conda查看环境信息
    conda info -e
  • conda退出环境
    conda deactivate
  • conda克隆环境
    conda create -n New_Env_Name --clone Old_Env_Name
  • conda删除环境
    conda remove -n Env_name --all
  • conda环境共享
    将环境保存为yml文件
    conda env export > environment.yml
    然后在新的电脑上重构环境
    conda env create -f environment.yml
    首先environment.yml这个文件的名称是可以任意改的。其次,对于重构环境的名称,可以对yml里的name项进行更改,此外有时候export的yml文件最下方会生成一行prefix记录被复制环境的位置,因为据说重构环境时候并不会理这一行,所以可以直接删除(亲测没什么问题)。最后,如果在重构过程中中断了,后续重新断点继续的方法为如下:
    先进到目标环境中
    conda activate myenv
    然后根据yml文件,conda会知道哪些操作需要做,并执行更新
    conda env update --file environment.yml

Screen常用命令

  • 列出所有窗口
    screen -ls
  • 创建窗口
    screen -S NAME
  • 恢复窗口
    screen -r NAME
  • 杀掉detached的进程
    screen -X -S NAME quit

Github

安装Git

  1. 创建public key ssh-keygen -t rsa -C “mail@address”
  2. 复制id_rsa.pub公开键的内容 cat .ssh/id_rsa.pub
  3. 将复制内容添加到github个人主页Setting>>SSH and GPG keys>>SSH keys中, 标题任意
  4. 回到终端, 测试连接
ssh -T [email protected]
Hi xx! You've successfully authenticated, but GitHub does not provide shell access.xi

PS: 如果出现以下Warning
Warning: Permanently added the RSA host key for IP address '13.250.177.223' to the list of known hosts.
则需要添加ip进入host

  • sudo vim private/etc/hosts
  • 进入编辑模式 添加以下信息
    13.250.177.223 github.com
  • 再次重连ssh, Warning解除

同步Git:

git add . # . 代表全部改动都会被更新
git commit -m ‘message contents’
git push / git push origin master
有时候因为GitHub上也改动,本地也改动,就会出现错误,这时候要在第3步之前加3步
git remote add origin + 添加远程主分支, 一次就好, 以后都不用这步了!
git pull origin master pull远程变动
git push -u origin master push本地变动

删除GitHub仓库中的.iml文件和.idea文件夹

git rm -r --cached .idea # --cached不会把本地的.idea删除
git cimmit -m "delete .idea dir"
git push -u origin master

Juman++

wget https://github.com/ku-nlp/jumanpp/releases/download/v2.0.0-rc3/jumanpp-2.0.0-rc3.tar.xz
tar xf jumanpp-2.0.0-rc3.tar.xz
cd jumanpp-2.0.0-rc3.tar.xz
mkdir bld
cd bld
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/home/namae/usr/local/
make install -j2

  • PS: install_prefix 那里当时指定路径为/usr/local/, install过程失败(此路径只有root权限才能写入), 所以当时下载到了另一个文件夹 之后将那个文件夹中的/bin/jumanpplibexec/jumanpp分别cp到了/home/namae/usr/local/bin//home/namae/usr/local/libexec下也能正常使用, 注意cp时候如果复制的文件夹子目录中也有文件夹要加-r
  • 验证是否安装成功:
!pip install pyknp
from pyknp import Juman
jumanpp = Juman()
result = jumanpp.analysis("恵比寿にあるあのイタリアンにはよく行く。美味しいんだ。")
for mrph in result.mrph_list():
    print(mrph.midasi, mrph.yomi, mrph.genkei, mrph.hinsi)

python-mecab

加载词典并分词

关于mecab的参数

Numpy

multiply和dot运算

访问指定index的元素

访问满足条件的元素

关于np.stack

np.random.shuffle()和np.random.permutation()

np.random.shuffle()和np.random.permutation()的区别是前者直接打乱原排列, 而后者不改变元排列, 打乱后的排列可以赋值给别的变量
而且用法可以为np.random.permutation(4) --> [0,2,1,3]

Plot基本绘图流程

文本标注工具Brat的使用

http://lucene.jugem.jp/?eid=478

关于python中OpenCV的使用笔记(cv2)

由于最近在做vediocaption的项目,所以需要用到opencv来读取视频文件,在这里对于用到的函数做一些记录。

关于视频的读取

视频文件的读取

视频文件的读取主要是用到VedioCapture()这个函数,参数是文件地址,过程如下所示。
对于返回的VedioCapture Object,用isOpened()即可查看文件是否成功读取了。

import cv2

cap_file = cv2.VideoCapture('data/temp/sample_video.mp4')
print(type(cap_file))
# <class 'cv2.VideoCapture'>

print(cap_file.isOpened())
# True

为什么要用isOpened确认是否读取了呢,是因为即使路径是错误的,VedioCapture()也会返回VedioCapture类型的Object而不会报错,如下所示。

cap_file_wrong = cv2.VideoCapture('wrong_path')
print(type(cap_file_wrong))
# <class 'cv2.VideoCapture'>

print(cap_file_wrong.isOpened())
# False

通过内置摄像头读取视频

opencv还可以通过电脑的内置摄像头读取视频,也可以控制读取时长(镜头会打开多长时间获取视频),过程如下

import cv2

cap_cam = cv2.VideoCapture(0) # 用内置camera读取则文件地址参数为0
print(type(cap_cam))
# <class 'cv2.VideoCapture'>

print(cap_cam.isOpened())
# True

获取视频的properties

对于读取视频得到的VedioCapture Object,我们想要知道视频的一些属性例如视频高宽,帧数或者FPS。 这里我们用get()方法来获取对应属性,如下所示

import cv2

cap = cv2.VideoCapture('data/temp/sample_video.mp4')
print(type(cap))
# <class 'cv2.VideoCapture'>

print(cap.isOpened())
# True

print(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) # Frame的宽
# 640.0

print(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) # Frame的高
# 360.0

print(cap.get(cv2.CAP_PROP_FPS)) # FPS,即一秒内多少帧
# 29.97002997002997

print(cap.get(cv2.CAP_PROP_FRAME_COUNT)) # Frame总数
# 360.0

print(cap.get(cv2.CAP_PROP_FRAME_COUNT) / cap.get(cv2.CAP_PROP_FPS)) # 动画秒数(播放时长)
# 12.012

对于可以指定的属性,可以参考这两个链接:英文官网属性列表, 中文翻译版属性列表

设定读取视频的属性值

如果我们想要更改视频的一些属性,那么需要使用到get()方法,使用方法如下:

### 属性值不可变更则返回False
print(cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320))
# False

print(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
# 640.0

print(cap.get(cv2.CAP_PROP_POS_FRAMES)) # POS_FRAMES为接下来要解码/捕获的帧的基于0的索引(开始的索引)。
# 0.0

print(cap.set(cv2.CAP_PROP_POS_FRAMES, 100))
# True

print(cap.get(cv2.CAP_PROP_POS_FRAMES))
# 100.0

以Numpy的ndarray来获取视频

使用read()方法获取ndarray的视频数据,如下

import cv2

cap = cv2.VideoCapture('data/temp/sample_video.mp4')
print(type(cap))
# <class 'cv2.VideoCapture'>

print(cap.isOpened())
# True

print(cap.get(cv2.CAP_PROP_POS_FRAMES)) # 当前帧数
# 0.0

print(cap.get(cv2.CAP_PROP_POS_MSEC)) # 经过的时间
# 0.0

ret, frame = cap.read() # 读取视频为ndarray数据

print(ret) # 第一个返回值为bool值,表示是否成功读取
# True

print(type(frame)) # 第二个值为ndarray类型变量,为读取的当前Frame
# <class 'numpy.ndarray'>

print(frame.shape) # 当前Frame的形状
# (360, 640, 3)

print(cap.get(cv2.CAP_PROP_POS_FRAMES)) # 当前Frame位置变为了1
# 1.0

print(cap.get(cv2.CAP_PROP_POS_MSEC)) # 经过时间为33ms
# 33.36666666666667

print(1 / cap.get(cv2.CAP_PROP_FPS) * 1000) # 通过FPS计算的一帧需要的ms数,同上
# 33.36666666666667

想把现在的位置移到任意Frame的话要使用set()方法如下

cap.set(cv2.CAP_PROP_POS_FRAMES, 100)
print(cap.get(cv2.CAP_PROP_POS_FRAMES))
# 100.0

ret, frame = cap.read()

print(ret)
# True

print(cap.get(cv2.CAP_PROP_POS_FRAMES)) # 在100处read则得到位置为101的帧
# 101.0

print(cap.get(cv2.CAP_PROP_POS_MSEC))
# 3370.0333333333333

视频的循环播放

视频的播放使用的是imshow()方法,过程如下所示

import cv2
import sys

file_path = 'data/temp/sample_video.mp4'
delay = 1
window_name = 'frame' # 窗口名

cap = cv2.VideoCapture(file_path)

if not cap.isOpened():
    sys.exit()

while True:
    ret, frame = cap.read() # 读取视频
    if ret:
        cv2.imshow(window_name, frame) # imshow在指定window显示frame
        ```
        waitKey()は引数に指定した時間(単位はミリ秒)動作を止めてキーボード入力を待つ関数。
        0xFFとの&をとっているのは64bit環境対応のため。
        waitKey()の引数を0とするとキーボード入力がされるまで無限に待ち続けるので、何らかのキーが押されるまで表示画像は更新されない。
        q以外のキーを押すと画像が更新される。<-主要是这一句,下面的作用就是按q则停止
        ```
        if cv2.waitKey(delay) & 0xFF == ord('q'):
            break
    else:
        cap.set(cv2.CAP_PROP_POS_FRAMES, 0)

cv2.destroyWindow(window_name)

其他内容参考这个日文博客
对于视频损坏提取指定帧的方法参考知乎链接

用rosbag来提取bag文件中的数据

rosbag文件一般存储着一些序列数据,bag文件中包含着很多个定义好的数据类型即topic,每个topic下包含着对应的数据,一般来说提取都是需要安装ROS的,但是ROS需要root权限,而且安装过程非常麻烦,因此我们这里用网上的一个方法不安装ROS,只安装python中的rosbag也可以提取数据。

安装所需文件

安装roslz4

conda install -c conda-forge ros-roslz4

安装rosbag

pip install --extra-index-url https://rospypi.github.io/simple/ rospy rosbag

有了这两个步骤我们就可以import rosbag了

按照topic读取bag包中的数据

import rosbag
filename = 'abs_path_for_bag_file'

bag = rosbag.Bag(filename)

# 打印每个时间步的数据类型名称,数据内容和当前时间
for topic,msg,t in bag.read_messages():
    print(topic,msg,t)

而如果我们想要获取某个类型数据的所有时间步的数据则
for topic,msg,t in bag.read_messages():
    if topic == 'specified_topic_name':
       print(msg.data) 
       # 注意,.data不是一个固定用法,而是在上一步中输出msg时候我看到了它包含的数据名称是"data"所以这里才用.data
       # 其他数据是不是也用.data来抽出数据目前还不清楚

参考

用gdown来下载google drive上的大文件

gdown https://drive.google.com/uc?id=file_id
The file_id should look something like 0Bz8a_Dbh9QhbNU3SGlFaDg
这里的file_id可以通过复制最终的下载链接(这里最终的一定是点了之后能跳出下载目录的那个链接),在链接中查找到file_id,然后替换到上面的那句话里。
追记 因为被NEDO的下载折磨过好几次,所以这里记录下他们分享的文件下载的整个过程

  1. 打开分享的文件夹链接会跳出可视化文件夹页面,然后对着要下载的文件夹右键选择获取共享链接,并复制链接。
  2. 然后注意一定要开个新的页面把刚刚复制的链接打开。
  3. 之后由于文件很大,所以还要点一次下载,会弹出一个新页面,这个页面才是最终的下载链接(如上所述)。
  4. 最后再这个页面的地址栏找到uc?id=abcde...这样的文字,这里abcde...就是我们需要的file id。
  5. 最后用gdown https://drive.google.com/uc?id=file_id来下载文件。

又因为下载共享文件折腾了一下,小文件的话上面的方法即使重新开页面打开后和原页面一样,并不能弹出什么新链接。然后查了下官网,发现人家给了很好的方案如下

$ gdown --help
usage: gdown [-h] [-V] [-O OUTPUT] [-q] [--fuzzy] [--id]  [--proxy PROXY]
             [--speed SPEED] [--no-cookies] [--no-check-certificate]
             [--continue] [--folder]
             url_or_id
...

$ # a large file (~500MB)
$ gdown https://drive.google.com/uc?id=1l_5RK28JRL19wpT22B-DY9We3TVXnnQQ
$ # gdown --id 1l_5RK28JRL19wpT22B-DY9We3TVXnnQQ
$ md5sum fcn8s_from_caffe.npz
256c2a8235c1c65e62e48d3284fbd384

$ # a small file
$ gdown https://drive.google.com/uc?id=0B9P1L--7Wd2vU3VUVlFnbTgtS2c
$ cat spam.txt
spam

$ # download with fuzzy extraction of a file ID
$ gdown --fuzzy 'https://drive.google.com/file/d/0B9P1L--7Wd2vU3VUVlFnbTgtS2c/view?usp=sharing&resourcekey=0-WWs_XOSctfaY_0-sJBKRSQ'
$ cat spam.txt
spam

$ # --fuzzy option also works with Microsoft Powerpoint files
$ gdown --fuzzy "https://docs.google.com/presentation/d/15umvZKlsJ3094HNg5S4vJsIhxcFlyTeK/edit?usp=sharing&ouid=117512221203072002113&rtpof=true&sd=true"

$ # a folder 下载共享文件参考这里!!非常好用~ 
$ gdown https://drive.google.com/drive/folders/1ivUsJd88C8rl4UpqpxIcdI5YLmRD0Mfj -O /tmp/folder --folder

$ # as an alternative to curl/wget
$ gdown https://httpbin.org/ip -O ip.json
$ cat ip.json
{
  "origin": "126.169.213.247"
}

$ # write stdout and pipe to extract
$ gdown https://github.com/wkentaro/gdown/archive/refs/tags/v4.0.0.tar.gz -O - --quiet | tar zxvf -
$ ls gdown-4.0.0

除上面之外还有个更简单的用文件id的方法: gdown --id File_ID

Jupyter 相关问题

  1. Python=3.6环境下会出现函数通过tab不能自动补全,这时通过pip卸载jedi就可以了,命令如下
pip uninstall jedi --yes
  1. Jupyter在创建新文件时候会出现警告: Config option template_path not recognized by...,解决方法如下
pip install nbconvert==5.6.1

不需要手动卸载已经存在的conda中的nbconvert,直接pip下载会自动卸载存在的nbconvert

Opencv和numpy中图像的(上下左右)翻转和旋转

# 翻转问题
## For OpenCV
import cv2

img = cv2.imread('data/src/lena.jpg')
print(type(img))
# <class 'numpy.ndarray'>

print(img.shape)
# (225, 400, 3)

img_flip_ud = cv2.flip(img, 0)
cv2.imwrite('data/dst/lena_cv_flip_ud.jpg', img_flip_ud)
# 0为上下翻转

img_flip_lr = cv2.flip(img, 1)
cv2.imwrite('data/dst/lena_cv_flip_lr.jpg', img_flip_lr)
# 1为左右翻转

img_flip_ud_lr = cv2.flip(img, -1)
cv2.imwrite('data/dst/lena_cv_flip_ud_lr.jpg', img_flip_ud_lr)
# -1为上下左右翻转
#######################################
## For Numpy
import numpy as np
from PIL import Image

img = np.array(Image.open('data/src/lena.jpg'))
print(type(img))
# <class 'numpy.ndarray'>

print(img.shape)
# (225, 400, 3)

Image.fromarray(np.flipud(img)).save('data/dst/lena_np_flipud.jpg')
# 上下

Image.fromarray(np.fliplr(img)).save('data/dst/lena_np_fliplr.jpg')
# 左右

Image.fromarray(np.flip(img, (0, 1))).save('data/dst/lena_np_flip_ud_lr.jpg')
# 上下左右

参考Link

关于tqdm

在使用tqdm时,我们经常会像知道运行进度,具体来说就是,在循环中开始处理第i个数据的时候打印当前的i的index来获取进度。但是使用print经常会造成process bar变成很多条,这样既不美观也不利于查看进度,这里有一个方法可以把多个bar合成一个,并且在bar的前端输出一个以i的index作为输入的简短信息,具体如下

from tqdm import tqdm
import time

x = tqdm(range(10))
for i in x:
    x.set_description("Processing %s" % i)
    time.sleep(1)

出处来源

Tmux命令及快捷键记录

1.Tmux命名并创建session
tmux new -s [session-name]
2.Tmux显示所有session
tmux ls
3.Tmux断开当前对话的快捷键
先按tmux+b(tmux所有快捷键以这个组合为prefix),然后注意是松开手之后才按b来断开对话
4.Tmux重新连接对话
tmux at -t [session-name]
或者通过下面的可以连接最近关闭的对话
tmux a
5.Tmux杀死对话
tmux kill-ses -t [session-name]
6.Tmux跳出输入,上下翻页快捷键
先按tmux+b,然后按[来进行上下翻页模式,退出模式是按esc键 7.Tmux分割pane
ctrl+b + % 水平分割窗口(注意mac要打这个字符是shift+符号位即数字5)
ctrl+b + " 垂直分割窗口(注意mac要打这个字符是shift+符号位即数字2)
8.Tmux切换pane
ctrl+b + 上下左右键
9.关闭pane
ctrl+b + x
10.调整pane的size
ctrl+b, then Esc + (arrow key)
11.修改session名称
ctrl+b + $, then input new name
12.自动调整pane的宽度和高度

Ctrl+b esc+1             # vertical split, all panes same width, 主要用到的是这个自动调节等宽的方法
Ctrl+b esc+2             # horizontal split, all panes same height
Ctrl+b esc+3             # horizontal split, main pane on top, other panes on bottom, vertically split, all same width
Ctrl+b esc+4             # vertical split, main pane left, other panes right, horizontally split, all same height
Ctrl+b esc+5             # tile, new panes on bottom, same height before same width