嵌入式程序调试与opencv图像库
在Ubuntu系统上练习程序代码的GDB调试
构建一个函数实现对一个整型数的反转功能,比如输入123,则输出321。
lee@ubuntu:~$ vi RevertNum.c
其中代码
#include <stdio.h>
void ShowRevertNum(int iNum)
{
while (iNum > 10)
{
printf("%d", iNum % 10);
iNum = iNum / 10;
}
printf("%d\n", iNum);
}
int main(void)
{
int iNum;
printf("Please input a number :");
scanf("%d", &iNum);
printf("After revert : ");
ShowRevertNum(iNum);
}
发现输入100时,程序的输出结果却不正确
进行gdb调试排查问题
lee@ubuntu:~$ gcc -o RevertNum -g RevertNum.c
lee@ubuntu:~$ gdb RevertNum
GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from RevertNum...done.
显示代码及行号
(gdb) l
1 #include <stdio.h>
2 void ShowRevertNum(int iNum)
3 {
4 while (iNum > 10)
5 {
6 printf("%d", iNum % 10);
7 iNum = iNum / 10;
8 }
9 printf("%d\n", iNum);
10 }
(gdb) list
11 int main(void)
12 {
13 int iNum;
14 printf("Please input a number :");
15 scanf("%d", &iNum);
16 printf("After revert : ");
17 ShowRevertNum(iNum);
18 }
通过行号设置断点
(gdb) b 16
Breakpoint 1 at 0x7d7: file RevertNum.c, line 16.
通过函数名设置断点
(gdb) b ShowRevertNum
Breakpoint 2 at 0x725: file RevertNum.c, line 4.
查看所有断点信息
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000000007d7 in main at RevertNum.c:16
2 breakpoint keep y 0x0000000000000725 in ShowRevertNum
at RevertNum.c:4
执行程序(输入100)
(gdb) run
Starting program: /home/lee/RevertNum
Please input a number :100
Breakpoint 1, main () at RevertNum.c:16
16 printf("After revert : ");
查看iNum类型
(gdb) whatis iNum
type = int
(gdb) print iNum
$1 = 100
继续执行
gdb) c
Continuing.
Breakpoint 2, ShowRevertNum (iNum=100) at RevertNum.c:4
4 while (iNum > 10)
打印iNum的值
(gdb) p iNum
$2 = 100
单步调试
(gdb) s
6 printf("%d", iNum % 10);
(gdb) s
__printf (format=0x555555554894 "%d") at printf.c:28
28 printf.c: 没有那个文件或目录.
opencv
ubantu16安装并配置oepncv3.4.1
找到对应版本选择下载sources
将下载的zip文件复制到主目录
在终端中解压zip
lee@ubuntu:~$ unzip opencv-3.4.1.zip
进入文件夹
lee@ubuntu:~$ cd opencv-3.4.1
安装cmake
lee@ubuntu:~/opencv-3.4.1$ sudo apt-get install cmake
安装依赖库
lee@ubuntu:~/opencv-3.4.1$ sudo apt-get install build-essential libgtk2.0-dev libavcodec-dev libavformat-dev libjpeg.dev libtiff5.dev libswscale-dev libjasper-dev
出现报错
正在读取软件包列表... 完成
正在分析软件包的依赖关系树
正在读取状态信息... 完成
注意,根据正则表达式 'libjpeg.dev' 选中了 'libjpeg-dev'
注意,根据正则表达式 'libtiff5.dev' 选中了 'libtiff5-dev'
E: 无法定位软件包 libjasper-dev
解决:
sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main"
sudo apt update
sudo apt install libjasper1 libjasper-dev
再次输入安装依赖库代码,可以发现以及安装成功
lee@ubuntu:~/opencv-3.4.1$ sudo apt-get install build-essential libgtk2.0-dev libavcodec-dev libavformat-dev libjpeg.dev libtiff5.dev libswscale-dev libjasper-dev
正在读取软件包列表... 完成
正在分析软件包的依赖关系树
正在读取状态信息... 完成
注意,根据正则表达式 'libjpeg.dev' 选中了 'libjpeg-dev'
注意,根据正则表达式 'libtiff5.dev' 选中了 'libtiff5-dev'
build-essential 已经是最新版 (12.4ubuntu1)。
libgtk2.0-dev 已经是最新版 (2.24.32-1ubuntu1)。
libjpeg-dev 已经是最新版 (8c-2ubuntu8)。
libtiff5-dev 已经是最新版 (4.0.9-5ubuntu0.3)。
libavcodec-dev 已经是最新版 (7:3.4.8-0ubuntu0.2)。
libavformat-dev 已经是最新版 (7:3.4.8-0ubuntu0.2)。
libswscale-dev 已经是最新版 (7:3.4.8-0ubuntu0.2)。
libjasper-dev 已经是最新版 (1.900.1-debian1-2.4ubuntu1.2)。
升级了 0 个软件包,新安装了 0 个软件包,要卸载 0 个软件包,有 131 个软件包未被升级。
创建编译文件夹
lee@ubuntu:~/opencv-3.4.1$ mkdir my_build_dir
进入文件夹进行配置
lee@ubuntu:~/opencv-3.4.1$ cd my_build_dir
进行cmake
lee@ubuntu:~/opencv-3.4.1/my_build_dir$ cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..
编译
lee@ubuntu:~/opencv-3.4.1/my_build_dir$ sudo make
下载完成
[100%] Building CXX object apps/interactive-calibration/CMakeFiles/opencv_interactive-calibration.dir/main.cpp.o
[100%] Building CXX object apps/interactive-calibration/CMakeFiles/opencv_interactive-calibration.dir/parametersController.cpp.o
[100%] Building CXX object apps/interactive-calibration/CMakeFiles/opencv_interactive-calibration.dir/rotationConverters.cpp.o
[100%] Linking CXX executable ../../bin/opencv_interactive-calibration
[100%] Built target opencv_interactive-calibration
Scanning dependencies of target opencv_version
[100%] Building CXX object apps/version/CMakeFiles/opencv_version.dir/opencv_version.cpp.o
[100%] Linking CXX executable ../../bin/opencv_version
[100%] Built target opencv_version
执行命令
lee@ubuntu:~/opencv-3.4.1/my_build_dir$ sudo make install
将opencv的库添加到路径,出现一个空白文件,在文件末尾编辑写入/usr/local/lib
lee@ubuntu:~/opencv-3.4.1/my_build_dir$ sudo gedit /etc/ld.so.conf.d/opencv.conf
使路径生效
lee@ubuntu:~/opencv-3.4.1/my_build_dir$ sudo ldconfig
配装bash,在打开的文件末尾编辑写入PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
export PKG_CONFIG_PATH
lee@ubuntu:~/opencv-3.4.1/my_build_dir$ sudo gedit /etc/bash.bashrc
使配置生效
lee@ubuntu:~/opencv-3.4.1/my_build_dir$ source /etc/bash.bashrc
更新
lee@ubuntu:~/opencv-3.4.1/my_build_dir$ sudo updatedb
至此所有配置完成
编写一个打开图片进行特效显示的代码 test1.cpp
在opencv-3.4.1下新建文件夹mytest
lee@ubuntu:~$ cd opencv-3.4.1
lee@ubuntu:~/opencv-3.4.1$ mkdir mytest
创建text.cpp
touch test.cpp
进入编程
sudo gedit /test.cpp
#sudo vim /test.cpp
#根据自己配置编辑器进行编辑
源码
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
CvPoint center;
double scale = -3;
IplImage* image = cvLoadImage("lena.jpg");
argc == 2? cvLoadImage(argv[1]) : 0;
cvShowImage("Image", image);
if (!image) return -1; center = cvPoint(image->width / 2, image->height / 2);
for (int i = 0;i<image->height;i++)
for (int j = 0;j<image->width;j++) {
double dx = (double)(j - center.x) / center.x;
double dy = (double)(i - center.y) / center.y;
double weight = exp((dx*dx + dy*dy)*scale);
uchar* ptr = &CV_IMAGE_ELEM(image, uchar, i, j * 3);
ptr[0] = cvRound(ptr[0] * weight);
ptr[1] = cvRound(ptr[1] * weight);
ptr[2] = cvRound(ptr[2] * weight);
}
Mat src;Mat dst;
src = cvarrToMat(image);
cv::imwrite("test.png", src);
cvNamedWindow("test",1); imshow("test", src);
cvWaitKey();
return 0;
}
将一张图片复制到mytest,将名字改为lena.jpg
编译
lee@ubuntu:~/opencv-3.4.1/mytest$ g++ /test.cpp -o test `pkg-config --cflags --libs opencv`
执行
lee@ubuntu:~/opencv-3.4.1/mytest$ ./test
弹出处理后的图片
摄像头
创建lt.cpp
lee@ubuntu:~/opencv-3.4.1/mytest$ touch lt.cpp
进入编程
lee@ubuntu:~/opencv-3.4.1/mytest$ sudo gedit /lt.cpp
源代码
/*********************************************************************
打开电脑摄像头,空格控制视频录制,ESC退出并保存视频RecordVideo.avi
*********************************************************************/
#include<iostream>
#include <opencv2/opencv.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
int main()
{
//打开电脑摄像头
VideoCapture cap(0);
if (!cap.isOpened())
{
cout << "error" << endl;
waitKey(0);
return 0;
}
//获得cap的分辨率
int w = static_cast<int>(cap.get(CV_CAP_PROP_FRAME_WIDTH));
int h = static_cast<int>(cap.get(CV_CAP_PROP_FRAME_HEIGHT));
Size videoSize(w, h);
VideoWriter writer("RecordVideo.avi", CV_FOURCC('M', 'J', 'P', 'G'), 25, videoSize);
Mat frame;
int key;//记录键盘按键
char startOrStop = 1;//0 开始录制视频; 1 结束录制视频
char flag = 0;//正在录制标志 0-不在录制; 1-正在录制
while (1)
{
cap >> frame;
key = waitKey(100);
if (key == 32)//按下空格开始录制、暂停录制 可以来回切换
{
startOrStop = 1 - startOrStop;
if (startOrStop == 0)
{
flag = 1;
}
}
if (key == 27)//按下ESC退出整个程序,保存视频文件到磁盘
{
break;
}
if (startOrStop == 0 && flag==1)
{
writer << frame;
cout << "recording" << endl;
}
else if (startOrStop == 1)
{
flag = 0;
cout << "end recording" << endl;
}
imshow("picture", frame);
}
cap.release();
writer.release();
destroyAllWindows();
return 0;
}
编译并执行
g++ lt.cpp -o lt `pkg-config --cflags --libs opencv`
./lt
主目录出现一个视频