小白学习嵌入式第四回合
一、用GCC生成.a静态库和.so动态库
1、创建3个子程序hello.h、hello.c、main.c
程序hello.h内容如下:
程序hello.c内容如下:
程序main.c内容如下:
2、将hello.c编译成.o文件
通过以下命令得到hello.o文件,让我们来看看是否生成了
3、由.o文件创建静态库
ar -crv libmyhello.a hello.o
通过以上命令得到静态库文件libmyhello.a
4、在程序中使用静态库
用如下命令,先生成main.o,再生成可执行文件的方法,完成程序连接静态库的操作
对静态库进行一个小测试,看看是否公用函数hello是否真的连接到了目标文件hello中了,删除掉静态库文件之后也是一样的
程序正常运行,静态库中的公用函数已经连接到目标文件
5、由.o文件创建动态库文件
用如下命令进行操作生成动态库文件libmyhello.so
6、在程序中使用动态库
一.GCC程序的编译过程大概分四个阶段
预处理(Pre-Processing)
编译(Compiling)
汇编(Assembling)
链接(Linking)
二.简单HelloWorld程序的编译过程
示例:HelloWorld.c
1 #include <stdio.h>
2 int main()
3 {
4 printf(“Hello World!\n”);
5 return 0;
6 }
Ctrl+Alt+T —>打开控制台—>输入vim HelloWorld.c
- 执行如下命令:$ gcc -o HelloWorld HelloWorld.c
运行如下 : $ ./HelloWorld
输出: HelloWorld!
- 分步编译如下:
(1) $ gcc –E HelloWorld.c -o HelloWorld.i
可以输出HelloWorld.i文件中存放着HelloWorld.c经预处理之后的代码。打开HelloWorld.i文件,看一看,就明白了。后面那条指令,是直接在命令行窗口中输出预处理后的代码.
gcc的-E选项,可以让编译器在预处理后停止,并输出预处理结果。在本例中,预处理结果就是将stdio.h 文件中的内容插入到HelloWorld.c中了。
//预处理结束
//这时候你看一下HelloWorld.i ,可以看到插进去了很多东西。
(2) $ gcc –S HelloWorld.i
gcc的-S选项,表示在程序编译期间,在生成汇编代码后,停止,-o输出汇编代码文件。
(3)生成汇编代码文件HelloWorld.s以后,需要gas汇编器负责将其编译为目标文件,如下:
$ gcc –c HelloWorld.c
或者:
$ gcc -c HelloWorld.c –o HelloWorld.o
或者:
$ gcc -c HelloWorld.i -o HelloWorld.o
//编译结束
//生成 HelloWorld.o文件
(4) $ gcc HelloWorld.o –o HelloWorld 生成连接,可执行文件(HellWorld重新生成的可执行文件)
gcc连接器是gas提供的,负责将程序的目标文件与所需的所有附加的目标文件连接起来,最终生成可执行文件。
附加的目标文件包括静态连接库和动态连接库。
对于上一小节中生成的HelloWorld.o,将其与C标准输入输出库进行连接,最终生成程序HelloWorld可执行文件
输入命令:gcc HelloWorld.o –o HelloWorld—>生成如下图:
. 多个程序文件的编译
一般情况一个程序都是有若干个文件源文件组成,所以编译的时候需要形成多个编译单元,使用GCC编译器可以将多个源文件编译成所需要的程序
比如:源文件有main.c a.c b.c 最终生成一个可执行的文件main
比如:一个工程有main.c a.c b.c生成test的可执行文件。
编译命令如下:
$ gcc –c main.c a.c b.c –o main
或者:
$ gcc –o main main.c a.c b.c
GCC仍然会按照预处理、编译和链接的过程依次进行
大概过程相当于:
gcc -c main.c -o main.o
gcc -c a.c -o a.o
gcc -c b.c -o b.o
最后:
gcc main.o a.o b.o -o main
Opencv3.4.6安装教程
下载opencv
下载opencv_contrib
Cmake配置、生成
Visual Studio 2017环境配置
测试
下载opencv
从官网下载需要的opencv版本:https://opencv.org/releases/
下载的opencv.exe文件其实是一个压缩包,将其解压。
下载opencv_contrib
从Opencv官方的GitHub上下载:https://github.com/opencv
进入opencv_contrib后,点击releases,就可以下载与opencv版本对应的opencv_contrib。
下载后,将其解压到opencv同一目录下。
Cmake配置、生成
Cmake官网:https://cmake.org/download/
作者下载的Cmake版本是3.12.3。下载完成后,解压缩 --> bin --> 打开cmake-gui.exe,就可以用Cmake进行配置、生成。
按图操作,点击Configure后,选择自己安装的vs版本和位数,点击Finish之后,就开始构建。
Configure完成后,如下图所示,进行相应操作,完成Generate。
若显示Configure done,Generate done,且配置、生成过程中没有红色字样,说明构建、生成成功,否则失败。
有的因为opencv版本,可能需要下载一个 protobuf-cpp- * . * .* 的文本协议,*为opencv版本号,官网地址为https://github.com/protocolbuffers/protobuf/releases/。下载 .tar.gz 格式的,将其下载后,拷贝到opencv_contrib- * . * . */moudles/dnn/.download/(一堆哈希码)/v * . *. */文件夹下,即可。之后重新Configure、Generate操作。
Visual Studio 2017环境配置
进入\opencv\opencv3.4.6\newbuild目录,找到OpenCV.sln,打开。找到CMakeTargets --> INSTALL,右键 --> 生成,这个生成过程需要一段时间。
生成结果如下图,结果中失败和跳过个数是0个,说明生成成功;否则重新进行Cmake的相关操作。
最终build就是为了生成这些文件。
3. 打开VS 2017,新建项目,选择空项目,配置VS环境。
6. 通用属性 ——》链接器——》输入——》附加依赖项——》编辑,将5.(2)库目录中的所有.lib文件名全都拷贝进去。(注:有一个opencv_world346d的.dll和.lib文件是在\opencv\opencv3.4.6\build\x64\vc15\目录下的bin和lib文件夹中,需要先拷贝到\opencv\opencv3.4.6\newbuild\install\x64\vc15\目录下的bin和lib文件夹下):
设置环境变量,将\opencv\opencv3.4.6\newbuild\install\x64\vc15\bin路径添加到计算机系统的环境变量中(计算机右键——》属性——》高级系统设置——》环境变量——》系统变量中的Path——》编辑;
测试
在opencv_test项目中,源文件(右键) ——》添加 ——》新建项。
在测试前,先将平台从x86改为x64,要不会报错。
测试代码如下:
#include <opencv2/opencv.hpp>
#include
using namespace cv;
int main(int argc, char** argv) {
Mat src = imread(“G:/images/img/dog1.jpg”); //输入一张图片
if (src.empty()) {
printf(“Could not load image…\n”);
return -1;
}
imshow(“Show”, src);
waitKey(0);
return
}
若测试结果显示输入的图片,说明opencv配置成功;如果报找不到.dll的错,并且之前安装都正确的话,说明是环境配置没起作用的问题,重启电脑,重新测试就能成功。
三、打开摄像头采集图像并保存(改进)
代码
/*********************************************************************
打开电脑摄像头,空格控制视频录制,ESC退出并保存视频RecordVideo.avi
*********************************************************************/
#include
#include <opencv2/opencv.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
void main()
{
//打开电脑摄像头
VideoCapture cap(0);
if (!cap.isOpened())
{
cout << “error” << endl;
waitKey(0);
return;
}
//获得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就可以解决了。
//删掉这样段代码
if (!cap.isOpened())
{
cout << “error” << endl;
waitKey(0);
return;
}
//将上面的这段代码修改为下面的代码
if (!cap.isOpened())
{
cout << “error” << endl;
waitKey(0);
return 0;
}
这个是视频采集画面的记录过程,当按下ESC按键时,视频采集画面就会关闭,采集记录过程也就结束了。(摄像头采集的画面就不展示了,就展示采集记录的过程)
小结
通过这个简单的摄像头采集的程序,基本能够掌握在Ubuntu下,该怎么使用opencv,怎么来完成这个过程。虽然,这个过程开始就遇到摄像头打不开的情况,但是,再查找资料后,也顺利的解决了。所以,遇到问题的小伙伴们,不要就此放弃,查找资料解决也是很快的。