opencv虽然很有名,但是自己一直没怎么玩过,暑假的时候使用深度相机做项目,但负责的不是代码模块,也只是配好了环境,没有继续了解图像处理。最近电子实习老师有教这个东西,但是身边不少同学遇到了麻烦,所以在此总结了一下,汇总了一些我行之有效的教程和官方资料,并且附上了两个例程;方便ubuntu环境下的opencv新手快速上手。

00 opencv4.5.3

先放一个链接,当初在ubuntu1804上无痛配置好opencv4.5.3的环境,采用的是这个教程.

下面是我自己的总结,大家可以避免页面跳转。

00-1 安装相关软件包

1 sudo apt install  build-essential
2
3 sudo apt install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
4
5 sudo apt install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev

如果第三个命令行无法定位软件包;

1 sudo apt install  build-essential
2
3 sudo apt install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
4
5 sudo apt install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev

libjasper1 是 libjasper-dev 的依赖包

00-2 源码下载

opencv官网下载:Releases - OpenCV

找到自己想要的版本,这里我使用的是4.5.3,暑假的时候还算比较新,现在已经out了。

下载成功后解压,解压到哪个文件夹都可以。

00-3 编译源码

采用cmake的编译方法对下载解压后的软件包进行编译。

进入解压出来的OpenCV-4.1.0文件夹,创建一个新文件夹,我创建的叫 build

进入新文件夹,打开终端,进入这个文件夹

执行命令

1 cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/your_opencv_install_path
2 ​
3 sudo make
4 //为了快也可以直接 sudo make -j3并行编译
5 ​
6 sudo make install

完成后,OpenCV 就安装好了,接下来要配置 OpenCV 的编译环境;

00-4 配置环境

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

打开opencv.conf ,打开后很可能是空白

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

在文末添加

 /usr/local/lib 

接下来配置 bash

 sudo gedit /etc/bash.bashrc  

在文末添加

1 PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
2 ​
3 export PKG_CONFIG_PATH

保存后退出刷新(source)

1 source /etc/bash.bashrc
2
3 sudo updatedb
 

配置完成。

01 测试安装成功

转到 opencv-4.5.3/sample/cpp/example_cmake 目录下,打开终端

运行如下命令:

1 cmake .
2 make
3 ./opencv_example

弹出该页面:

然后把电脑自带的摄像头打开,就会出现画面。说明安装、配置成功。

02 读取jpg并显示

02-1 工程建立

首先,在opencv4.5.3文件夹里建立一个我们学习用的文件夹,日后所有的学习项目都会放在这里,方便管理。

 mkdir opencv-learn 

然后,我们进入这个文件夹

 cd opencv-learn 

建立今天的第一个项目

1 mkdir learn1
2 cd learn1
3 touch DisplayImage.cpp

02-2 C++程序

编写我们读取jpg并显示的程序

 1 #include <stdio.h>
2 #include <opencv2/opencv.hpp>
3 using namespace cv;
4 int main(int argc, char** argv )
5 {
6 if ( argc != 2 )
7 {
8 printf("usage: DisplayImage.out <Image_Path>\n");
9 return -1;
10 }
11 Mat image;
12 image = imread( argv[1], 1 );
13 if ( !image.data )
14 {
15 printf("No image data \n");
16 return -1;
17 }
18 namedWindow("Display Image", WINDOW_AUTOSIZE );
19 imshow("Display Image", image);
20 waitKey(0);
21 return 0;
22 }

02-3 代码解析

opencv的代码风格与arduino很相似,函数很多,且名字与功能强相关,初入门的编程主要是函数的调用,不涉及复杂数据结构与算法。

前面的if-else是鲁棒性保证,感兴趣可以查一下argv与argc;这里代码的意思是如果命令行编译参数不是2,那么报错。

argv与argc简介如下:

这两个参数在使用命令行编译的时候有用。

  1. argc 为整型,是命令行参数的个数;

  2. argv 是字符串型,为字符串数组,数组成员意义如下:

    argv[0]指向程序名;

    argv[1]指向程序名后的第一个字符串;

    ...以此类推


接下来:

 Mat image;  

定义一个Mat格式的矩阵image用来存储下面会用到的图片。

  image = imread( argv[1], 1 ); 

把读取的图片信息,存进来。

  namedWindow("Display Image", WINDOW_AUTOSIZE );  

这里是指定展现处理后图片的视窗的名字

1    imshow("Display Image", image);
2 waitKey(0);

展示图片(会弹出一个视窗,名字是上面定义的名字)

int waitKey(int delay=0)的功能是不断刷新图片,频率由delay来衡量。

  1. 在显示图片和视频时,会在imshow()时,通常在后面加上while(WaitKey(n)==key),key为大于0的数即可,这样程序将在此处循环运行直到按键响应为key。

  2. delay:为0时,则会一直显示这一帧,这在显示摄像头和视频时有用。这个参数用于设置在显示完一帧图像后程序等待“delay”ms后再显示下一帧图片。

  3. 举几个例子

    1 if(waitKey(10)>=0)//是说10ms中按任意键进入if语句
    2
    3 while(waitKey(2)!=27)//表示不按Esc按键则一直在2ms后显示

02-4 CMakeLists.txt编写

A 内容

接下来我们采用CMakeLists.txt的形式进行编译。

这种形式可以避免引用库不全面而造成的未定义报错。//而这在opencv编程中是经常出现的。

因此CMakeLists.txt是一种很好的编译方式,值得学习。

1 touch CMakeLists.txt
2
3 gedit CMakeLists.txt

在弹出的页面

1     cmake_minimum_required(VERSION 2.8)
2 project( DisplayImage )
3 find_package( OpenCV REQUIRED )
4 add_executable( DisplayImage DisplayImage.cpp )
5 target_link_libraries( DisplayImage ${OpenCV_LIBS} )

B 解释

这里这些语句的意思是:

1.cmake_minimum_required,指定最小需要的版本。里面的内容也是与版本信息有关。

2.project,基本用法是:用于指定cmake工程的名字,比如此处就制定了当前工程的名字是DisplayImage

3.find_package

关于find_package

当我们编译一个需要使用第三方库的程序时,我们需要知道的是:

目标 对照
去哪儿找头文件 .h GCC的 -I 参数
去哪儿找库文件 (.so/.dll/.lib/.dylib/…) GCC的 -L参数
需要链接的库文件的名字 GCC的 -l 参数

比如我们需要一个第三方库 curl,那么我们的 CMakeLists.txt 需要指定头文件目录,和库文件,类似:

1 include_directiories(/usr/include/curl)
2
3 target_link_libraries(myprogram path/curl.so)

而如果我们要借助cmake语法的功能,如果借助于cmake提供的finder会怎么样呢?使用cmake的Modules目录下的FindCURL.cmake,相应的CMakeList.txt 文件:

1 find_package(CURL REQUIRED)
2
3 include_directories(${CURL_INCLUDE_DIR})
4
5 target_link_libraries(curltest ${CURL_LIBRARY})

cmake是如何查找这些列出的第三方库的,在这里就不谈了

可以看出我们编写的CMakeList.txt这句的意思是OpenCV的依赖库的添加。

4.add_executable

使用指定的源文件来生成目标可执行文件。这里的目标可执行文件分为三类:

  1. 普通可执行目标文件

  2. 导入可执行目标文件

  3. 别名可执行目标文件

分别对应的三种命令格式如下:

1 add_executable (<name> [WIN32] [MACOSX_BUNDLE]
2       [EXCLUDE_FROM_ALL]
3       [source1] [source2 ...])
4       
5 add_executable (<name> IMPORTED [GLOBAL])
6 ​
7 add_executable (<name> ALIAS <target>)

这里使用的是最简单的形式:

 1 #语法:add_executable(可执行程序名 要编译的cpp) 

5.target_link_libraries

该指令的作用为将目标文件与库文件进行链接。

这项的编写需要注意:库之间可能也存在着依赖关系,被依赖的库放在后面。

02-5 编译

编写完成后,我们编译这个项目:

1 cmake .
2
3 make

记得在项目里(与代码同文件夹下)放入我们要处理的图片(jpg)。

02-6 执行得到结果

然后我们执行

  ./DisplayImage TEST.jpg 

即可看到C++程序调用opencv处理后显示的图片,虽然在此例子中展示的是图片原貌。

在这个程序基础上可以实现灰度图等等。

03 使用电脑摄像头初步

03-1 工程建立

我们建立一个新的文件夹learn2并建立文件

1 mkdir learn2
2
3 cd learn2
4
5 touch testopencv_camera.cpp

03-2 C++程序

 1 //两个功能:如果直接运行程序./exe文件,就是打开电脑摄像头并显示;如果./exe avi视频,那会读取这个avi视频,并在窗口里显示出来。
2 #include "opencv/highgui.h"
3 #include "opencv/cv.h"
4 using namespace std;
5 using namespace cv;
6
7 int main(int argc, char** argv){
8 cvNamedWindow("testcamera", CV_WINDOW_AUTOSIZE);
9 CvCapture* capture;
10 if (argc == 1){
11 capture=cvCaptureFromCAM(0);
12 printf("capture 0\n");
13 }
14 else {
15 capture = cvCreateFileCapture(argv[1]);
16 printf("capture argv1\n");
17 }
18 assert(capture != NULL);
19 IplImage* frame;
20 frame = cvCreateImage(cvSize(640, 320), IPL_DEPTH_16U, 3);
21 while(1){
22 frame = cvQueryFrame(capture);
23 if (!frame)
24 break;
25 cvShowImage("testcamera", frame);
26 char c=cvWaitKey(33);//显示间隔是33ms
27 if (c==27)////27ms内按下任意建进入if
28 break;
29 }
30 cvReleaseCapture(&capture);
31 cvDestroyWindow("testcamera");
32 return 0;
33 }
34 ​

03-3 代码解析

常规库、工作空间准备;

1 #include "opencv/highgui.h"
2 #include "opencv/cv.h"
3 using namespace std;
4 using namespace cv;

接下来,如果我们的命令行编译参数只有一个(argc==1)那么调用cvCaptureFromCAM()函数初始化CvCapture结构的 capture变量。

这是OpenCV库中的一个函数。

初始化从摄像头中获取的视频

 CvCapture* cvCaptureFromCAM( int index ); 
  • index是个整数;

  • 要使用的摄像头索引。如果只有一个摄像头或者用哪个摄像头也无所谓,那使用参数-1应该便可以。


这个函数用“从摄像头获取的视频流“分配和初始化CvCapture结构。

  1. 目前在Windows下可使用两种接口:Video forWindows(VFW)和Matrox Imaging Library(MIL);

  2. Linux下也有两种接口:V4L和FireWire(IEEE1394)。(现在不需要深入了解这个)

释放这个结构,使用函数cvReleaseCapture。

接着,否则的话,我们这个程序会判定我们将使用下面这个功能:

读取一段视频(avi格式)并显示出来;

我们选取参数中的第二个参数(avi视频)读取到capture变量里。

接下来是一个鲁棒性过滤

1  assert(capture != NULL);
2 //意为如果表达式为假,整个程序将推出,不再运行,如果表达式成立,则继续运行。
3 ​
4 //使用assert()的缺点是,频繁的调用会极大的影响程序的性能,增加额外的开销。

接下来我们要创建一个3通道图像变量(RGB图像)

1   IplImage* frame;//创建变量
2 ​
3 frame = cvCreateImage(cvSize(640, 320), IPL_DEPTH_16U, 3);
4 //宽为640,高为360,图像像素的位深度为16位无符号整数的图像
5 //尽管在一般IPL图像格式中可以以非交叉的方式存储,并且一些OpenCV可以处理它,但此函数只能创建交叉存储的图像。

函数cvCreateImage创建图像首地址,并分配存储空间。

IplImage* cvCreateImage(CvSize cvSize(int width, int height), int depth, int channels);

接下来进入循环

摄像头或者文件中抓取并解压返回这一帧

   frame = cvQueryFrame(capture); 

这个函数:

 1 IplImage* cvQueryFrame( CvCapture* capture ); 

这个函数仅仅是函数cvGrabFrame和函数cvRetrieveFrame在一起调用的组合。

返回的图像不可以被用户释放或者修改。

抓取后,capture被指向下一帧,可用cvSetCaptureProperty调整capture到合适的帧。

如果图像存储空间没有批下来,则退出循环;

1  if (!frame)、
2 break;

批下来了,就展示出来视频的一帧frame

  cvShowImage("testcamera", frame); 

下面是退出程序的控制程序;

1     char c=cvWaitKey(33);
2 if (c==27)//27ms
3 break;
4 }
5 cvReleaseCapture(&capture);
6 cvDestroyWindow("testcamera");
7 return 0;

03-4 编译运行结果

1 # 编译
2 g++ testopencv_camera.cpp -o first `pkg-config --libs --cflags opencv` -ldl
3 #运行
4 ./first
5 #就可以看到电脑摄像头显示的"视频"

计算机视觉1->opencv4学习指南1 | 环境配置与例程的更多相关文章

  1. Qt5学习笔记(1)-环境配置(win+64bit+VS2013)

    Qt5学习笔记(1)-环境配置 工欲善其事必先-不装-所以装软件 久不露面,赶紧打下酱油. 下载 地址:http://download.qt.io/ 这个小网页就可以下载到跟Qt有关的几乎所有大部分东 ...

  2. 大数据学习之路—环境配置——IP设置(虚拟机修改Ip的内在原因及实现)

    一.IP原理 关于IP我的理解, (1)主要去理解IP地址的作用,IP地址包括网络相关部分和主机的相关部分.即:用一段特殊的数据,来标识网络特征和主机的特征. 至于具体的技术实现,日后可以慢慢体会和了 ...

  3. servlet:从入门到实战学习(1)---全·环境配置

    最近公司忙加班学习,学校忙助教工作,博客鸽了好久,后端学习工作过程中学了好多东西,趁着工作之余得空补补博客,算是整理下学习的东西. javaweb的后端研发需要学习的是tomcat+servlet+j ...

  4. JMeter学习-038-JMeter Linux 环境配置

    1.1.下载 Download URL:http://mirrors.tuna.tsinghua.edu.cn/apache//jmeter/binaries/apache-jmeter-3.0.tg ...

  5. 【lua学习笔记】——环境配置

    1 开发平台 windows7 64位 2 下载链接 http://www.lua.org/download.html 3 安装完成-环境配置 4  运行 WIN+R 运行 cmd 运行lua,显示配 ...

  6. 学习笔记-ionic3 环境配置搭建到打包

    折腾了两周总算理清楚了,参考的链接如下: https://blog.csdn.net/zeternityyt/article/details/79655150  环境配置 https://segmen ...

  7. OpenGL 学习笔记 01 环境配置

    以下教程仅适用于Mac下的Xcode编程环境!其他的我也不会搞. 推荐教程:opengl-tutorial  本项目Github网址       OpenGL太可怕了...必需得把学的记下来,不然绝壁 ...

  8. Maven 学习笔记——Maven环境配置(1)

    在学习Selenium的过程中,接触到了Maven(项目管理工具),不至于学一路忘一路,左耳朵进右耳多出,还是决定边学边记录,毕竟听的不如 看的,看的不如写的吗.首先学一样东西,肯定得明确学的是什么, ...

  9. WP8 学习笔记(001_环境配置)

    Step 1  WP8 的开发要求64位操作系统,Windows 8及以上版本,需要激活版,建议网上买一个注册码.详见安装双系统. Step 2 安装好系统并已经激活之后,需要安装Windows Ph ...

随机推荐

  1. javaSE高级篇7 — 设计原则和设计模式 — 设计模式慢慢更( 这是思想层次篇 )

    1.什么是设计原则? 设计原则就是面向对象的原则嘛,即:OOP原则 换句话说:就是为了处理类与类之间的关系( 包括接口.类中的方法 ) 2.OOP设计原则有哪些? 1).开闭原则:就是指对拓展开放.对 ...

  2. 生产调优2 HDFS-集群压测

    目录 2 HDFS-集群压测 2.1 测试HDFS写性能 测试1 限制网络 1 向HDFS集群写10个128M的文件 测试结果分析 测试2 不限制网络 1 向HDFS集群写10个128M的文件 2 测 ...

  3. Linux磁盘分区(一)之fdisk命令

    Linux磁盘分区(一)之fdisk命令转自:https://www.cnblogs.com/machangwei-8/p/10353683.html 一.fdisk 的介绍fdsik 能划分磁盘成为 ...

  4. Linux学习 - shell脚本执行

    一.shell概述 shell是一个命令行解释器,为用户提供一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以用shell来启动.挂起.停止甚至是编写一些程序 shell还是一个功能强 ...

  5. 使用jsp制作index,可以通过<c:if test==“管理员”>或<c:if test=="客户">来区别展示用户界面

    <%@ page contentType="text/html;charset=UTF-8" language="java" %><%@ ta ...

  6. 【Linux】【CentOS7】免密登录突然失效

    [报错解决]免密登录突然失效 哔哩哔哩 萌狼蓝天 博客:萌狼工作室-博客园 [问题描述] 原本配置好了的免密登录,今天启动hadoop发现免密登录失效了 [解决方案] 1.切换到管理员模式,进入配置文 ...

  7. 【Spark】【RDD】从HDFS创建RDD

    1.在HDFS根目录下创建目录(姓名学号) hdfs dfs -mkdir /zwj25 hdfs dfs -ls / 访问 http://[IP]:50070 2.上传本地文件到HDFS hdfs ...

  8. 并行Louvain社区检测算法

    因为在我最近的科研中需要用到分布式的社区检测(也称为图聚类(graph clustering))算法,专门去查找了相关文献对其进行了学习.下面我们就以这篇论文IPDPS2018的文章[1]为例介绍并行 ...

  9. C++STL标准库学习笔记(一)sort

    前言: 近来在学习STL标准库,做一份笔记并整理好,方便自己梳理知识.以后查找,也方便他人学习,两全其美,快哉快哉! 这里我会以中国大学慕课上北京大学郭炜老师的<程序设计与算法(一)C语言程序设 ...

  10. Jenkins构建通知

    目录 一.简介 二.推送到gitlab 三.邮件通知 自带配置 Email Extension 四.钉钉通知 五.脚本钉钉通知 六.HTTP请求通知 一.简介 类似于监控报警,jenkins在配置持续 ...