GCC背后的故事&OpenCV相识何必曾相逢&git初见

一.使用gcc生成.a静态库和.so动态库

1.编译生成子程序hello.h、hello.c以及main.c
创建作业目录,并用 vim编辑器编辑生成所需要的 3 个文件

mkdir test1
cd test 1

在这里插入图片描述
在这里插入图片描述

hello.h为该函数库的头文件

#ifndef HELLO_H
#define HELLO_H
void hello(const char *name);
#endif //HELLO

hello.c是函数库的源程序,其中包含公用函数 hello,该函数将在屏幕上输出"Hello
XXX!‘’

#include <stdio.h>
void hello(const char *name)
{
printf("Hello %s!\n", name);
}

main.c为测试库文件的主程序,在主程序中调用了公用函数 hello

#include "hello.h"
int main()
{
hello("everyone");
return 0;
}

2.将 hello.c 编译成.o 文件。

gcc -c hello.c

在这里插入图片描述

运行 ls 命令查看是否生存了 hello.o 文件

ls

在这里插入图片描述
3.由.o 文件创建静态库,并运行 ls 命令查看结果

ar -crv libdearhello.a hello.o
 ls

在这里插入图片描述
4.在程序中使用静态库

gcc -o hello main.c -L. –ldearhello

在这里插入图片描述

5 .由.o 文件创建动态库文件并使用 ls 命令查看动态库文件是否生成。

gcc -shared -fPIC -o libdearhello.so hello.o
ls

在这里插入图片描述

6 .在程序中使用动态库

gcc -o hello main.c -L. -ldearhello

运行

./hello

在这里插入图片描述
运行./hello 会提示出错,因为虽然连接时用的是当前目录的动态库,但是运行时,是到/usr/lib 中找库文件的,将文件 libmyhello.so 复制到目录/usr/lib即可

mv libdearhello.so /usr/lib

又发现需要管理员权限,则使用sudo命令

sudo mv libdearhello.so /usr/lib

再次运行查看结果
在这里插入图片描述

二.改写一函数及对静态库、动态库的应用

(一)文件的建立及编译

1.建立main.c、sub1.c、sub2.c、sub.h文件

 mkdir work1
 cd work1
 touch main.c sub1.c sub2.c sub.h

在这里插入图片描述
main.c:

#include"sub.h"
#include<stdio.h>
int main(){
int a=8,b=16;
printf("%f\n",x2x(a,b));
printf("%f\n",x2y(a,b));
return 0;
}

sub1.c

#include<stdio.h>
float x2x(int a,int b){
float x;
x=a*b;
return x;
}

sub2.c:

#include<stdio.h>
float x2y(int a,int b){
float c;
c=a+b;
return c;
}

sub.h:

#ifndef SUB_H
#define SUB_H
float x2x(int a,int b);
float x2y(int a,int b);
#endif

2.使用gcc分别编译sub1.c和sub2.c生成sub1.o和sub2.o并查看结果

gcc -c sub1.c sub2.c
ls

在这里插入图片描述

(二)静态库

1.生成静态库文件及可执行文件

 ar -crv libmysub.a sub1.o sub2.o
 ./main

在这里插入图片描述
在这里插入图片描述
2.查看静态库大小

ls -l

在这里插入图片描述

(三)动态库

1.键入gcc -c -fpic sub1.c sub2.c

gcc -c -fpic sub1.c sub2.c

2.生成动态库文件及可执行文件

gcc -o main main.c libmysub.so
sudo mv libmysub.so /usr/lib
./main

在这里插入图片描述
3.查看动态库大小

ls -l

在这里插入图片描述
##(四)动态库与静态库文件大小的比较

在这里插入图片描述
在这里插入图片描述
两图对比,发现静态库和动态库生成的可执行文件大小差不多

三.Linux GCC常用命令及背后的故事

(一)准备工作

1.创建工作目录test2,并用vim编译生成一个hello.c程序

mkdir test2
cd test2
vi hello.c

在这里插入图片描述

hello.c文件:

#include <stdio.h>
int main(void)
{
printf("Hello World! \n");
return 0;
}

(二) 编译过程

1.预处理

gcc -E hello.c -o hello.i

预处理的过程主要包括以下过程:
(1) 将所有的#define 删除,并且展开所有的宏定义,并且处理所有的条件预编
译指令,比如#if #ifdef #elif #else #endif 等。
(2) 处理#include 预编译指令,将被包含的文件插入到该预编译指令的位置。
(3) 删除所有注释“//”和“/* */”。
(4) 添加行号和文件标识,以便编译时产生调试用的行号及编译错误警告行号。
(5) 保留所有的#pragma 编译器指令,后续编译过程需要使用它们
2.编译

gcc -S hello.i -o hello.s

编译过程就是对预处理完的文件进行一系列的词法分析,语法分析,语义分析及优化后生成相应的汇编代码
3.汇编

gcc -c hello.s -o hello.o

汇编过程调用对汇编代码进行处理,生成处理器能识别的指令,保存在后缀为.o的目标文件中。通过调用 Binutils 中的汇编器 as 根据汇编指令和处理器指令的对照表一一翻译
在这里插入图片描述

4.链接
链接分为动态链接和静态链接
(1) 静态链接是指在编译阶段直接把静态库加入到可执行文件中去,这样可执行
文件会比较大。链接器将函数的代码从其所在地(不同的目标文件或静态链接库中)拷贝到最终的可执行程序中。
(2) 动态链接则是指链接阶段仅仅只加入一些描述信息,而程序执行时再从系统中把相应动态库加载到内存中去。
由于链接动态库和静态库的路径可能有重合,所以如果在路径中有同名的静态库文件和动态库文件,比如 libtest.a 和 libtest.so,gcc 链接时默认优先选择动态库,会链接libtest.so,如果要让 gcc 选择链接 libtest.a 则可以指定 gcc 选项-static,该选项会强制使用静态库进行链接。

链接动态库:

gcc hello.c -o hello

使用size查看大小:

size hello

查看可执行文件链接的动态库

ldd hello

在这里插入图片描述

链接静态库:

gcc -static hello.c -o hello

在这里插入图片描述

(三)分析ELF文件

1.ELF 文件的段

  • 一个典型的 ELF 文件包含下面几个段:
  • .text:已编译程序的指令代码段。
  • .rodata:ro 代表 read only,即只读数据(譬如常数 const)
  • .data:已初始化的 C 程序全局变量和静态局部变量。
  • .bss:未初始化的 C 程序全局变量和静态局部变量。
  • .debug:调试符号表,调试器用此段的信息帮助调试。

查看其各个 section 的信息

readelf -S

在这里插入图片描述

2.反汇编 ELF
由于 ELF 文件无法被当做普通文本文件打开,如果希望直接查看一个 ELF 文件包
含的指令和数据,需要使用反汇编的方法。

objdump -D hello

在这里插入图片描述

使用 objdump -S 将其反汇编并且将其 C 语言源代码混合显示出来

gcc -o hello -g hello.c 
objdump -S hello

在这里插入图片描述

四.基于Opencv完成图像程序编程

(一)安装opencv3.4.16

1.在官网安装opencv3.4.16.zip
https://opencv.org/releases/添加链接描述
在这里插入图片描述

点击source源,下载完成后解压成文件夹复制粘贴到Ubuntu的文件夹中
在这里插入图片描述
在这里插入图片描述
(途中显示文件已经过重命名)
2.安装依赖库和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  

在这里插入图片描述

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

mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..

在这里插入图片描述
4.执行命令

sudo make -j8

在这里插入图片描述
在这里插入图片描述
5.执行命令

sudo make install

(二)配置OpenCV的编译环境

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

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

在这里插入图片描述

2.在文件末尾添加

/usr/local/lib  

3.保存回到命令行界面
执行如下命令使得刚才的配置路径生效

sudo ldconfig  

4.配置bash

sudo gedit /etc/bash.bashrc  

在这里插入图片描述
5.在文件末尾添加

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

在这里插入图片描述

6.保存,执行如下命令使得配置生效

source /etc/bash.bashrc  

7.更新

sudo updatedb  

在这里插入图片描述
至此所有的配置都已经完成

(三)图像程序编程

1.首先创建一个代码存放文件夹 code1 ,然后进入文件夹中

cd code1

2.创建一个 test1.cpp 文件

gedit test1.cpp

3.输入如下代码:

#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("boy.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.执行以下命令

g++ test1.cpp -o test1 `pkg-config --cflags --libs opencv`

在这里插入图片描述

5.在用同文件夹下准备一张图片,文件名为:lena.jpg
运行

./test1

在这里插入图片描述
在这里插入图片描述

可以看到由 boy.jpg 生成了一个 test.png ,呈现的效果不同了

(四)视频程序编程

1.虚拟机获取摄像头权限
使用快捷键 Win + R ,输入 services.msc ,并回车

在这里插入图片描述

找到VMware USB Arbitration S…保证启动
在这里插入图片描述

2.点击 “ 虚拟机 ” ,然后点击 “ 设置(S)… ”

在这里插入图片描述

3.选择 “ USB控制器 ” ,将 “ USB兼容性 ” 设置为 “ USB 3.0 ” ,并点击确定

在这里插入图片描述
4.播放视频
创建一个 test2.cpp 文件

gedit test2.cpp

test2代码:

#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
	//从摄像头读取视频
	VideoCapture capture("pink.mp4");
	//循环显示每一帧
	while(1){
		Mat frame;//定义一个Mat变量,用于存储每一帧的图像
		capture >> frame;//读取当前帧
		if(frame.empty())//播放完毕,退出
			break;
		imshow("读取视频帧",frame);//显示当前帧
		waitKey(30);//掩饰30ms
	}
	system("pause");
	return 0;
}

5.准备一个小视频,我这里准备了 pink.mp4

在这里插入图片描述

6编译 test2.cpp 文件并输出结果

g++ test2.cpp -o test2 `pkg-config --cflags --libs opencv`
./test2

在这里插入图片描述

下图即为视频展示

在这里插入图片描述

(五)录制视频编程

1.创建test3.cpp并编译

gedit test3.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;
	}

	//获得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;
}

2.编译

g++ test3.cpp -o test3 `pkg-config --cflags --libs opencv`

3.输出结果

./test3

生成了一个 .avi 文件,并不断生成帧

在这里插入图片描述

五.Gitee.com的基本使用

1.登录码云账号

在这里插入图片描述

2.新建仓库

在这里插入图片描述

3.将私有仓库设置为公开仓库

在这里插入图片描述
在这里插入图片描述
4.保存后点击仓库名返回仓库初始界面

在这里插入图片描述

5.在终端输入sudo apt-get install git来安装git

sudo apt-get install git

在这里插入图片描述
6.设置昵称和邮箱地址

git config --global user.name "你的名字"
git config --global user.email "你的邮箱地址"

!](https://img-blog.csdnimg.cn/e17747daaae4458ab7af88e74b2fb555.png

7.得到连接的SSH公钥

ssh-keygen -C -t rsa "邮箱地址"

在这里插入图片描述

8.连接gitee.com

cd ~/.ssh

在这里插入图片描述
将文件中的内容复制粘贴到gitee.com的公钥中(图为添加成功后)

在这里插入图片描述
检查是否连接成功

检测Ubuntu能否连接到Gitee

在这里插入图片描述

9.上传文件

在这里插入图片描述
将文件初始化为本地仓库

git init

命令上传该文件夹内所有文件(add和.之间为两个空格)

git add  .

克隆的SSH链接
获取克隆的SSH链接的方法:打开你在Gitee创建的那个仓库,点击克隆/下载按钮,出现下面的文本框里的就是克隆的SSH链接,点击复制即可
在这里插入图片描述

git remote add origin +SSH链接

同步Gitee仓库

git pull origin master

信息备注

在这里插入图片描述

git commit -m "备注内容''

开始上传文件至Gitee

git push origin master

在这里插入图片描述

刷新后即可得到上传文件

在这里插入图片描述

六.总结

通过本次练习,基本掌握了动态库、静态库的使用,gcc常用命令的使用,编译器的操作过程,以及opencv软件的安装以及图像视频的操作,对于练习过程中出现的问题,通过不断查阅资料,由于初次使用,使得花费时间较长,但最终完成了任务,自己对ubuntu有了更多的了解。

七.参考资料

https://blog.csdn.net/weixin_50617754/article/details/111722043
https://blog.csdn.net/ssj925319/article/details/109231145
https://cungudafa.blog.csdn.net/article/details/84451066
https://blog.csdn.net/qq_43279579/article/details/109026927
https://blog.csdn.net/ssj925319/article/details/109231145
https://blog.csdn.net/weixin_46129506/article/details/120646081

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值