文章目录
  1. 1. Install OpenCV on Ubuntu
  2. 2. Test it
  3. 3. Install curl on Ubuntu
  4. 4. Test both together
  5. 5. Reference

最近一直在做老板的一个摄像头跟踪的项目,需要在linux上完成编译和运行,OpenCV 3.x在linux上的编译需要使用cmake的方式,同时需要配置curl库文件。我刚开始在配置时饶了很多弯路,现在分享出来,供大家参考。

Install OpenCV on Ubuntu

说明下我的系统环境:Ubuntu 14.04 LTS 64 bits。在开始之前,有必要更新下系统,相信大家都不陌生

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

1.安装OpenCV必要的依赖文件
话不多说,运行下面的命令

1
sudo apt-get -y install libopencv-dev build-essential cmake git libgtk2.0-dev pkg-config python-dev python-numpy libdc1394-22 libdc1394-22-dev libjpeg-dev libpng12-dev libtiff4-dev libjasper-dev libavcodec-dev libavformat-dev libswscale-dev libxine-dev libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev libv4l-dev libtbb-dev libqt4-dev libfaac-dev libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev libtheora-dev libvorbis-dev libxvidcore-dev x264 v4l-utils unzip

2.下载OpenCV安装文件
你可以自己手动下载,也可以使用下面的命令来下载

1
2
3
4
mkdir opencv
cd opencv
wget https://github.com/Itseez/opencv/archive/3.1.0.zip -O opencv-3.1.0.zip
unzip opencv-3.1.0.zip

3.安装OpenCV
使用Cmake安装编译时有许多可选项,根据自己的需要选择。如果你想要安装Qt 5.x那么不要使用-D WITH_QT=ON,参见how to use OpenCV 3 on Qt 5.3

1
2
3
4
5
6
cd opencv-3.1.0
mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_TBB=ON -D WITH_V4L=ON -D WITH_QT=ON -D WITH_OPENGL=ON ..
make -j $(nproc)
sudo make install

4.完成安装
将opencv配置文件链接到Ubuntu

1
2
sudo /bin/bash -c 'echo "/usr/local/lib" > /etc/ld.so.conf.d/opencv.conf'
sudo ldconfig

Test it

在测试之前,可以重启下系统,别着急,马上就好。
1.使用OpenCV 示例
首先,我们需要进入到示例目录,并使用cmake编译,然后运行看看

1
2
3
cd opencv/opencv-3.1.0/samples/
sudo cmake .
sudo make -j $(nproc)

现在可以运行任意一个示例了,选择一个吧

1
2
3
cd cpp/
./cpp-example-facedetect lena.jpg // (../data/lena.jpg)
./cpp-example-houghlines pic1.png // (../data/pic1.jpg)

2.编译并运行我们自己的代码
在含有代码cpp文件以及cmakelist的项目目录里(建议在该目录下新建目录再编译运行)

1
2
3
cmake .
make
./yourprogram

Install curl on Ubuntu

1.下载curl库文件

1
2
3
4
mkdir curl
cd curl
wget https://curl.haxx.se/download/curl-7.47.1.tar.gz
tar -xzvf curl-7.47.1.tar.gz

2.安装curl库

1
2
3
4
5
cd curl-7.47.1
./configure --prefix=/usr/local/curl
make
sudo make install
vi /etc/profile (添加export PATH=$PATH:/usr/local/curl/bin)

3.测试下

1
curl --version

看是否返回刚刚安装的版本号。

Test both together

这里我使用一个项目初始代码来测试。

1
2
3
4
mkdir test
cd test
touch main.cpp
touch CMakeLists.txt

main.cpp是我的主程序文件,CMakeLists.txt是cmake编译所需文件。

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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
[main.cpp]
*实现从给定IPIP Camera中获取图像并保存成图片,同时可以使摄像头跟随镜头前运动物体的方向运动*
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <curl/curl.h>

using namespace std;
using namespace cv;

char ip[32];
int x_center, y_center;

// Check if there is motion in the result matrix
// count the number of changes and return.
inline int detectMotion(const Mat & motion, Mat & result, Mat & result_cropped,
int x_start, int x_stop, int y_start, int y_stop,
int max_deviation,
Scalar & color)
{
int Direction = 0;
// calculate the standard deviation
Scalar mean, stddev;
meanStdDev(motion, mean, stddev);
// if not to much changes then the motion is real (neglect agressive
// snow, temporary sunlight)
if(stddev[0] < max_deviation)
{
int number_of_changes = 0;
int min_x = motion.cols, max_x = 0;
int min_y = motion.rows, max_y = 0;
// loop over image and detect changes
for(int j = y_start; j < y_stop; j+=2){ // height
for(int i = x_start; i < x_stop; i+=2){ // width
// check if at pixel (j,i) intensity is equal to 255
// this means that the pixel is different in the sequence
// of images (prev_frame, current_frame, next_frame)
if(static_cast<int>(motion.at<uchar>(j,i)) == 255)
{
number_of_changes++;
if(min_x>i) min_x = i;
if(max_x<i) max_x = i;
if(min_y>j) min_y = j;
if(max_y<j) max_y = j;
}
}
}
if(number_of_changes){
//check if not out of bounds
if(min_x-10 > 0) min_x -= 10;
if(min_y-10 > 0) min_y -= 10;
if(max_x+10 < result.cols-1) max_x += 10;
if(max_y+10 < result.rows-1) max_y += 10;
// draw rectangle round the changed pixel
Point x(min_x,min_y);
Point y(max_x,max_y);

x_center = (min_x + max_x) / 2;
y_center = (min_y + max_y) / 2;

Rect rect(x,y);
Mat cropped = result(rect);
cropped.copyTo(result_cropped);
rectangle(result,rect,color,1);
}

return number_of_changes;
//return Direction;
}
return 0;
}

/*
* Move camera, dir: direction, 0:up, 1:stop up, 2:down, 3:stop down,
* 4:left, 5:stop left, 6:right, 7:stop right
*/
void moveCamera(int dir, int degree)
{
CURL *c;
char cmd[128];
memset(cmd, 0, 128);
sprintf(cmd, "http://192.168.1.115:81/decoder_control.cgi?loginuse=admin&loginpas=&command=%d&onestep=0&%d", dir, degree);
c = curl_easy_init();
curl_easy_setopt(c, CURLOPT_URL, cmd);
curl_easy_perform(c);
curl_easy_cleanup(c);
}

void moveCameraUp(int degree)
{
moveCamera(0, degree);
}

void moveCameraDown(int degree)
{
moveCamera(2, degree);
}

void moveCameraLeft(int degree)
{
moveCamera(4, degree);
}

void moveCameraRight(int degree)
{
moveCamera(6, degree);
}

void moveCameraStop(int degree)
{
moveCamera(1, degree);
}

int main(int argc, char** argv)
{
char addr[128];
strcpy(ip, argv[1]);
sprintf(addr, "http://192.168.1.115:81/videostream.cgi?loginuse=admin&loginpas=&.mjpg", ip);
const std::string videoStreamAddress = addr;

int thre_width = 100;
int threshold_height = 60;

VideoCapture cap(videoStreamAddress); // open the default camera
if(!cap.isOpened()) // check if we succeeded
return -1;


cv::Mat result, result_cropped, prev_frame, next_frame, current_frame, d1, d2, motion;
int number_of_changes, number_of_sequence = 0;
Scalar mean_, color(0, 0, 255); //yellow mark

cap >> prev_frame;
result = prev_frame;

cap >> current_frame;

cap >> next_frame;

cvtColor(current_frame, current_frame, CV_RGB2GRAY);
cvtColor(prev_frame, prev_frame, CV_RGB2GRAY);
cvtColor(next_frame, next_frame, CV_RGB2GRAY);

int x_start = 10, x_stop = current_frame.cols - 11;
int y_start = 0, y_stop = current_frame.rows - 1, there_is_motion = 5, max_deviation = 20;

Mat kernel_ero = getStructuringElement(MORPH_RECT, Size(2,2));

for(;;) {
prev_frame = current_frame;
current_frame = next_frame;
if(!cap.read(next_frame)) {
std::cout << "No frame" << std::endl;
cv::waitKey();
}

result = next_frame;

cvtColor(next_frame, next_frame, CV_RGB2GRAY);

absdiff(prev_frame, next_frame, d1);
absdiff(next_frame, current_frame, d2);
bitwise_and(d1, d2, motion);

threshold(motion, motion, 35, 255, CV_THRESH_BINARY);
erode(motion, motion, kernel_ero);

number_of_changes = detectMotion(motion, result, result_cropped, x_start, x_stop, y_start, y_stop, max_deviation, color);

if (y_center > (result.rows / 2) + threshold_height)
{
moveCameraDown(1);
}
if (y_center < (result.rows / 2) - threshold_height)
{
moveCameraUp(1);
}
else
{
moveCameraStop(1);
}

if (x_center > (result.cols / 2) + thre_width)
{
moveCameraRight(1);
}
if (x_center < (result.cols / 2) - thre_width)
{
moveCameraLeft(1);
}
else
{
moveCameraStop(1);
}
cv::imshow("My Window", result);
waitKey(1);
}
return 0;
}



1
2
3
4
5
6
7
8
[CMakeLists.txt]
cmake_minimum_required(VERSION 2.8)
project(main)
add_executable(main main.cpp)
find_package(OpenCV REQUIRED)
find_package(CURL REQUIRED)
target_link_libraries(main ${CURL_LIBRARY})
target_link_libraries(main ${OpenCV_LIBS})

下面我们来编译运行一下,在test目录下

1
2
3
4
5
mkdir build
cd build
cmake ..(如需使用gdb调试使用 cmake -DCMAKE_BUILD_TYPE=Debug ..)

make
./main 192.168.1.xxx(ip)

如果上面的编译中没有出错,那么恭喜你,配置成功。

Reference

installing-opencv-3-0-0-on-ubuntu-14-04

文章目录
  1. 1. Install OpenCV on Ubuntu
  2. 2. Test it
  3. 3. Install curl on Ubuntu
  4. 4. Test both together
  5. 5. Reference