Embedded program debugging and opencv3.4.1 image library, and complete learning of GDB debugging

Embedded program debugging and opencv image library

1. Practice GDB debugging of program code on Ubuntu system.

1. Introduction to GDB

GDB: GNU Debugger is a
debugger developed by the GNU Project for the GNU operating system , but its use is not limited to the GNU operating system. GDB can run
on UNIX, Linux and even Microsoft Windows. • GDB can debug
programs written in C, C++, Objective-C, Pascal, Ada and other languages ; the debugged program can run on the same computer as GDB, or
on different computers.
• Using GDB we can:
-Set breakpoints to stop the program
-Monitor or modify the value of variables in the program
-Track the code execution process

2. The main parameters of GDB

Insert picture description here
Insert picture description here

2. Perform GDB debugging

2.1) First install GDB

hcr@ubuntu:~$ sudo apt-get install gdb
[sudo] password for hcr: 
Reading package lists... Done
Building dependency tree       
Reading state information... Done
gdb is already the newest version (7.11.1-0ubuntu1~16.5).
0 upgraded, 0 newly installed, 0 to remove and 30 not upgraded.

2.2) Use GDB to debug a program

a. Not much nonsense, now we start to create a simple program to debug

hcr@ubuntu:~$ vim hellow.c

hellow.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);
}

b. When compiling the program, add debugging information to the program through the -g option of gcc:

hcr@ubuntu:~$ gcc -g hellow.c -o mytest

c. Perform GDB debugging

hcr@ubuntu:~$ gdb mytest

d. Display code and line number ()

(gdb) l       /利用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) l +        /利用l  +来显示剩余代码
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	}


Debug picture (we add breakpoints through b num, then run through run, and run step by step through c)
Insert picture description here
e. Add breakpoints, check the breakpoints, and run (we enter the number entry, and the function respectively at the main function entry Set breakpoint at entry)
Breakpoint can be set by function name, line number in the file, or you can specify the file name first and then the line number, you can also specify the offset from the pause position, or use the address to set.

(gdb) break function name
(gdb) break line number
(gdb) break file name: line number
(gdb) break file name: function name
(gdb) break + offset
(gdb) break-offset
(gdb) break *address

(gdb) b 11  /主函数入口设置断点
Breakpoint 1 at 0x400677: file hellow.c, line 11.
(gdb) b 15  /输入数字入口设置断点
Breakpoint 2 at 0x400695: file hellow.c, line 15.
(gdb) b 17   /函数入口设置断点
Breakpoint 3 at 0x4006ba: file hellow.c, line 17.
(gdb) info b  /查看断点
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000400677 in main at hellow.c:11
2       breakpoint     keep y   0x0000000000400695 in main at hellow.c:15
3       breakpoint     keep y   0x00000000004006ba in main at hellow.c:17

(gdb) run    /运行

f. Start step-by-step debugging

(gdb) run
Starting program: /home/hcr/mytest 

Breakpoint 1, main () at hellow.c:12
12	{
    
    
(gdb) s  /分步调试
14	 printf("Please input a number :");
(gdb) s
__printf (format=0x40076b "Please input a number :") at printf.c:28 /这有一个错误,我打多了空格
28	printf.c: No such file or directory.

Run to input number entry breakpoint

15	 scanf("%d", &iNum);
(gdb) c
Continuing.
Please input a number :100

运行到函数入口断点:(打印)

Breakpoint 3, main () at hellow.c:17
17	 ShowRevertNum(iNum);
(gdb) p iNum /打印输入的iNum ,发现没有问题
$1 = 100

继续添加新的断点

(gdb) b 6
Breakpoint 1 at 0x400603: file hellow.c, line 6.
(gdb) b7
Undefined command: "b7".  Try "help".
(gdb) run
Starting program: /home/hcr/mytest 
Please input a number :100 

Breakpoint 1, ShowRevertNum (iNum=100) at hellow.c:6
6	printf("%d", iNum % 10);
(gdb) p iNum
$1 = 100
(gdb) s
__printf (format=0x400764 "%d") at printf.c:28
28	printf.c: No such file or directory.
(gdb) s
32	in printf.c
(gdb) c
Continuing.
After revert : 010
[Inferior 1 (process 23688) exited normally]
(gdb) 

我们可以发现错误在函数的循环里

二. “学了opencv3.4.1,妈妈再不担忧你不会图像编程啦!”。

1.opencv3.4.1简介

1.1)Opencv3.4.1模块各个模块介绍

参考链接: //https://blog.csdn.net/sxk20091111/article/details/80450340

从opencv3开始就把整个库拆分成了两个库模块,Main modules和Extra modules这两部分,从网上下载的库默认都是Main module,它里面都是一些比较稳定的核心算法库,而Extra modules都是一些试验性质的库,很多新的算法库都会放到这里面来。从opencv3开始所有的库都会编译一个dll,而opencv2会将各个主要模块都分别编译成dll。

Core 核心功能模块

  1. 基本的数据结构

  2. 动态结构(从2.0开始基本都采用了vector结构)

  3. 数组的一些操作(add, abs等)

  4. 基本的绘图功能(点,线,框,圆等)

  5. 系统函数交互和宏

  6. Opengl的交互操作

Imgproc 图像处理模块

  1. 图像滤波

  2. 图像的几何变换

  3. 其它(miscellaneous)图像变换

  4. 绘图功能

  5. 一些颜色表类型

  6. 2D点的拓扑连接

  7. 直方图操作

  8. 结构分析和形状描述

  9. 运动分析和目标跟踪

  10. 特征检测和目标监测(canny, hough变换,模版匹配)

  11. 硬件加速模块

Imgcodes 图像读写模块
图像的文件的读和写(包含编解码)

Videoio 视频读写接口
对视频的读或者捕捉以及写视频文件的接口

Video 视频分析模块
对视频中的运动建模分析,视频中的目标进行跟踪

Highgui视频分析模块
高级的图形交互界面,包括控制显示窗口, 鼠标交互,图像视频的显示

calib3d 相机标定和三维重建模块

  1. 提取相机标定的角点以及角点的显示

  2. 相机的单目以及立体标定

  3. 基于影像求解基础矩阵和本质矩阵

  4. 由本质矩阵估计相机的姿态(opencv3以后增加了)

  5. 相机的外参数的估计

  6. 图像的畸变矫正和核线校正

  7. 生产点云(包括视差的方式以及三角化的方式)

在Extra modules中会有一些三维重建的算法包括影像建模,结构光编码等。同时还有一些最近比较流行的实时相机姿态估计的方式(sfm, slam)。

Features2d 2D特征框架
这是一个抽象的接口框架:

  1. 特征提取和描述子

  2. 描述子匹配

  3. 画出特征点以及匹配关系

Opencv2中像orb, fast, brief,surf, sift都在这个框架中, 在opencv3里面将sift, surf移到了Extra modules,当需要使用这两种特征的时候需要将Extra modules编译到主库中。

2.opencv3.4.1安装

参考链接: lhttps://blog.csdn.net/cungudafa/article/details/84451066.:

在Ubuntu16/18系统下练习编译、安装著名的C/C++图像处理开源软件库 Opencv3.x
1)去官网下载opencv,在本教程中选用的时opencv3.4.1,其他版本的配置方法异曲同工。
下载链接http://opencv.org/releases.html,选择sources版本
Insert picture description here

`
2).解压下载下来的zip包


hcr@ubuntu:~$ unzip opencv-3.4.1.zip

3)进入到解压后的文件包中

hcr@ubuntu:~$ cd opencv-3.4.1

4)安装依赖库和cmake ,如果提醒需要apt-get update,那就先sudo su进入root权限,再sudo apt-get update,然后在执行下面命令

hcr@ubuntu:~/opencv-3.4.1$ sudo apt-get install cmake  
[sudo] password for hcr: 
Reading package lists... Done

5).安装完cmake之后执行命令 ,创建编译文件夹,不创建的会提示(如下图)

hcr@ubuntu:~/opencv-3.4.1$ mkdir my_build_dir
hcr@ubuntu:~/opencv-3.4.1$ cd my_build_dir

In-source builds are not allowed.
6)cmake一下

hcr@ubuntu:~/opencv-3.4.1/my_build_dir$ cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..

7).执行命令,漫长的编译过程
sudo make

hcr@ubuntu:~/opencv-3.4.1/my_build_dir$ sudo make

Insert picture description here

下载完成
1)执行命令,

hcr@ubuntu:~/opencv-3.4.1/my_build_dir$ sudo make install

sudo make install
2)sudo make install 执行完毕后OpenCV编译过程就结束了,接下来就需要配置一些OpenCV的编译环境首先将OpenCV的库添加到路径,从而可以让系统找到

hcr@ubuntu:~/opencv-3.4.1/my_build_dir$ sudo gedit /etc/ld.so.conf.d/opencv.conf

sudo gedit /etc/ld.so.conf.d/opencv.conf
3)执行此命令后打开的可能是一个空白的文件,不用管,只需要在文件末尾添加Insert picture description here
4)保存回到命令行界面
5)执行如下命令使得刚才的配置路径生效

hcr@ubuntu:~/opencv-3.4.1/my_build_dir$sudo ldconfig  

6)配置bash

hcr@ubuntu:~/opencv-3.4.1/my_build_dir$sudo gedit /etc/bash.bashrc  

sudo gedit /etc/bash.bashrc

7)在最末尾添加

PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig  
export PKG_CONFIG_PATH 

Insert picture description here
8)保存,执行如下命令使得配置生效

hcr@ubuntu:~/opencv-3.4.1/my_build_dir$source /etc/bash.bashrc  

source /etc/bash.bashrc

9)更新

hcr@ubuntu:~/opencv-3.4.1/my_build_dir$sudo updatedb  

3. 编写一个打开图片进行特效显示的代码 test1.cpp;

注意gcc编译命令: gcc test1.cpp -o test1 pkg-config --cflags --libs opencv

请解释这条编译命令,它是如何获得opencv头文件、链接lib库文件的路径的?

3.1)在opencv-3.4.1下新建文件夹mytest

hcr@ubuntu:~/opencv-3.4.1$ 
hcr@ubuntu:~/opencv-3.4.1$ mkdir mytest

3.2)创建test.cpp

hcr@ubuntu:~/opencv-3.4.1$ touch test.cpp
sudo vim /test.cpp

3.3)进入编程

Insert picture description here

3.4)源码

请参考这个大牛
参考链接: lhttps://blog.csdn.net/cungudafa/article/details/84451066.:

3.5)保存并编译:

gcc编译器:gcc +文件名+ -o+输出文件流名称 +` 支持包

3.6)运行

hcr@ubuntu:~/opencv-3.4.1/mytest./test

Insert picture description here
Insert picture description here

3.7)思考

注意gcc编译命令: gcc test1.cpp -o test1 pkg-config --cflags --libs opencv

请解释这条编译命令,它是如何获得opencv头文件、链接lib库文件的路径的?
思考: pkg-config --cflags --libs opencv这个是代表一个字符串,通过这个地址来找到这个库

4.练习使用opencv库编写打开摄像头压缩视频的程序。参考示例代码1和示例代码。

4.1)我们尝试,打开摄像头

4.1.1)正常打开

创建test8.cpp

hcr@ubuntu:~/opencv-3.4.1$ touch test8.cpp
hcr@ubuntu:~/opencv-3.4.1$ sudo gedit  /test8.cpp

附图
Insert picture description here
直接上源码

#include<opencv2/opencv.hpp>
using namespace cv;
int main()
{
    
    
 VideoCapture capture(0);
while(1)
{
    
    
Mat frame;
capture >> frame;
imshow("hello",frame);
waitKey(30);
}
system("pause");
return 0;
}

编译

hcr@ubuntu:~/opencv-3.4.1/mytest$ g++ test8.cpp -o test8 `pkg-config --cflags --libs opencv`

会出现test8可执行文件
Insert picture description here
运行会发现有问题,这是因为我们没有打开摄像头

hcr@ubuntu:~/opencv-3.4.1/mytest$ ./test8
OpenCV(3.4.1) Error: Assertion failed (size.width>0 && size.height>0) in imshow, file /home/hcr/opencv-3.4.1/modules/highgui/src/window.cpp, line 356
terminate called after throwing an instance of 'cv::Exception'
  what():  OpenCV(3.4.1) /home/hcr/opencv-3.4.1/modules/highgui/src/window.cpp:356: error: (-215) size.width>0 && size.height>0 in function imshow

Aborted (core dumped)

4.1.2)配置摄像头

a)lsusb查看一下是否有找到摄像头。

hcr@ubuntu:~$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 004: ID 0e0f:0008 VMware, Inc. 
Bus 002 Device 003: ID 0e0f:0002 VMware, Inc. Virtual USB Hub
Bus 002 Device 002: ID 0e0f:0003 VMware, Inc. Virtual Mouse
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

我们发现没有摄像头!!!
b)ls /dev | grep video,查看是否有video0。

hcr@ubuntu:~$ ls /dev | grep video

c)如以上两点都没有,需要检查的部分是虚拟机设置>usb控制器>usb兼容性>(usb2.0/3.0)
Insert picture description here

d)如果当前选中的是2.0就选择3.0,如果当前选中的是3.0就选择2.0。然后确定。
Insert picture description here

e)在VMware的工具栏选择虚拟机->可移动设备->摄像头->断开连接。

f)然后再虚拟机>可移动设备>摄像头>连接。
Insert picture description here

4.1.3)摄像头成功拍摄图片

运行

hcr@ubuntu:~/opencv-3.4.1/mytest$ ./test8

Insert picture description here

4.2)我们尝试,打开摄像头录像

创建test9.cpp

hcr@ubuntu:~/opencv-3.4.1$ touch test9.cpp
hcr@ubuntu:~/opencv-3.4.1$ sudo gedit  /test9.cpp

直接贴代码(注意原代码有错

#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();
}

运行结果

hcr@ubuntu:~/opencv-3.4.1/mytest$ g++ test9.cpp -o test9 `pkg-config --cflags --libs opencv`
hcr@ubuntu:~/opencv-3.4.1/mytest$ ./test9

其中空格录像,esc保存退出
视频保存在mytest目录
Insert picture description here

Insert picture description here

4.3)如果要求打开你硬盘上一个视频文件来播放,请问示例代码1第7行代码如何修改?

看第七行

#include<opencv2/opencv.hpp>
using namespace cv;
int main()
{
    
    
 VideoCapture capture("0");/1.avi 
while(1)
{
    
    
Mat frame;
capture >> frame;
imshow("hello",frame);
waitKey(30);
}
system("pause");
return 0;
}
~         

我们按步骤编译运行,我们可以看到运行成功

Insert picture description here

4.4)在示例代码1第9行的while循环中,Mat是一个什么数据结构? 为什么一定要加一句waitKey延时代码,删除它行不行?

Mat is a class. It consists of two parts of data: a matrix header (including matrix size, storage method, storage address and other information) and a pointer to a matrix of all pixel values ​​(depending on the selected storage method, the matrix can have different dimensions).
The longer the waitKey delay is, the smaller the fps is, the frame skipping and the camera display becomes stuck, so there must be a certain delay

My understanding is that we need to buffer time

4.5) The sample code 1 code will always run in the while loop. If you try to close the image display window with the mouse, you will find that it cannot be closed. You need to use the keyboard Ctrl+C to forcibly interrupt the program, which is very unfriendly. How to improve?

This is to ensure that the program runs all the time, I think if you
add a break code, such as

#include<opencv2/opencv.hpp>
using namespace cv;
hcr=0;
int main()
{
    
    
 VideoCapture capture("0");/1.avi 
while(1)
{
    
    
Mat frame;
if(hcr== 27) break;
capture >> frame;
imshow("hello",frame);
waitKey(30);
}
system("pause");
return 0;
}
~         

to sum up

Through this study, I think both Linux and windows are operating systems that can be used in our lives. Embedded is very boring, but it will be very interesting if we combine embedded learning with Linux. opencv is a very useful tool, so it makes sense that we can implement it in unbantu.

Guess you like

Origin blog.csdn.net/nsnsnbabsb/article/details/109303186