嵌入式程序调试和opencv图像库
一、在Ubuntu系统上练习程序代码的GDB调试
1、GDB简介
GDB : GNU Debugger,是GNU工程为GNU操作系统开发的
调试器,但它的使用不局限于GNU操作系统, GDB可以运行
在UNIX、Linux甚至Microsoft Windows。
GDB可以调试C、C++、Objective-C、Pascal、Ada等语言编
写的程序;被调试的程序可以跟GDB运行于同一台电脑,也可
运行于不同电脑。
使用GDB我们可以:
1、设置断点使程序停住
2、监视或修改程序中变量的值
3、跟踪代码执行过程
2、GDB的常用命令
命令 | 命令功能 |
---|---|
file | 装入想要调试的可执行文件 |
kill | 终止正在进行的调试程序 |
list | 列出产生执行文件的源代码的一部分 |
next | 执行一行源代码但不进入函数内部 |
step | 执行一行源代码并可以进入函数内部 |
run | 执行当前被调试的程序 |
c | 继续运行程序 |
quit | 终止gdb |
watch | 使你能监视一个变量的值而不管它何时被改变 |
backtrack | 栈跟踪,查看代码被谁调用 |
查看变量的值 | |
make | 不用退出gdb,就可以重新生成可执行文件 |
shell | 不用退出gdb,就可以使用UNIX shell命令 |
3、GDB的常见调试例子
(1)编写实现对一个整型数的反转功能的演示程序
创建文件
编写程序
编译文件
启动gdb
显示代码
按照行号设置断点
按照函数名设置断点
查看所有断点信息
执行程序
查看inum的类型
继续执行
打印inum的值
单步调试
退出gdb
运行程序
输入123,输出321,程序正确运行。
(2)内存出错的GDB调试
创建文件
编写程序
编译
执行
Linux中,程序崩溃时,一般会产生core文件,记录进程退出前
的状态,调试段错误问题,借助于该文件,可快速定位问题。
• 可按如下步骤生成和使用core文件
– Step 1: 让系统产生core文件
• ulimit –c num #设定core文件容量(num为数字,为0
是不产生core文件)
– Step 2: 运行程序,让程序崩溃,从而生成core文件
– Step 3: gdb配合core文件,定位问题
• gdb 程序名 core文件名
• 比如: gdb segDemo core
构建函数
编程
编译
利用core文件定位出错代码
小结:通过对在Ubuntu系统上练习程序代码的GDB调试,我更加清楚了GDB的常用命令和一些基础的调试的方法。很多地方参考了老师给出的课件示例,如果有什么不准确的地方,请多多海涵。
二、在Ubunt系统下练习编译、安装著名的C/C++图像处理开源软件库 Opencv3.x
安装教程可参考如下:
1、安装opencv3.4.10
通过官网地址下载opencv
ps:如果无法将安装包拷贝进虚拟机的话,可以安装VMware Tools ,详细步骤参考下面
将安装包移动到Home目录中
利用如下的代码将安装包解压
unzip opencv-3.4.1.zip
进入到解压后的文件目录中
cd opencv-3.4.1
安装依赖库和cmake
sudo apt-get install cmake
sudo apt-get install build-essential libgtk2.0-dev libavcodec-dev libavformat-dev libjpeg.dev libtiff5.dev libswscale-dev libjasper-dev
创建编译文件夹
mkdir my_build_dir
进入文件夹开始配置
cd my_build_dir
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..
执行命令,进较长的编译过程
sudo make
实际花费约20分钟(实际花费时间应与电脑性能挂钩)
执行如下命令,结束编译
sudo make install
配置OpenCV编译环境
sudo gedit /etc/ld.so.conf.d/opencv.conf
在文件末尾添加
/usr/local/lib
点击保持并退出
执行如下命令使得刚才的配置路径生效
sudo ldconfig
配置bash
sudo gedit /etc/bash.bashrc
末尾添加内容
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
export PKG_CONFIG_PATH
保存并退出
执行如下命令使得配置生效
source /etc/bash.bashrc
sudo updatedb
完成了opencv的所有配置。
2、编写一个打开图片进行特效显示的程序
创建文件
编写程序
代码参考的这位学姐的:
#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("test.png");
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("test1.png", src);
cvNamedWindow("test",1); imshow("test", src);
cvWaitKey();
return 0;
}
编译
执行程序
结果如上图所示。
3、编写一个打开摄像头显示处理视频的程序
创建test.cpp文件
编写程序
#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main()
{
VideoCapture capture(0);//从摄像头读取视频
while (1)//循环显示每一帧
{
Mat frame;//定义Mat变量
capture >> frame;//读取帧
imshow("读取视频帧", frame);//显示帧
waitKey(30);
}
system("pause");
return 0;
}
编译
出现错误,后经老师指导,成功解决了错误。
运行程序
没有摄像头界面弹出,通过网络找到了解决方法:
打开此电->管理->服务和应用程序->VMware USB Arbitration,重启动此服务,回到虚拟机查看就会弹出上面的界面。
解决完成后,运行程序
问题:
(1)如果要求打开你硬盘上一个视频文件来播放,请问第7行代码如何修改?
答:如果要打开一个视频文件来播放,第七行可改为
cv::VideoCapture capture;
capture.open(flowers.gif");
(2)在第9行的while循环中,Mat是一个什么数据结构? 为什么一定要加一句waitKey延时代码,删除它行不行?
答:Mat是一个数组,用来存放一帧图片的像素点,每个像素点对应一个RGB值,可以显示当前像素色块。而之所以加一句waitKey延时代码,是因为读帧时做一定延时是为了达到正常播放,据统计每秒显示 24帧时,我们看到的视频时流畅的,如果没有延时,那画面就不流畅,所以waitKey函数必不可少。
3)此代码会在while循环中一直运行,你如果试图用鼠标关闭图像显示窗口,会发现始终关不掉。需要用键盘Ctrl+C 强制中断程序,非常不友好。如何改进?
if(delay>=0 && waitKey (delay)>=32)
waitKey(0);</span>
通过如上的代码可控制视频暂停或者播(空格键控制暂停/播放)
小结:通过在Ubuntu上对opencv的安装,练习图像编程。在安装过程中遇到了一些问题,尽量去网络上搜索出解决方法。当一种方法不行时,要不怕麻烦地去尝试另一种方法。