itchatmp

  • itchat是个微信机器人,作者通过微信网页版抓的接口
  • itchatmp是对应的微信公众号的机器人,微信官方提供的接口,但相比于itchat,不太完善,文档也不行
  • 我已经要放弃这个了,这里只记录一下我修改nginx配置的过程
  1. itchatmp.run(port=8180),这里首先要指定端口
  2. 微信公众号的配置页面里,写上对应的域名,yongxinxue.xin/weixin,由于我根域名被占了,所以建立了个新路径
  3. nginx里增加配置,这里简单说一下last和break的区别
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    server {
    listen 80;
    server_name _;

    location / {
    ...
    }
    location /weixin {
    rewrite /weixin/(.*) /$1 break;
    proxy_pass http://127.0.0.1:8180/;
    }
    }

rewrite break 重写后,直接使用当前资源,不再执行location里余下的语句,完成本次请求,地址栏url不变
rewrite last 重写后,马上发起一个新的请求,再次进入server块,重试location匹配,超过10次匹配不到报500错误,地址栏url不变

werobot

  • 看着更成熟一点,后面再看,这里

  • 反正已经加到这么晚了,索性再水一篇博客再走
  • 如何把bmp和png批量转换成jpg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import os
from PIL import Image

for root, dirs, files in os.walk("."):
for bmpfig in files:
if not bmpfig.endswith('.bmp') and not bmpfig.endswith('.png'):
continue
bmpfig = os.path.join(root, bmpfig)
newfigname = bmpfig[:-4] + ".jpg"
print "converting from", bmpfig, "to", newfigname
img = Image.open(bmpfig)
img = img.convert('RGB') # for png
img.save(newfigname, format='jpeg', quality=95)
img.close()
os.remove(bmpfig)
  • 这段代码贴在某个文件夹下,运行之后会递归地把所有bmp转换成jpg
  • 其中,quality是生成jpg的质量,quality越大,jpg文件越大,图片细节越清晰,取值0-100

啰嗦一下

  • 在mac下,使用vscode,使用汉字输入法,删除完后,会多一个退格符!而且这个退格符默认是不可见的!
  • 过年在家写论文的时候,就发现xetex莫名其妙不能编译,说是多了字符,苦于不知道这个字符是啥,也不知道怎么描述这个现象,一直没有找到原因。
  • 就在今天,我配置博客的搜索的时候,又被这个bug给搞了,看别人的解释说是生成的检索文件里,多了BS(unicode)这个字符,终于顺着这个BS,我找到了困扰我半年的bug。
  • 十分激动,以至于我一改冷淡的文风,在大半夜里啰嗦这么多。

vscode并不打算修

  • 参考这里的说明。

    vscode底层使用了electron,这是electron的bug,electron不解决这个问题,vscode就不会解决。
    electron底层使用了chromium, 这是chromium的bug,chromium不解决,elctron就无法解决。

  • 非常稳,于是这个bug还是open的

补救措施

  • 首先让这个字符显示出来
1
"editor.renderControlCharacters": true
  • 使用插件 Remove backspace control character,并如下配置,这样在保存文件的时候,会自动帮你删除这些控制符
1
“editor.formatOnSave”: true 

丑陋的编码

python中有很多地方涉及到编码,简直丑陋

  • 文本编辑器可以选编码格式,一般都位于右下角
  • python文件开头有#coding: utf-8
  • python还有默认encoding
    1
    2
    3
    import sys
    reload(sys)
    sys.setdefaultencoding('utf-8')
  • 字符串前有u和b

一些编码知识

  • unicode是个大集合,支持百万级别的字符,但unicode只是给每个字符进行了一个编码,没有给具体实现
  • utf-8是unicode的一种实现形式,除此之外还有utf-16等等
  • gb系列的编码和unicode没啥关系,GB2312 < GBK < GB18030
  • windows中文版系统的默认编码是gbk的

一些python的知识

  • python里有三种string类,unicode(text string)、str(byte string)、basestring。basestring是前两个的父类
  • python里,字节串就等同于字符串
  • 在类型转换或和文本拼接时,需要确定字节串的编码,不然就不能转换。python2的年代,默认的encoding是ASCII,放现在当然是不够用的
  • python3终于把默认的编码变成unicode
  • str转换成unicode,在python里叫decode,unicode转换成str称之为encode
  • 打印unicode是不会出错的,这就是python3的厉害,打印str的话,就要看打印编码式和你显示的编码是否一致了

这些编码的区别

  • 文本编码格式:只和你的编辑器有关,负责把你的python文件按这种格式保存
  • python文件开头的coding:告诉python解释器,文件是按什么格式保存的,所以要与你实际文件的保存格式一致。如果不写的话,python文件里只能有ASCII
  • 默认的encoding格式就是你要告诉系统,字节码以哪种格式转换成unicode
  • u是指后面引号里的内容是unocide,b是指引号里面的内容是str,所以python3里写u是没用的,python2里写b是没用的

最佳实践

  • 换python3
  • 如果换不了python3
    • 所有 text string 都应该是 unicode 类型,而不是 str
    • 在需要转换的时候,显式转换。从字节解码成文本,用 var.decode(encoding),从文本编码成字节,用 var.encode(encoding)
    • 从外部读取数据时,默认它是字节,然后 decode 成需要的文本;同样的,当需要向外部发送文本时,encode 成字节再发送。

论文常看常忘,还是把看过的先记下来,再补充总结

NET

pvanet

  • pvanet是为了实时目标识别提出来的网络,用来提取特征的,用了很多方法来减小计算量,看起来像个大杂烩
  • C.ReLU,由于观察到浅层的网络卷基层总是存在互补层,所以直接把卷积取反再concatenate,可以减少一半的计算量
  • Inception,使用了inception unit,用两个3*3的卷集合替代了5*5的卷积,也是为了减小计算量
  • HypteNet多层融合,融合哪两层是比较讲究的,选择不好的话,会白白增加计算量。这里作者使用了最后输出层2倍和4倍多layer进行融合,以2倍的layer为标准,分别pooling和差值upscale。
  • ResNet,再inception unit里也用了残差网络。
  • 整个网络结构如下表

pvanet

  • pvanet里还提到了一种学习策略,动态调整学习率,如果一定的迭代次数内,loss下降小于阈值,就说明是on plateau,这时候就降低学习率。在github上有人实现,只不过没有被merge进来。

mobilenet

shufflenet

densenet

  • 每一层都有来自前面所有层的输入,L个层,就是$\frac{L*(L+1)}{2}$个连接。
  • Each layer has direct access to the gradients from the loss function and the original input signal, leading to an implicit deep supervision.
  • resNet中,l层的输出是l-1的非线性加l-1

$$x_l = H_l(x_{l-1}) + x_{l-1}$$

  • denseNet中,是直接做的concatenate

$$x_l = H_l([x_0, x_1, …, x_{l-1}])$$

  • denseNet中包含三个dense block,如下图所示(盗图自这里

dense block

  • 整个网络的结构图如下

dense net

  • 由于denseNet是concatenate,所以到最后一层的时候,channel会异常地大,所以每个3*3卷积前,会有个1*1的bottle neck层,减小channel数量

  • dense block之间还有transition层,也是用1*1的卷积减小channel数

Attention 和 CTC

Attention is all you need
CTC

text localization

EAST

  • 用于文本检测,输出可以是四边形或rotated box

east

  • 最左边用的是PVANet,也可以换成其他ResNet什么的
  • 然后中间是特征融合,这里作者借鉴了U-net的做法,用到了unpool,原因是文字有大有小,需要有不同的感受野
  • 最后是输出层,包括score map和位置信息,输出的size是原图的1/4大小
  • score对应的ground truth: 是将原始的bounding box按照短边长度r向内收缩了0.3r的距离。不懂为什么要这么做
  • 针对bounding box内部的每个点,计算他们到上下左右四个边的距离,并且计算角度。针对bounding box外部的点,ground truth置为0
  • loss包含两个部分,score map的loss和位置坐标的loss
  • score的loss使用的是balanced cross entropy,可以配合正负样本不均衡的情况

$$ L_s = -\beta Y^* log(\hat{Y}) - (1-\beta)(1-Y^*)log(1-\hat{Y})$$
$$ \beta = 1 - \frac{\sum_{y^* \in Y^*} y^*}{|Y^*|}$$

  • 位置坐标的loss我只看了rotated box的,又可以分成两个部分,iou的loss和角度的loss,角度的loss前面会乘个系数,10或者20,是个超参数

InceptText from Alibaba, IJCAI2018

text recognition

FAN
Edit Probability

OCR end2end

an end to end textspotter with explicit aligment and attention, ICCV2018
Textbox++

OCR 综述

Text Detection and Recognition in Imagery: A Survey

Character Segmentation

A Gradient Vector Flow-Based Method for Video Character Segmentation, ICDAR201z1

GAN and Draw

General CV

YOLO

SSD

Faster rcnn

mask rcnn

FCN

  • FCN里用到了三个技术,全卷积、上采样和跳层链接
  • 全卷积:一般的CNN最后会有全连接层,把二维的图像压缩成以为的向量,FCN把全连接换成了卷积,实际上计算上是等价的。

fcn

  • 上采样:或者叫反卷积、转置卷积(Caffe和Kera里叫Deconvolution,tensorflow里叫conv_transpose)。
  • 跳层连接:将全卷积之后的结果直接上采样得到的结果是很粗糙的,所以用不同池化层的结果进行上采样之后来优化输出。

fcn2

  • 原文感觉不好看,主要参考了这里

deeplab

Visualization

Understanding neural Networks Through Deep Visualization

源文章标题取得很大,write a shell in c。相关的内容总结如下。

  • fork(), exec() and waitpid() are defined by the POSIX standard, and Windows is not POSIX-compliant. In order to have POSIX compliance under Windows, you should compile under Cygwin.

  • fork, exec, chdir are in unistd.h(unix std); execvp is in stdlib

  • system命令相当于 fork + exec + waitpid

  • windows也提供了一个chdir函数,叫_chdir,在direct.h里

  • cc来自于Unix的c语言编译器,是 c compiler 的缩写。gcc来自Linux世界,是GNU compiler collection 的缩写,注意这是一个编译器集合,不仅仅是c或c++

  • strtok()

    1
    2
    3
    4
    5
    6
    char sentence[]="192.168...9...14";
    char *token=strtok(sentence,".");
    while(token!=NULL){
    cout<<token<<" ";
    token=strtok(NULL,".");
    }
  • 在gcc编译器中,对标准库进行了扩展,加入了一个getline函数。会自动malloc, realloc,所以用的话,需要自己手动free,好像没啥人用,参考这里

  • 我用system代替了fork等,于是有了window版

评论

gitment

  • gitment是挂在github的issue上,从github给的api上提交和拉取评论,然后界面(应该)是作者自己做的。
  • 当然好处是只能github账号登陆,坏处的话,issue会很乱吧。。。
  • 具体操作:可以看这里,就是先注册个application,然后把id、secret什么的填到next的config里就好。
  • 坑:Error:validation failed。原因是作者的方法在create an issue时,提交的id号太长了。。。方法是在next/_third-party/comments/gitment.swig里,修改id: window.location.pathnameid: '{{ page.date }}'

valine

  • 是我目前见到过的唯一支持匿名评论的,也是需要注册valine的账号

搜索

Swiftype

  • 去注册账号,拿到swiftype_key,写道next的配置里就好
  • 后来才这道这个是要收费的,不要用了

local search

  • npm install --save hexo-generator-search
  • 在主题的config里,local_search的enable要打开
  • 在hexo的config里,写上
1
2
3
search:
path: search.xml
field: post(或者all)
  • 最后hexo g就可以了

代码

  • 修改hexo的配置
1
2
3
4
5
highlight:
enable: true
line_number: true
auto_detect: false
tab_replace:
  • 然后在next的配置里修改代码配色
1
highlight_theme: night bright
  • 写代码的时候,要注意在```后加上代码类型如c、python、yml等等

公式

  • 在next的config里,enable mathjax
  • 行内公式用$,行间公式用$$
  • 但是还有些问题,比如说公式里有两个_,hexo会优先按markdown给你解析成斜体,所以latex公式还不能直接抄,有些富豪需要转义
  • 当然,也有优雅的方法,换个render
1
2
npm uninstall hexo-renderer-marked --save
npm install hexo-renderer-kramed --save
  • 更换完了行内公式还是有问题,参考这里
  • 修改kramed的转义规则,文件为/node_modules/kramed/lib/rules/inline.js
1
2
escape: /^\\([`*\[\]()# +\-.!_>])/,
em: /^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
  • mathjax公式粗体,放弃\bm{},使用\boldsymbol{}

流程图

1
npm install --save hexo-filter-flowchart

一些图像操作

膨胀腐蚀都是针对亮色区域说的,膨胀是取最大值,腐蚀是最小值,实现的话,最直接的方法是四个for循环

  • 开运算:腐蚀+膨胀,可以去除图中的小白点;闭运算:膨胀+腐蚀,可以去除图片中的小黑点

  • top hat:原图-开,得到的是开运算中被去掉的小白点;black hat:原图-闭,得到闭运算中去掉的小黑点

  • 霍夫线变换

  • 直方图均衡化

1
2
3
4
5
6
cv::equalizeHist(srcmat, dstmat);

cv::Mat lookup(1, 256, CV_8U);
// p[i] 是强度小于等于i的比例
lookup.at<uchar>(i) = static_cast<uchar>(255.0 * p[i]);
dstmat = applyLookUp(srcmat, lookup);

C的接口

  • 字体的说明参考这里
  • cvReleaseImage,只是将IplImage*型的变量值赋为NULL,而这个变量本身还是存在的并且在内存中的存储位置不变
  • iplimg->imageSize == iplimg->height * iplimg->widthStep,而不是frame->height * frame->width
  • iplimg->imageData是对齐的内存,官方文档iplimg->imageDataOrigin是没有对齐的内存,还没有验证过
  • 默认的存储方式是BGR,不是RGB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 读图
IplImage* iplimg = cvLoadImage("heels.jpg");

// 把cv::mat改为c的图
*iplimg = IplImage(matimg);

// 创建新图,最后一个参数是channel数
IplImage* iplimg=cvCreateImage(cvSize(360, 640), IPL_DEPTH_8U, 3);

// 显示图
cvNamedWindow("img", 0);
cvShowImage("img", iplimg);
cvWaitKey(0);

// 打印字
CvFont font;
cvInitFont(&font, CV_FONT_HERSHEY_COMPLEX, 0.5, 0.5, 1, 2, 8);
cvPutText(iplimg, "This is a picture named lena!", cvPoint(50, 50), &font, CV_RGB(255,0,0));

// 保存图
cvSaveImage("c:\\test1.jpg", iplimg);

C++的接口

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
// 读图
cv::Mat matimg = cv::imread ("heels.jpg");

// 把IplImage改为c++接口,第二个参数是需不需要拷贝,默认是false
matimg = cv::Mat(iplimg, false);

// 创建新图,CV_8UC3是三通道,CV_8UC1是单通道
cv::Mat matimg(2, 2, CV_8UC3, Scalar(0,255,0));

// 显示图
cv::nameWindow("img");
cv::imshow("img", matimg);
cv::waitKey(-1);

// 打印字
// void putText(Mat& img, const string& text, Point org, int fontFace, double fontScale, Scalar color, int thickness=1, int lineType=8, bool bottomLeftOrigin=false )
cv::putText(image, "opencv", Point(5,100), FONT_HERSHEY_DUPLEX, 1, Scalar(0,143,143), 2);

// 保存图,后缀名决定了图片对编码格式
cv::imwrite("c:\\test1.jpg", matimg);

// 遍历图像
// Vec3b表示三通道usigned char类型,
// 还可以有2通道和4通道,类型还可以有f(loat)、i(nt)、d(ouble)、s(hort)、w(unsigned short)
// typedef Vec<float, 2> Vec2f;
matimg.at<cv::Vec3b>(j,i)[channel] = value;

// 还可以直接取每一行对首地址
uchar* data = matimg.ptr<uchar>(j);

头文件分析

  • 一般直接包含这三个头文件
1
2
3
#include<opencv2/core/core.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>

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
#include<iostream>
#include<fstream>
#include<cstring>

using namespace std;

int main(int argc, char* argv[])
{
using namespace std;
if (argc < 3){
cout << "filename missed" << endl;
return 0;
}
ifstream in(argv[1], ios::binary | ios::in);
if (!in){
cout << "source file open failed" << endl;
return 0;
}
ofstream out(argv[2], ios::binary | ios::out); //打开文件用于写
if (!out) {
cout << "New file open error." << endl;
in.close(); //打开的文件一定要关闭
return 0;
}
if (strcmp(argv[1], argv[2])==0) {
cout << "the src file can't be same with dst file" << endl;
exit(EXIT_FAILURE);
}
char buf[2048];
while (in)
{
//read从in流中读取2048字节,放入buf数组中,同时文件指针向后移动2048字节
//若不足2048字节遇到文件结尾,则以实际提取字节读取。
in.read(buf, 2048);
//gcount()用来提取读取的字节数,write将buf中的内容写入out流。
out.write(buf, in.gcount());
}
//char c;
//while (in.get(c)){
// out.put(c);
//}
in.close();
out.close();
}

步骤

  • 先去boost官方网站中查看boost的最新版本,然后去相应的链接地址进行下载
  • 在你创建好的工程项目中,选择属性对话框,然后在VC++目录选项中,把boost路径添加到包含目录和库目录中
  • 首选运行bootstra.bat,如果没有cl命令的话,查看这里,我是这个命令call "%VS120COMNTOOLS%"vsvars32.bat解决问题
  • 生成动态链接的静态库bjam address-model=64 link= static threading=multi variant=release runtime-link=shared stage

困惑的地方

  • vs里面的vc++目录和下面的c++目录、连接器目录,什么关系啊,能自动加载子目录?

引用自这里
VC++ Directories是一个Windows环境变量,C/C++是命令行参数,这是本质区别;
但是相同的项,也就是VC++ Directories中的include directories 对应到C/C++中的addition include directories 是一样的效果,也就是说效果一样。同样是命令行参数的还有Link设置,Link设置中的 addition library directories对应到VC++ Directories 中的library directories,也就是说,效果是相同的。

  • bjam里面的debug release、static share是啥。。。

编译调试版本加 debug

编译发布版本加 release

编译静态链接库:link=static runtime-link=static

编译动态库:link=shared runtime-link=shared

静态库只是需要的文件编译到exe/so中,而且shared的是否用户也要存在dll,所以static是更安全的方式;当然组件式开发和升级的软件用shared方式更加合适

参考

0%