GCC编译器与OpenCV图像编程

  • 一、可执行程序的组装过程
    • (一)用 gcc 生成 .a 静态库和 .so 动态库
      • 1.编辑得到举例的程序:hello.h、hello.c和main.c
      • 2.将hello.c编译成.o文件;
      • 3.由.o文件创建静态库
      • 4.在程序中使用静态库
      • 5.由.o文件创建动态库文件
      • 6.在程序中使用动态库
    • (二)Linux下静态库.a与.so库文件的生成与使用
      • 1.编辑所需程序
      • 2.静态库.a文件的生成与使用
      • 3.共享库.so文件的生成与使用
    • (三)程序改编
      • 1.完成目标1
      • 2.完成目标2
    • (四)Linux GCC编译过程
      • 1.程序准备
      • 2.程序的简单编译
      • 3.程序的分步编译
  • 二、OpenCV与图像编程
    • 1. 在Ubuntu下安装OpenCV
    • 2. 在Ubuntu下编写一个打开图片进行特效显示的代码
    • 3. 编写一个视频播放程序
    • 4. 使用opencv库编写程序

一、可执行程序的组装过程

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

我们通常把一些公用函数制作成函数库,供其它程序使用。函数库分为静态库和动态库两种。静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在。

通过举例来说明在Linux中如何创建静态库和动态库,以及使用它们,在创建函数库前,我们先来准备举例用的源程序,并将函数库的源程序编译成.o文件。

1.编辑得到举例的程序:hello.h、hello.c和main.c

hello.c是函数库的源程序,其中包含公用函数hello,该函数将在屏幕上输出"Hello XXX!"。hello.h为该函数库的头文件。main.c为测试库文件的主程序,在主程序中调用了公用函数hello。

hello.h

hello.c

main.c

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

无论静态库,还是动态库,都是由.o文件创建的。因此必须将源程序hello.c通过gcc先编译成.o文件。

在系统提示符下键入以下命令得到hello.o文件。
gcc -c hello.c

通过ls命令查看是否生成了hello.o文件

3.由.o文件创建静态库

静态库文件名的命名规范是以lib为前缀,紧接着跟静态库名,扩展名为.a。例如:我们将创建的静态库名为myhello,则静态库文件名就是libmyhello.a。在创建和使用静态库时,需要注意这点。创建静态库用ar命令。

在系统提示符下键入以下命令将创建静态库文件libmyhello.a,并用ls命令查看结果
ar -crv libmyhello.a hello.o

4.在程序中使用静态库

静态库制作完后,只需要在使用到这些公用函数的源程序中包含这些公用函数的原型声明,然后在用gcc命令生成目标文件时指明静态库名,gcc将会从静态库中将公用函数连接到目标文件中。注意,gcc会在静态库名前加上前缀lib,然后追加扩展名.a得到的静态库文件名来查找静态库文件。

在程序3:main.c中,我们包含了静态库的头文件hello.h,然后在主程序main中直接调用公用函数hello。下面先生成目标程序hello,然后运行hello程序看看结果如何。

输入以下指令:gcc main.c libmyhello.a -o hello

我们删除静态库文件试试公用函数hello是否真的连接到目标文件 hello中了。

程序照常运行,静态库中的公用函数已经连接到目标文件中了。

5.由.o文件创建动态库文件

继续看看如何在Linux中创建动态库,还是从.o文件开始。

动态库文件名命名规范和静态库文件名命名规范类似,也是在动态库名增加前缀lib,但其文件扩展名为.so。例如:我们将创建的动态库名为myhello,则动态库文件名就是libmyhello.so。用gcc来创建动态库。

在系统提示符下键入以下命令得到动态库文件libmyhello.so,并用ls命令查看
gcc -shared -fPIC -o libmyhello.so hello.o

6.在程序中使用动态库

在程序中使用动态库和使用静态库完全一样,也是在使用到这些公用函数的源程序中包含这些公用函数的原型声明,然后在用gcc命令生成目标文件时指明动态库名进行编译。

先运行gcc命令生成目标文件,再运行它看看结果。

输入以下指令:gcc -o hello main.c -L. -lmyhello

这里出现了错误,查看错误提示,原来是找不到动态库文件libmyhello.so。程序在运行时,会在/usr/lib和/lib等目录中查找需要的动态库文件。若找到,则载入动态库,否则将提示类似上述错误而终止程序运行。我们将文件libmyhello.so复制到目录/usr/lib中,再重新尝试

(二)Linux下静态库.a与.so库文件的生成与使用

1.编辑所需程序

A1.c

A2.c

A.h

test.c

2.静态库.a文件的生成与使用

(1)生成目标文件(XXX.o)
指令如下:gcc -c A1.c A2.c

(2)生成静态库.a文件
指令如下:ar crv libafile.a A1.o A2.o

(3)使用.a 库文件
创建可执行程序(若采用此种方式,需保证生成的.a 文件与.c 文件保存在同一目录下,即都在当前目录下)
指令如下:
cpp gcc -o test test.c libafile.a
./test

3.共享库.so文件的生成与使用

(1)生成目标文件(XXX.o)
此处生成.o 文件必须添加"-fpic"(小模式,代码少),否则在生成.so文件时会出错
指令:gcc -c -fpic A1.c A2.c

(2)生成共享库.so文件
指令:gcc -shared *.o -o libsofile.so

(3)使用.so 库文件,创建可执行程序
指令:gcc -o test test.c libsofile.s

当输入以下指令时:./test
发现出现错误:

原因与之前使用动态库的情况相同:找不到对用的.so文件,故需将对应 so 文件拷贝到对应路径。

指令如下:sudo cp libsofile.so /usr/lib

同时可直接使用 gcc -o test test.c -L. -lname,来使用相应库文件
其中,
-L.:表示在当前目录下,可自行定义路径 path,即使用-Lpath 即可。
-lname:name:即对应库文件的名字(除开 lib),即若使用 libafile.a,则 name 为 afile;若要使用 libsofile.so,则 name 为 sofile。

(三)程序改编

源程序编写过程链接:嵌入式系统程序设计基础

目标:
① 除了x2x函数之外,再扩展写一个x2y函数(功能自定),main函数代码将调用x2x和x2y ;将这3个函数分别写成单独的3个 .c文件,并用gcc分别编译为3个.o 目标文件;将x2x、x2y目标文件用 ar工具生成1个 .a 静态库文件, 然后用 gcc将 main函数的目标文件与此静态库文件进行链接,生成最终的可执行程序,记录文件的大小。
② 将x2x、x2y目标文件用 ar工具生成1个 .so 动态库文件, 然后用 gcc将 main函数的目标文件与此动态库文件进行链接,生成最终的可执行程序,记录文件的大小,并与之前做对比。

1.完成目标1

(1)编辑所需程序

x2x.c

x2y.c

main.c

(2)将以上文件用gcc编译成.o文件


(3)将x2x.o和x2y.o用 ar工具生成 .a 静态库文件

(4)使用gcc将main.c文件与此静态库文件进行链接

(5)运行xymain程序


记录文件大小为16888B

2.完成目标2

(1)将x2x.o、x2y.o文件用ar工具生成.so 动态库文件
(2)用gcc将main.c文件与此动态库文件进行链接

(3)运行somain

记录文件大小为16888B


(四)Linux GCC编译过程

GCC 的意思是 GNU C Compiler 。经过了这么多年的发展,GCC 已经不仅仅能支持 C语言;它现在还支持 Ada 语言、C++ 语言、Java 语言、Objective C 语言、Pascal 语言、COBOL语言,以及支持函数式编程和逻辑编程的 Mercury 语言等等。而 GCC 也不再单只是 GNU C 语言编译器的意思,而是变成了 GNU Compiler Collection 也即是 GNU 编译器家族的意思了。另一方面,说到 GCC 对于操作系统平台及硬件平台支持,概括起来就是一句话:无所不在。

1.程序准备

test.c

2.程序的简单编译

这个程序的一步到位的编译指令是gcc test.c -o main

3.程序的分步编译

实质上,上述编译过程是分为四个阶段进行的,即预处理(也称预编译,Preprocessing)、编译(Compilation)、汇编 (Assembly)和连接(Linking)。

gcc -E test.c -o test.i //预处理
gcc -S test.i -o test.s //编译
gcc -c test.s -o test.o //汇编
gcc test.o -o test //连接

执行以上指令后生成以下文件,并查看运行结果

二、OpenCV与图像编程

在Ubuntu系统下练习编译、安装C/C++图像处理开源软件库 Opencv 。

1. 在Ubuntu下安装OpenCV

该过程请参考在 Ubuntu系统下安装 OpenCV 全过程

2. 在Ubuntu下编写一个打开图片进行特效显示的代码

(1)在OpenCV的安装目录下创建一个新文件夹mytest,并创建一个test.cpp文件;

把图片直接放在home路径下,并复制一份在mytest文件夹中

cd opencv-3.4.8
mkdir mytest
touch test.cpp
sudo gedit /test.cpp

(2)编辑以下代码:

#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("lena.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("psb.png", src);cvNamedWindow("test",1);   imshow("test", src);cvWaitKey();return 0;
}

(3)保存并编译

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


(4)通过./test指令运行

3. 编写一个视频播放程序

(1)编写一个test2.cpp文件
代码如下:

#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{//从摄像头读取视频VideoCapture capture("man.mp4");//循环显示每一帧while(1){Mat frame;//定义一个Mat变量,用于存储每一帧的图像capture >> frame;//读取当前帧if(frame.empty())//播放完毕,退出break;imshow("读取视频帧",frame);//显示当前帧waitKey(30);//掩饰30ms}system("pause");return 0;
}
  • 如果语句:VideoCapture capture(0),后面的参数设置为 0 ,则从摄像头读取视频并循环显示每一帧;如果设置为一个视频的文件名,比如:man.mp4 ,则会将视频读取并循环显示每一帧;
  • while 循环体中的Mat数据结构其实是一个点阵,对应图像上的每一个点,点的集合形成了一帧图像;
  • 语句:waitKey(30) ,中的参数单位是 ms 毫秒,也就是每一帧间隔 30 ms ,该语句时不能删除的,否则会执行错误,无法播放视频或录制视频。

4. 使用opencv库编写程序

步骤如下:
(1)编译一个开启摄像头并录制视频的程序

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

编译并运行

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

参考文献:
1.gcc生成静态库.a和动态库.so
2.Ubuntu18.04下OpenCV3.4.11的安装及使用示例
3.【嵌入式】Windows10&Ubantu16.04&树莓派3B+安装opencv教程
4.在 Ubuntu系统下安装 OpenCV 全过程
5.OpenCV读取和写入视频文件
6.OpenCV中Mat数据结构

GCC编译器与OpenCV图像编程相关推荐

  1. gcc编译器的使用操作及opencv图像编程

    目录 一.gcc 生成 .a 静态库和 .so 动态库 1.创建作业目录 2.用vim编写hello.h.hello.c和main.c文件 3.将 hello.c 编译成.o 文件 4.由.o文件创建 ...

  2. ubuntu下opencv图像编程

    ubuntu下opencv的图像编程 一.ubuntu安装opencv-3.4.1 二.使用opencv打开一张图片 三.使用opencv打开摄像头 四.使用opencv打开一个视频文件 五.通过摄像 ...

  3. opencv图像编程

    文章目录 一.安装opencv 二.使用opencv进行图像编程 三. 打开摄像头显示处理视频 一.安装opencv 1.1 官网地址 点击上面进入官网 下载source 1.2 将刚刚下载的复制到u ...

  4. Ubuntu系统下基于Opencv完成图像编程

    文章目录 一.OpenCV简介 二.安装OpenCV 2.1 安装包下载 2.2 使用cmake安装 2.3 配置环境 三.使用实例 3.1 图片运用 3.2 视频运用 四.总结 五.参考文献 一.O ...

  5. OpenCV计算机视觉编程篇三《处理图像的颜色》

    前言 前期回顾: OpenCV计算机视觉编程篇二<操作像素> 上面这篇里面写了操作像素相关. 本章包括以下内容: 用策略设计模式比较颜色: 用 GrabCut 算法分割图像: 转换颜色表示 ...

  6. opencv计算机视觉编程攻略 第2版,OpenCV计算机视觉编程攻略(第2版)pdf

    摘要 1. 50多个知识点的案例解读,全面掌握基础知识与进阶内容 2. 学习OpenCV重要的图像操作类和函数 3. 初学者和从业者即查即用的工具书 4. 掌握计算机视觉与图像处理的基础知识与概念 O ...

  7. vs编译器 printf 控制台输出_【语言教程】通过语言了解GCC编译器工作过程

    通过c语言了解GCC编译器如何工作的 比特 下面是c语言初学必看的打印helloworld #include int main(){ printf("hello, world\n" ...

  8. OpenCV计算机视觉编程攻略之行人检测

    OpenCV计算机视觉编程攻略之行人检测,OpenCV 提供了一个基于HOG 和SVM且经过训练的行人检测器,可以用这个SVM 分类器以不同尺度的窗口扫描图像,在完整的图像中检测特定物体. 原图如下: ...

  9. 【CentOS Linux 7】【gcc编译器】

    Linux系统及应用---调研报告 [CentOS Linux 7]实验1[VMware安装.新建虚拟机:63个基础命令运行结果图] [CentOS Linux 7]实验2[Shell编程及应用] [ ...

最新文章

  1. android自定义控件绘制位置,Android自定义控件之——文字圆形边框(将文字绘制在圆中间)...
  2. shell 去掉字符串中的字母
  3. idea中修改jsp文件不用再重启tomcat的方法
  4. BugFree2.1.3升级到BugFree3.0.2
  5. React组件实现越级传递属性
  6. android物理健代码,Android 物理按键整理及实例代码
  7. Android平台Native开发与JNI机制详解
  8. PTA 11-散列4 Hard Version (30分)
  9. linux内核网络协议栈学习笔记:关于GRO/GSO/LRO/TSO等patch的分析和测试
  10. 最后一个自己_拔剑-浆糊的传说_新浪博客
  11. LaTeX 格式、字母、符号、公式 (总结)
  12. 翻译:俄国卫星GLONASS 简介 天基全球导航卫星系统 (GNSS)
  13. 微信支付接入-弹出支付框输入密码后一直在转圈,20s后提示:支付失败,请稍后再试
  14. pip国内镜像解决no matching distribution found for XXX
  15. RPC中Stub的理解
  16. “很抱歉,出现错误,Word不能启动(2)。”解决方法(转载),2023-3-3
  17. 特征工程(七):图像特征提取和深度学习
  18. 条码打印机的市场现状
  19. bat: 删除文件、文件夹
  20. 网页大作业——街机游戏拳皇(KOF)系列的介绍及试玩。

热门文章

  1. STM32F407ZGT6通信协议学习
  2. 钉钉审批流的调用(官方推荐审批流)
  3. 近期健康类(***)
  4. SCM(供应链管理)的概念
  5. Sharding-JDBC之 读写分离
  6. 走投无路的算法学习笔记|Day001
  7. 洛谷P3205 [HNOI2010]合唱队
  8. Minor GC、Major GC、Full GC的区别
  9. 装完deepin系统第一件事:设置root的密码--去掉文件夹上的小锁
  10. 图像和视频质量评估算法 资源帖