OpenCV学习
OpenCV 是一个开源的计算机视觉库,用C语言和 C++ 语言编写,多平台可用,有 Python、Java、Matlab 以及其他一些语言的接口。获取网站
1. 框架
System:与系统的交互
Binding&Example:语言绑定 和 示例应用程序。
OpenCV Contrib:其他开发者贡献的模块
OpenCV:OpenCV的核心模块,有原始的如:Core、improc
HAL:硬件加速层、硬件优化
2. 基本API
2.1 memory 内存问题
OpenCV 已经实现了对于这些数据结构自动分配和释放内存的机制。但是,当数据结构共享相同的缓冲存储器时(不同对象指向相同地址的时候)。
赋值运算符:并没有从一个对象(Mat A)到另一个对象(Mat B)复制内存内容;而只是对其引用(相应内容的存储地址)的复制。
Mat::clone():复制一个 Mat 对象的内存内容(新的内存)。
2.2 Mat对象
Core Module:Mat
OpenCV 中的许多函数在处理密集的单通道或多通道数组时,常使用 Mat 类。但是在某些场合,使用一个不同的数据类型可能很方便。
单通道数组:
多通道数组:
std::vector<>、Matx<>、Vec<> 或 Scalar。为此,OpenCV 提供了代理类 InputArray 和 OutputArray,允许前面的任意类型作为函数的参数使用。
实数或复数值向量和矩阵、彩色图像或灰度图像、直方图、点云等都可以存储
2.3 namespace
using namespace cv
- 包含头文件后还应添加使用命名空间
cv
的声明(using namespace cv)
- 所有 OpenCV 类、函数和数据结构上附加
cv::
前缀,因为有的名字可能和其他库冲突,比如STL。
2.4 图像格式
OpenCV支持:
- Windows bitmaps(*.bmp、*dib);
- Portable image formats(.pbm、.pgm、*.ppm);
- Sun rasters(.sr、.ras)
- Geographic Data Abstraction Library,GDAL
- libjpeg、libjasper、libpng和libtiff (Windows,OS X 下支持)
需要辅助库的:
- JPEG(.jpeg、.jpg、*.jpe);
- JPEG 2000(*.jp2);
- Portable Network Graphics(*.png);
- TIFF(.tiff、.tif);
- WebP(*.webp);
2.5 图像读写示例
#include <opencv2/opencv.hpp> // OpenCV的 头文件引用
#include <iostream>
using namespace std;
using namespace cv; //OpenCV的命名空间 cv
int main(int, char *argv[])
{
// Mat 对象(输入输出图像的存储)
Mat in_image, out_image;
// 原始图像读取
in_image = imread(argv[1], IMREAD_UNCHANGED);
if (in_image.empty()) {
//检查是否成功读取图像
cout << "Error! Input image cannot be read...\n";
return -1;
}
// 创建两个显示图像的窗口
namedWindow(argv[1], WINDOW_AUTOSIZE);
namedWindow(argv[2], WINDOW_AUTOSIZE>;
//在之前创建的窗口中显示原始图片
imshow(argv[1], in_image);
// 一个图像操作
cvtColor(in_image, out_image, COLOR BGR2GRAY);
// 在第二个窗口中显示处理过的图像
imshow(argv[2], in_image);
cout << "Press any key to exit...\n";
// 等待按键事件
waitKey();
// 写入图像
imwrite(argv[2], in_image);
return 0;
}
头文件&命名空间:
#include <opencv2/opencv.hpp>
// #include 指令包含 opencv.hpp 头文件,
// 实际上,它包含所有的 OpenCV 头文件。
// 包含该单个文件之后,不再需要包含其他文件。
#include <iostream>
// 标准输入输出流的库的头文件
using namespace std;
// 标准库的命名空间
using namespace cv;
// OpenCV的命名空间
文件读取:
/*
* 在OpenCV 3.0 版本中,函数 imread 是在 imgcodecs 模块中
* @filename:文件地址
* @flags:图像操作标志
*/
Mat imread(const String& filename,int flags = IMREAD_COLOR)
// flags的取值:
enum { IMREAD_UNCHANGED = -1, // 8 位,彩色或非彩色
IMREAD_GRAYSCALE = 0, // 8 位,灰度
IMREAD_COLOR = 1, //未改变深度、颜色
IMREAD_ANYDEPTH = 2, //任意深度,未改变颜色
IMREAD_ANYCOLOR = 4, //未改变深度,任意颜色
IMREAD_LOAD_GDAL = 8 // 使用 gdaL 驱动程序
};
// 检查图像读取是否成功
in_image.empty()
图像显示:
读取图像文件时没有发生错误则会创建两个窗口分别显示输入图像和输出图像
/*
* 窗口创建函数
* @filename:文件地址
* @flags:图像操作标志
*/
void namedWindow(const String& winname,int flags = WINDOW_AUTOSIZE)
// flags的取值
enum { WINDOW_NORMAL = 0x00000000,
//用户可以调整窗口的大小(无约束)
//还可以将一个全屏窗口切换为常规窗口
WINDOW_AUTOSIZE = 0x00000001,
//用户不能调整窗口的大小,
//窗口的大小由显示的图像所限制
WINDOW_OPENGL = 0x00001000, // OpenGL 支持的窗口
WINDOW_FULLSCREEN = 1,
WINDOW_FREERATIO=0x00000100,
//图像可任意使用(调整图像时可没有比例限制)
WINDOW_KEE PRATIO = 0x00000000
//调整图像时保持图像的缩放比例
};
/*
* 图像显示, highgui 模块
*/
void imshow(const String& winname,InputArray mat)
内部循环中处理事件:
若窗口上显示一幅图像之后不再做操作,将不再显示图像(图像闪现),显示一幅图像之后,我们想它一直显示,那么就要调用 highgui 模块waitKey(delay)函数用于获取和处理与用户和窗口交互有关的事件。
// highgui 模块
int waitKey(int delay=0)
// delay > 0内等待一个按键操作,并返回键的编码,如果延迟结束时没有按键则返回 -1。
// delay = 0 或 < 0 ,那么函数一直等待直到一个键被按下
写入文件
将一个图像保存到一个文件里面。
/*
* filename:文件名
* img:图像的输入数组缓存
* params:可选参数,默认为空,一个“属性-值”对的向量指定编解码器的参数
*/
bool imwrite(const String& filename,
InputArray img,
const vector<int>& params=vector<int>())