Linux下GDB调试及OpenCV安装及应用
前言
调试在编程中是必不可少的,那如何在Ubuntu中进行调试呢,本文介绍了常用的GDB调试命令;摄像头在生活中的应用也是非常的广泛,本文手把手教你OpenCV入门。
一、GDB调试
首先我们编辑一个程序(用于调试),下面是一个整形数反转的程序:
#include<stdio.h>
void ShowR(int iNum) //整形数反转子程序
{
while(iNum > 10) //INum大于10时,进入循环
{
printf("%d",iNum%10);
iNum=iNum/10;
}
printf("%d",iNum);
}
int main(void)
{
int iNum;
printf("Please input a numbrt:");
scanf("%d",&iNum);
printf("After revert:");
ShowR(iNum);
}
启动GDB
启动GDB命令:
gcc -o ShowR -g ShowR.c //编译
gdb ShowR //调试
执行结果如下图所示:
-g选项可以利用操作西永的“原生格式(native format)”生成调试信息、GDB可以直接利用这个信息,其他调试器也可以使用这个调试信息。
注意:如果想用调试器执行一个可执行文件,在GCC编译是必须加上 -g 选项
GDB部分调试命令
GDB查看代码命令
(gdb) l(ist) // ( 字母 l ) 从第一行开始列出源码,共列出10行。
扫描二维码关注公众号,回复: 12088708 查看本文章
执行结果如下图所示:
若想继续查看接下来的代码,可以直接 空格 或继续使用 l 命令,然后敲回车键,使用空格键查看接下来的命令如下图所示:
也可以使用数字命令,直接显示 某行 - 某行
(gdb) l 数字 ,数字
如下图所示
GDB设置断点命令
以行数设置断点:
(gdb) b(reakpoint) 数字
数字为设置断点的行数,示例如下图所示,(提示设置断点成功):
也可以通过函数名设置断点:
(gdb) b 函数名
示例如下图所示(提示第二个断点设置成功):
可以通过命令查看断点信息:
info b(reakpoint)
示例如下图所示:
GDB程序运行命令
GDB运行程序命令
(gdb) run
运行程序至断点处,会停止运行,查看断点行,然后输入 c(ontinue) 之后,可以继续运行,如下图所示:
(gdb) c
在调试过程中,如果需要查看参数类型,可以使用 whatis 命令,示例如下图所示:
whatis 参数
在调试过程中,如果需要查看参数的值,可以将参数值打印出来,使用 p(rint) 命令,示例如下图所示:
(gdb) p(rint)
常用的GDB命令
二、Ubuntu下的OpenCV
下载安装OpenCV
首先我们需要下载一个OpenCV的安装包,可以在官网下载,可以在Linux系统中下载,不过这样下载会比较慢,博主是直接下载到Windows系统中,然后复制到Linux系统中的,复制到Linux中的压缩包如下图所示。
然后进入到压缩包所在路径,对压缩包解压:
unzip opencv-3.4.1.zip
注意:版本有可能会不相同哦!
解压缩之后,文件中会有两个文件,一个是压缩包,一个是解压缩后的文件夹,如下图所示:
进入到opencv-3.4.1文件夹中:
cd opencv-3.4.1
如下图所示:
安装依赖库和cmake,如果提醒需要apt-get update,那就需要先进入root权限,再执行下面的命令:
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
执行结果如下图所示:
温馨提示:此过程也需要耐心等待。
安装完成cmake之后,创建一个编译文件夹,然后进入文件夹内进行配置:
mkdir hy_by_dir
cd hy_by_dir
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..
执行命令,开始漫长的编译过程:
sudo make
漫长的等待后(博主等了大概两小时):
执行命令:
sudo make install
到此,就完成了OpenCV的下载安装工作,接下来就需要对OpenCV进行配置,输入命令:
sudo gedit /etc/ld.so.conf.d/opencv.conf
执行命令后,会出现一个空白的文件,此时需要在文件中输入:
/usr/local/lib
保存后回到输命令的界面,执行命令:
sudo ldconfig
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
欧耶,配置完成!接下来,我们试试做图片的特效。
图片特效
首先创立一个文件夹,并到此文件夹下,编辑一个特效图像的函数:
mkdir hytest
cd hytest
touch hyimage.cpp
nano hyimage.cpp
hyimage.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("iu.jpg"); //注意对应图像的名称及后缀
argc == 2? cvLoadImage(argv[1]) : 0;
cvShowImage("Image", image);
if (!image) return -1; center = cvPoint(image->width / 2, image->heigh$
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("hyimage.png", src); //生成图像的名称及后缀
cvNamedWindow("hyimage",1);
imshow("hyimage", src);
cvWaitKey();
return 0;
}
执行命令,将.cpp文件生成可执行.exe文件(如果 gcc 不成功,可以换成 g++ 试试):
g++ hyimage.cpp -o hyimage `pkg-config --cflags --libs opencv`
执行结果如下图所示:
将图像从Windows系统复制到Linux系统中:
注意更改图像的名称哦!程序里面的图像名称要与文件夹中图像名称一致。
运行可执行文件:
./hyimage
执行结果如下图所示:
左边为原始图像,右边为特效后的图像;红色框为原始图像文件,黄色框为生成的图像文件。图像特效完成!
注意:
① 图像所在位置要与.cpp的位置在一个文件夹下,不然编译可能会出错;
② 也可以将 IplImage* image = cvLoadImage(“iu.jpg”); 改为绝对路径。
视频播放
依然在我们创立的文件夹下面,创建一个 .cpp 的文件,文件内容如下:
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
VideoCapture capture("Clouds.mp4");
while(1)
{
Mat frame;
capture >> frame;
imshow("读取视频帧",frame);
waitKey(30);
}
system("pause");
return 0;
}
再将一个视频添加到该目录下,可以直接在Windows系统中复制到Linux系统中,播放的视频支持.mp4和.avi格式:
注意:第五行的函数参数为视频名称及后缀,保证与文件夹中的视频名称及后缀对应。
如果你的视频文件和创建的.cpp文件不再同一目录下,需要在第五行函数参数中加上绝对路径。
视频文件添加好了,就可以试一下能否播放出视频。双击视频,如果能够播放出,则不需要一下操作;如果不能播放出,则按照系统提示下载插件即可。
此时,如果你直接编译运行程序,就会出现如下错误:
原因是你没有将你的摄像头设置在Ubuntu系统下,此时,你需要在Windows系统下运行 Win+R,然后执行语句 services.msc :
查看此选项是否启动,若没启动,则点击启动:
将虚拟机设置中的 USB 兼容性换成 USB 3.0 :
点击虚拟机,将摄像头连接到虚拟机:
温馨提示:如果换成兼容性换成 USB 3.0还是不成功,就换成 USB 2.0 或者 USB 1.1试试,总会有一款是兼容的。
如何查看自己的摄像头是否能够启用了?输入命令cheese如果有图像显示,则表明摄像头已经在虚拟机中启用,示例如下图所示:
此时就可以编译,运行程序了:
g++ hyvideo.cpp -o hyvideo `pkg-config --cflags --libs opencv`
./hyvideo
运行结果如下图所示:
疑难杂症
①如果要求打开你硬盘上一个视频文件来播放,请问VideoCapture capture(0)行代码如何修改?
修改为自己存储图像文件的目录及名称和后缀;若已在与.cpp相同的文件夹下,则只需要添加名称和后缀参数。
②在while循环中,Mat是一个什么数据结构? 为什么一定要加一句waitKey延时代码,删除它行不行?
Mat本质上是由两个数据部分组成的类:(包含信息有矩阵的大小,用于存储的方法,矩阵存储的地址等)的矩阵头和一个指针,指向包含了像素值的矩阵(可根据选用于存储的方法采用任何维度存储数据)。
Mat的第一件事是你不再需要手动分配其大小并且当你不需要它的时候,你不再需要手动释放它(自动内存管理)。
加了waitKey延时代码后,才能播放视频;如果删除延时代码,将不能观察到视频播放。
特殊:当waitKey的参数为0时,即waitKey(0),此时程序会无限制等待用户按下按键。
③此代码会在while循环中一直运行,你如果试图用鼠标关闭图像显示窗口,会发现始终关不掉。需要用键盘Ctrl+C 强制中断程序,非常不友好。如何改进?
在循环代码中加入条件语句:
if ( !cvGetWindowHandle ( " 窗口名字 " ) )
{
break;
}
此时就可以直接点击左上方的“×”号,直接结束程勋运行。
视频录制及保存
这里还有一种升级版代码,可以录制视频,并保存到本地文件夹中,程序示例如下:
#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();
}
按下空格键录制视频和暂停录制:
录制的视频将存储在该目录下:
红色框为录制保存的视频。
三、总结
在Linux中,我们可以使用GDB来进行对程序的调试;此次学习OpenCV之后,对其有了初步的了解,OpenCV的海洋很深,等待着我们遨游。
加油吧,读书人!