?
目录
一、用GCC生成动态库和静态库
??? (一)前言
?(二)静态库的使用
?(三)动态库的使用
(四)动态库和静态库使用实例
二、OpenCV的安装以及使用实例
(一)OpenCV简介
(二)OpenCV下载
(三)OpenCV使用实例
三、总结
四、参考网站
一、用GCC生成动态库和静态库
??? (一)前言
? 动态链接库(Dynamic Link Library 或者 Dynamic-link Library,缩写为 DLL),是微软公司在微软Windows操作系统中,实现共享函数库概念的一种方式。这些库函数的扩展名是 ”.dll"、".ocx"(包含ActiveX控制的库)或者 ".drv"(旧式的系统驱动程序)。
? Windows 中,DLL 多数情况下是带有 ".dll" 扩展名的文件,但也可能是 ".ocx"或其他扩展名;Linux系统中常常是 ".so" 的文件。它们向运行于 Windows操作系统下的程序提供代码、数据或函数。程序可根据 DLL 文件中的指令打开、启用、查询、禁用和关闭驱动程序。
? 静态库是指在我们的应用中,有一些公共代码是需要反复使用,就把这些代码编译为“库”文件;在链接步骤中,连接器将从库文件取得所需的代码,复制到生成的可执行文件中的这种库。
? 静态库和动态库是两种共享程序代码的方式,它们的区别是:静态库在程序的链接阶段被复制到了程序中,和程序运行的时候没有关系;动态库在链接阶段没有被复制到程序中,而是程序在运行时由系统动态加载到内存中供程序调用。使用动态库的优点是系统只需载入一次动态库,不同的程序可以得到内存中相同的动态库的副本,因此节省了很多内存。
?(二)静态库的使用
??? 首先在Linux虚拟机上创建一个文件夹用于存放本次的实验内容
编写代码:
hello.h
#ifndef HELLO_H
#define HELLO_H
void hello(const char *name);
#endif//HELLO_H
hello.c
#include<stdio.h>
void hello(const char *name)
{
printf("Hello %s\n",name);
}
main.c
#include"hello.h"
int main()
{
hello("everyone");
return 0;
}
?创建好的效果如下
?gcc编译得到.o文件 gcc -c hello.c
?? 使用静态库
首先创建静态库,创建静态库的工具:ar。静态库文件命名规范:以lib作为前缀,是.a文件
ar -crv libmyhello.a hello.o
在程序中使用静态库 gcc -o hello main.c -L. -lmyhello?
gcc main.c libmyhello.a -o hello
?
先生成main.o文件
gcc -c main.c??
然后再生成可执行文件
gcc -o hello main.c libmyhello.a?
效果如下
?(三)动态库的使用
? 首先创建动态库
gcc -shared -fPIC -o libmyhello.so hello.o
在程序中执行动态库 gcc -o hello main.c -L. -lmyhello或gcc main.c libmyhello.so -o hello?
?在运行hello程序时,会出现如下错误
问题的解决方法:将libmyhello.so复制到目录/usr/lib中。
mv libmyhello.so /usr/lib
在复制时可能会出现权限不够问题
输入 sudo -s 输入密码获得root权限
?问题解决!
(四)动态库和静态库使用实例
? 创建函数
f1.c
#include<stdio.h>
void print1(int arg)
{
printf("f1 print arg:%d\n",arg);
}
f2.c
#include<stdio.h>
void print2(char *arg)
{
printf("f2 printf arg:%s\n",arg);
}
f.h
#ifndef f_H
#define f_H
void print1(int);
void print2(char *);
#endif
test.c
#include<stdio.h>
#include"f.h"
int main()
{
print1(1);
print2("test");
return 0;
}
程序中使用静态库 ar crv libfile.a f1.o f2.o gcc -o test test.c libfile.a
结果如下:
?动态库使用
gcc -shared -fPIC -o libfile.so f1.o f2.o gcc -o test test.c libfile.so
二、OpenCV的安装以及使用实例
(一)OpenCV简介
OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上。 它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。
OpenCV用C++语言编写,它具有C ++,Python,Java和MATLAB接口,并支持Windows,Linux,Android和Mac OS,OpenCV主要倾向于实时视觉应用,并在可用时利用MMX和SSE指令, 如今也提供对于C#、Ch、Ruby,GO的支持。
(二)OpenCV下载
? 下载地址:
OpenCV/opencv_contrib国内快速下载 | 绕云技术笔记https://www.bzblog.online/wordpress/index.php/2020/03/09/opencvdownload/
?将 opencv-3.4.11.zip 复制到 home 文件夹下,再解压缩。
unzip opencv-3.4.11.zip
?
进入opencv文件夹打开终端,然后获取root用户权限 ,并更新。
sudo apt-get update
?
安装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?
创建一个build 文件夹并进入文件夹
使用cmake编译参数
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local ..
?
然后使用cmake创建编译
sudo make
编译完成
安装
sudo make install
?
?接下来配置环境
修改 opencv.conf 文件,打开后的文件是空的,添加 opencv 库的安装路径:/usr/local/lib
sudo gedit /etc/ld.so.conf.d/opencv.conf
?
更新系统的共享链接库
sudo ldconfig
?
配置 bash ,修改 bash.bashrc 文件
sudo gedit /etc/bash.bashrc
在文件末尾加入:
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
export PKG_CONFIG_PATH
?
保存退出,然后执行如下命令使得配置生效
source /etc/bash.bashrc
?
更新一下。
sudo updatedb
接下来查看 opencv 的版本信息。
pkg-config --modversion opencv
?
安装完成
(三)OpenCV使用实例
? 创建一个代码存放的文件,命名为code并打开终端
创建一个 test1.cpp 文件。
gedit test1.cpp
test1.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("pic.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;
}
执行以下命令:
g++ test1.cpp -o test1 `pkg-config --cflags --libs opencv`
?在用同文件夹下准备一张图片命名为pic.jpg
?
执行以下命令:
./test1
出现错误
执行以下命令:
sudo apt-get install libcanberra-gtk-module
安装好之后继续执行./test1
此时出现了一个png格式的图片
可以看到两者的呈现效果不同
视频实例
虚拟机获取摄像头的权限,使用快捷键 Win + R ,输入 services.msc ,并回车。
确保启动了此服务
点击 “ 虚拟机 ” ,然后点击 “ 设置(S)… ”。
选择 “ USB控制器 ” ,将 “ USB兼容性 ” 设置为 “ USB 3.0 ” ,并点击确定。
选择 “ 虚拟机 ” ,再选择 “ 可移动设备 ” ,再选择 “ Acer HD WebCam ” ,最后点击 “ 连接 ” ,再弹出的窗口内点击 “ 确定 ” 。?
出现此图标说明连接成功
创建一个 test2.cpp 文件。
gedit test2.cpp
复制以下代码
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
//从摄像头读取视频
VideoCapture capture("video.mp4");
//循环显示每一帧
while(1){
Mat frame;//定义一个Mat变量,用于存储每一帧的图像
capture >> frame;//读取当前帧
if(frame.empty())//播放完毕,退出
break;
imshow("读取视频帧",frame);//显示当前帧
waitKey(30);//掩饰30ms
}
system("pause");
return 0;
}
编译 test2.cpp 文件。
g++ test2.cpp -o test2 `pkg-config --cflags --libs opencv`
准备一个视频,命名为video.mp4
运行test2
完成视频播放
?视频录制
创建一个 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;
}
?
?
g++ test3.cpp -o test3 `pkg-config --cflags --libs opencv`
?
输出结果。
./test3
可以看到调用了摄像头来录制视频
?
生成了.avi文件
三、总结
? 本次实验过后我初步理解了在Linux操作系统下的静态库和动态库原理,以及简单的OpenCV应用实例。
四、参考网站
gcc生成静态库.a和动态库.so_Harriet的博客-CSDN博客
Ubuntu18.04下OpenCV3.4.11的安装及使用示例_ssj925319的博客-CSDN博客
动态链接库(编程相关名词)_百度百科
静态库_百度百科
|