湛江做网站,带数据库的网站模板下载,wordpress optiontree,企业官网搭建OpenCV简介
OpenCV#xff08;开源计算机视觉库#xff1a;http://opencv.org#xff09;是一个开源库#xff0c;包含数百种计算机视觉算法。OpenCV 具有模块化结构#xff0c;主要包括下列模块#xff1a;
核心功能#xff08;core#xff09; - 定义基本数据结构的…OpenCV简介
OpenCV开源计算机视觉库http://opencv.org是一个开源库包含数百种计算机视觉算法。OpenCV 具有模块化结构主要包括下列模块
核心功能core - 定义基本数据结构的紧凑模块包括密集多维数组 Mat 和所有其他模块使用的基本函数。图像处理( imgproc) - 图像处理模块包括线性和非线性图像过滤、几何图像变换调整大小、仿射和透视变形、基于通用表的重新映射、颜色空间转换、直方图等。视频分析( video ) - 视频分析模块包括运动估计、背景扣除和对象跟踪算法。相机校准和 3D 重建( calib3d ) -基本多视图几何算法、单立体相机校准、物体姿态估计、立体对应算法和 3D 重建元素。2D 特征框架( features2d ) -显着特征检测器、描述符和描述符匹配器。对象检测( objdetect ) -检测预定义类的对象和实例例如面部、眼睛、杯子、人、汽车等。高级 GUI ( highgui ) - 一个易于使用的界面具有简单的UI 功能。视频 I/O ( videoio ) - 一个易于使用的视频捕获和视频编解码器接口。…一些其他帮助模块例如 FLANN 和 Google 测试包装器、Python 绑定等。
当前的 OpenCV 实现是完全可重新输入的。也就是说不同类实例的相同函数或相同方法可以从不同线程调用。此外相同的 Mat 可以在不同的线程中使用因为引用计数操作使用特定于体系结构的原子指令
API概念
命名空间
opencv 的所有类和函数都存放在 cv 命名空间中。因此要引用 opencv 的代码需要增加作用域运算符 cv::在项目开发中建议不用使用 using namespace cv 定义作用域范围可能会引起某些的冲突。jpg是一个有损压缩算法在平时使用时尽量避免使用。
自动内存管理
OpenCV的内存管理机制类似 Shared_ptr, Mat 对象只有当引用计数为 0其内存空间才会真正得销毁当一个 Mat 实例被拷贝时内存并不会真正的发生复制行为而是将改对象的引用计数增加 1 可以使用 cv::Mat::clone 进行实际 “全复制”。
// create a big 8Mb matrix
Mat A(1000, 1000, CV_64F);
// create another header for the same matrix;
// this is an instant operation, regardless of the matrix size.
Mat B A;
// create another header for the 3-rd row of A; no data is copied either
Mat C B.row(3);
// now create a separate copy of the matrix
Mat D B.clone();
// copy the 5-th row of B to C, that is, copy the 5-th row of A
// to the 3-rd row of A.
B.row(5).copyTo(C);
// now let A and D share the data; after that the modified version
// of A is still referenced by B and C.
A D;
// now make B an empty matrix (which references no memory buffers),
// but the modified version of A will still be referenced by C,
// despite that C is just a single row of the original A
B.release();
// finally, make a full copy of C. As a result, the big modified
// matrix will be deallocated, since it is not referenced by anyone
C C.clone();对于用户自定义的数据类型opencv 提供了 cv:Ptr 进行管理其机制和刚刚的描述一致。
# 普通指针定义
T* ptr new T(....);# opencv 提供的管理方式
cv::Ptr prt(new T(...));
cv::Ptr ptr cv::makePtrT(...);Ptr封装了一个 T 实例的指针和该指针引用计数器更多的细节在 cv::Ptr 。
对输出数据自动分配内存
opencv可以为输出数据类型自动 分配 和 重分配 内存其 size 和 type 取决于输入数据的 size 和 type。同时可为输出数据指定额外的参数。
#include opencv2/imgproc.hpp
#include opencv2/highgui.hpp
using namespace cv;
int main(int, char**)
{VideoCapture cap(0);if(!cap.isOpened()) return -1;Mat frame, edges;namedWindow(edges, WINDOW_AUTOSIZE);for(;;){cap frame;cvtColor(frame, edges, COLOR_BGR2GRAY);GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);Canny(edges, edges, 0, 30, 3);imshow(edges, edges);if(waitKey(30) 0) break;}return 0;
}上面的代码通过输出重定向符 自动为 frame 实例分配内存因为视频的视频的帧分辨率和位深已通过 video capturing module处理并获知。 edges 的内存被函数 cvtColor 函数自动分配它和输入具有相同的 size 和 bit-depth。通道数经过 cv::COLOR_BGR2GRAY处理并设为1彩色图变为灰度图。frame 和 edges 在第一次执行时分配内存并具有相同的帧分辨率当分辨率改变时frame 和 edges 的内存会被自动的重新分配。
该技术的关键组件是 cv::Mat::create 方法。如果数组已经具有指定的大小和类型则该方法不执行任何操作。否则它释放先前分配的数据如果有这部分涉及递减引用计数器并将其与零进行比较释放掉无用的内存然后分配所需大小的新缓冲区。
某些例如的函数需要注意例如 cv::mixChannels, cv::RNG::fill等他们不能分配输出数据我们不得不手动执行。
饱和度算法
这一节主要想介绍OpenCV的存储方式以及可能产生的错误。因为opencv对像素的存储是以紧凑的、每通道 8 位或 16 位的形式进行编码值的范围非常有限对图像的某些处理如色彩空间转换、亮度/对比度调整、锐化、复杂插值双三次、Lanczos很可能产生超出可用范围的值这样就会产生图像伪影。为了解决这个问题需要使用饱和度算法。例如存储变量或计算结果r到一个8位图像时使用下列公式找到在0-255范围内最接近的值 f ( x , y ) m i n ( m a x ( r o u n d ( r ) , 0 ) , 255 ) f(x,y) min(max(round(r), 0), 255) f(x,y)min(max(round(r),0),255) 这个函数在opencv的库中已经做了实现
I.atuchar(y,x)saturate_castuchar(r);其中cv::uchar 代表8位无符号整形 右图出现了视觉伪影
OpenCV的模板使用受限
模板如果广泛使用会增加编译时间和代码大小单独使用模板也很难将接口和实现分开。对于opencv视觉库来说如果使用模板可能某个算法会跨越上千行代码。OpenCV实现了基于多态性和模板上的运行时调度以简化和其他语言的绑定开发。OpenCV在运行时调度太慢的地方像素访问运算符在某些不使用模板不能实现cv:Ptr、或不易于实现的地方cv::saturate_cast引入了模板类、方法、和函数。
opencv可以操作的数据类型有限。也就是说数组元素应该具有以下类型之一
8 位无符号整数 (uchar)8 位有符号整数 (schar)16 位无符号整数 (ushort)16 位有符号整数短32 位有符号整数 (int)32位浮点数float64 位浮点数双精度由多个元素组成的元组其中所有元素都具有相同的类型上述类型之一。其元素为此类元组的数组称为多通道数组与元素为标量值的单通道数组相反。最大可能的通道数由CV_CN_MAX常量定义当前设置为 512。
可以使用以下选项指定多通道n 通道类型
CV_8UC1 … CV_64FC4常量通道数1-4CV_8UC(n) … CV_64FC(n) or CV_MAKETYPE(CV_8U, n) … CV_MAKETYPE(CV_64F, n) 通道数大于4或未知时的语法
Note CV_32FC1 CV_32F, CV_32FC2 CV_32FC(2) CV_MAKETYPE(CV_32F, 2), 和CV_MAKETYPE(depth, n) ((depth7) ((n-1)3). 这意味着常量类型由深度取最低 3 位和通道数减 1取接下来的log2(CV_CN_MAX)位构成。
# 3x3的浮点数单通道矩阵
Mat mat(3,3,CV_32F)# 10x1的浮点数双通道矩阵
Mat cmatx(10,1,CV_64FC2)# 3通道图像
Mat img(Size(1920, 1080), CV_8UC3)#单通道图像和img的大小、通道数据类型相同
Mat grayscale(img.size(), CV_MAKETYPE(img.depth(), 1));输入输出数组
在某些情况下使用std::vector例如对于点集或cv::Matx对于 3x3 单应性矩阵等更方便。为了避免 API 中出现许多重复引入了特殊的“代理”类。基本“代理”类是cv::InputArray。它用于在函数输入上传递只读数组。派生自InputArray类cv::OutputArray用于指定函数的输出数组。通常您不应该关心那些中间类型并且您不应该显式声明这些类型的变量它都会自动工作。您可以假设您始终可以使用cv::Mat、std::vector、cv::Matx或来代替 InputArray cv::Vec/ OutputArray cv::Scalar。当函数具有可选的输入或输出数组而您没有或不需要时请传递cv::noArray()。
InputArray可以接受以下类型的输入数据
cv::Mat用于表示图像或矩阵数据。std::vector用于表示标准C STL容器的数据如std::vectorcv::Pointstd::vectorcv::Vec3f等。数组可以接受指向数据的指针和数据的大小。cv::InputArrayOfArrays用于表示多个InputArray的数组用于处理多通道数据或多个数据块。cv::cuda::GpuMat用于表示GPU上的图像或矩阵数据仅适用于使用OpenCV的CUDA模块。
void processImage(cv::InputArray input) {cv::Mat image input.getMat(); // 获取输入图像的Mat对象// 进行图像处理操作
}在调用processImage函数时可以传递图像、矩阵或其他支持的数据类型作为参数OpenCV会自动处理它们并将其转换为相应的cv::Mat对象方便你进行图像处理操作。使用InputArray可以使函数接受更加灵活的输入数据类型增加代码的可重用性和可扩展性。
错误处理
OpenCV 使用异常来表示严重错误。当输入数据具有正确的格式并且属于指定的值范围但由于某种原因算法无法成功例如优化算法没有收敛时它返回一个特殊的错误代码通常只是一个布尔变量。OpenCV 使用异常来表示严重错误。当输入数据具有正确的格式并且属于指定的值范围但由于某种原因算法无法成功例如优化算法没有收敛时它返回一个特殊的错误代码通常只是一个布尔变量。
通常使用CV_Error(errcode, description)宏或其类似 printf 的CV_Error_(errcode, (printf-spec, printf-args))变体或使用CV_Assert(condition)宏来抛出异常该宏检查条件并在不满足时抛出异常。对于性能关键型代码CV_DbgAssert(condition)仅保留在调试配置中。由于自动内存管理如果突然发生错误所有中间缓冲区都会自动释放。如果需要您只需要添加一条 try 语句来捕获异常
try
{... // call OpenCV
}
catch (const cv::Exception e)
{const char* err_msg e.what();std::cout exception caught: err_msg std::endl;
}