一、GDB简单调试
1、 安装gdb
sudo apt-get install gdb
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
(1)创建并编译
示例代码:
#include<stdio.h>
int main(void)
{
int *p=0;
*p=1;
return 0;
}
gcc -o tao -g tao.c
(2)让系统产生core文件,并运行让程序崩溃,从而产生core文件
ulimit -c 100
(3)输入gdb 文件名 core找到文件问题
gdb tao core
二、安装opencv-3.4.12
1、将在网上下载好的opencv-3.4.12拖进unbuntu并将其复制到主目录下
2、打开终端解压包
unzip opencv-3.4.12.zip
3、 进入到解压后的文件包中
cd opencv-3.4.12
4、 安装依赖库和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
5、创建编译文件夹
mkdir my_build_dir
进入文件夹进行配置
cd my_build_dir
6、进行cmake
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..
执行命令
sudo make
sudo make install
7、配置OpenCV的编译环境
将OpenCV的库添加到路径
sudo gedit /etc/ld.so.conf.d/opencv.conf
打开后输入
/usr/local/lib
8、执行如下命令使得刚才的配置路径生效
sudo ldconfig
配置bash
sudo gedit /etc/bash.bashrc
在最末尾添加
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
export PKG_CONFIG_PATH
9、执行如下命令使得配置生效并更新
source /etc/bash.bashrc
sudo updatedb
二、 Linux编程
1、在opencv-3.4.1下新建文件夹mytest
cd opencv-3.4.1
mkdir mytest
2、创建test.cpp
touch test.cpp
3、进入编程
sudo gedit /test.cpp
图片路径直接放在home目录下;
#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;
}
4、保存并编译
gcc -c test.cpp -o test `pkg-config --cflags --libs opencv`
5、运行结果
运行./test会出现
输入命令即可
sudo apt-get install libcanberra-gtk-module
结果
三、使用opencv库编写打开摄像头压缩视频的程序
在上面的配置环境下进行
1、先将虚拟机的usb控制器下的usn兼容改为3.0并连接摄像头
在可移动设备中点击最后一个连接
2.创建文件和编译
touch a.cpp
gedit a.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;
}
```c
//获得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;
}
3.编译后运行结果
g++ a.cpp -o a `pkg-config --cflags --libs opencv`
./a
开启摄像头
空格控制视频录制,ESC退出并保存视频
总结
1)如果要求打开你硬盘上一个视频文件来播放,请问第5行代码如何修改?
代码:
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
VideoCapture capture(0);
while(1)
{
Mat frame;
capture >> frame;
imshow("读取视频帧",frame);
waitKey(30);
}
system("pause");
return 0;
}
将第5行代码改为
VideoCapture capture("你想播放的视频的名字");
2)在第9行的while循环中,Mat是一个什么数据结构? 为什么一定要加一句waitKey延时代码,删除它行不行?
MAT是一个类由两部分数据组成:矩阵头(包括矩阵尺寸、存储方法、存储地址等信息)和一个指向所有像素值的矩阵(根据所选存储方法不同,矩阵可以是不同的维数)的指针。不能删除wajitKey不然时间太短视频无法显示。