嵌入式程序调试与opencv图像库

  • 一.在Ubuntu系统上练习程序代码的GDB调试
  • 1.什么是GDB
  • 2.使用方法
  • 3.启动GDB
  • 4.GDB命令
  • 5.GDB调试举例
  • 6.内存出错的GDB调试
  • 二.在Ubuntu16/18系统下练习编译、安装C/C++图像处理开源软件库 Opencv3.x
  • 1.安装opencv-3.4.1
  • 2.配置OpenCV的编译环境
  • 3.图像处理
  • 三、使用opencv简单使用摄像头(因为我台式电脑没有摄像头,所以很多没有展示)
  • 1、首先要将虚拟机摄像头USB配好
  • 2、设置虚拟机
  • 四.总结


一.在Ubuntu系统上练习程序代码的GDB调试

1.什么是GDB

GDB : GNU Debugger,是GNU工程为GNU操作系统开发的调试器,但它的使用不局限于GNU操作系 统, GDB可以运行在UNIX、Linux甚至Microsoft Windows。 • GDB可以调试C、C++、Objective-C、Pascal、Ada等语言编写的程序;被调试的程序可以跟GDB运行于同一台电脑,也可运行于不同电脑。
使用GDB我们可以:
①:设置断点使程序停住
②:监视或修改程序中变量的值
③:跟踪代码执行过程

2.使用方法

程序要能被调试,必须包含调试信息。
编译程序时,通过gcc的-g选项为程序添加调试信息,例如:

gcc –g –o helloworld helloworld.c

3.启动GDB

gdb [程序名]

嵌入式opencv对硬件要求 嵌入式linux opencv_linux

4.GDB命令

• file 装入想要调试的可执行文件。
• kill 终止正在调试的程序。
• list 列出产生执行文件的源代码的一部分。
• next 执行一行源代码但不进入函数内部。
• step 执行一行源代码而且进入函数内部。
• run 执行当前被调试的程序。
• c 继续运行程序。
• quit 终止gdb。 • watch 使你能监视一个变量的值而不管它何时被改变。
• backtrace 栈跟踪,查出代码被谁调用。
• print 查看变量的值。
• make 使你能不退出gdb就可以重新产生可执行文件。
• shell 使你能不离开gdb就执行UNIX shell命令。
• whatis 显示变量或函数类型。
• break 在代码里设断点,这将使程序执行到这里时被挂起。
• info break 显示当前断点清单,包括到达断点处的次数等。
• info files 显示被调试文件的详细信息。
• info func 显示所有的函数名称。
• info local 显示当函数中的局部变量信息。
• info prog 显示被调试程序的执行状态。
• delete [n] 删除第n个断点。
• disable[n] 关闭第n个断点。
• enable[n] 开启第n个断点。
• ptype 显示结构定义。
• set variable 设置变量的值。
• call name(args) 调用并执行名为name,参数为args的函数。
• Finish 终止当前函数并输出返回值。
• return value 停止当前函数并返回value给调用者。
• break命令的使用
– 根据行号设置断点:
• (gdb) break linenum
– 根据函数名设置断点:
• (gdb) break funcname
– 执行非当前源文件的某行或某函数时停止执行:
• (gdb) break filename:linenum
• (gdb) break filename:funcname
– 根据条件停止程序执行:
• (gdb) break linenum if expr
• (gdb) break funcname if expr

5.GDB调试举例

我们用下图代码为例,实现对一个整型数的反转。

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

在ubuntu下创建一个test.c文件,编译

嵌入式opencv对硬件要求 嵌入式linux opencv_嵌入式opencv对硬件要求_02


运行程序,我们发现我们输入的数字是100,而输出的确实010,出现了问题,这个时候我们就可以用GDB来对程序进行调试。

嵌入式opencv对硬件要求 嵌入式linux opencv_GDB_03


代码调试阶段

嵌入式opencv对硬件要求 嵌入式linux opencv_图像处理_04


继续运行

嵌入式opencv对硬件要求 嵌入式linux opencv_linux_05

通过最后调试,我们发现是当iNum的值等于10的时候,代码循环就结束了。所以我们应该修改我们的代码,修改后调试运行。

嵌入式opencv对硬件要求 嵌入式linux opencv_图像处理_06

6.内存出错的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;
}

嵌入式opencv对硬件要求 嵌入式linux opencv_ubuntu_07


调试结束。

二.在Ubuntu16/18系统下练习编译、安装C/C++图像处理开源软件库 Opencv3.x

1.安装opencv-3.4.1

在opencv官网下载3.4.1版本,可以直接复制文件到虚拟机上。

参考网站:Opencv官网 ①将复制的包放在Home目录下

嵌入式opencv对硬件要求 嵌入式linux opencv_图像处理_08


解压复制的文件

unzip opencv-3.4.12.zip

②进入解压后的文件

cd opencv-3.4.12

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

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

嵌入式opencv对硬件要求 嵌入式linux opencv_GDB_09


④安装完cmake之后执行命令 ,创建编译文件夹

创建编译文件夹

`mkdir my_build_di`r

进入文件夹进行配置

cd my_build_dir

cmake一下

cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..

嵌入式opencv对硬件要求 嵌入式linux opencv_GDB_10


⑤执行命令,经过漫长的编译过程

sudo make

下载完成

嵌入式opencv对硬件要求 嵌入式linux opencv_linux_11


执行:sudo make install

2.配置OpenCV的编译环境

将OpenCV的库添加到路径,从而可以让系统找到

sudo gedit /etc/ld.so.conf.d/opencv.conf

在跳出的文本框的内输入/usr/local/lib

嵌入式opencv对硬件要求 嵌入式linux opencv_linux_12


执行命令

sudo ldconfig

配置bush

sudo gedit /etc/bash.bashrc

弹出这样一个窗口

嵌入式opencv对硬件要求 嵌入式linux opencv_ubuntu_13


在末尾添加如下框中的代码

嵌入式opencv对硬件要求 嵌入式linux opencv_GDB_14


执行如下命令使7配置成功

source /etc/bash.bashrc

更新

sudo updatedb

3.图像处理

1.在opencv-3.4.1下新建文件夹mytest

嵌入式opencv对硬件要求 嵌入式linux opencv_GDB_15


在目录下存放一张图片

嵌入式opencv对硬件要求 嵌入式linux opencv_linux_16

再次移动到刚创建的mytest文件夹中。
2、创建函数test.cpp

touch test.cpp

进入编程

sudo gedit  /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("1.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("test.png", src);

    cvNamedWindow("test",1);  	imshow("test", src);
	 cvWaitKey();
	 return 0;
}

3.运行

嵌入式opencv对硬件要求 嵌入式linux opencv_linux_17

三、使用opencv简单使用摄像头(因为我台式电脑没有摄像头,所以很多没有展示)

1、首先要将虚拟机摄像头USB配好

Win+R打开cmd 输入services.msc把虚拟机的USB服务打开如图所示

嵌入式opencv对硬件要求 嵌入式linux opencv_ubuntu_18

2、设置虚拟机

在虚拟机菜单栏中选择“虚拟机(M)”->选择“可移动设备”->选择最后一行选项->选择“连接(断开与主机连接)”,设置完这项之后,虚拟机接管了笔记本摄像头。

嵌入式opencv对硬件要求 嵌入式linux opencv_GDB_19


因为我台式电脑的问题没有摄像头,所以它没有找到文件

嵌入式opencv对硬件要求 嵌入式linux opencv_图像处理_20


输入代码打开摄像头

cheese

就到这里了。
代码解释:

1、如果要求打开你硬盘上一个视频文件来播放,请问第7行代码如何修改? VideoCapture capture(“视频名.mp4”);
2、Mat是一个数组,用来存放一帧图片的像素点,每个像素点对应一个RGB值,可以显示当前像素色块
3、读帧时做一定延时是为了达到正常播放,据统计每秒显示 27、28帧时,如果没有延时,那么运行后画面马
上就消失了,还没看到画面就没了。所以waitKey函数必不可少,最好延时30ms左右
4、此代码会在while循环中一直运行,你如果试图用鼠标关闭图像显示窗口,会发现始终关不掉。需要在终端用 键盘Ctrl+C
强制中断程序如果想要控制视频暂停或者播放可以在下面加入下面语句,空格即可以控制暂停


学姐

四.总结

没多次都是安装和配置环境比较麻烦,最后的运行和测试都比较简单,所以下次会做得更好。