尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

003、OpenCV概览:历史、核心模块与版本差异

003、OpenCV概览:历史、核心模块与版本差异 003、OpenCV概览历史、核心模块与版本差异上个项目升级OpenCV代码编译不过。报错是SIFT未声明我以为没加头文件加了一堆opencv2/nonfree/nonfree.hpp还是不行。查了一晚上才发现OpenCV 4把SIFT挪进了opencv_contrib仓库还要自己重新编译。这种坑估计不少朋友都踩过。今天不聊具体算法先把OpenCV的家底捋一遍重点说清楚版本差异省得你将来被类似问题折腾到半夜。先看历史吧。OpenCV脱胎于Intel一个内部项目目标是搞一个高效的计算机视觉库1999年启动2000年左右作为开源项目放出来。早期就是Intel的工程师在维护所以很多人叫它Intel OpenCV。到了2009年左右Willow Garage这家机器人公司接手主导干了一件大事——发布2.x系列把1.x的C风格接口推倒重来引入C接口用cv::Mat替代了那个又笨又容易内存泄漏的IplImage。可以说2.0是真正的分水岭。之后OpenCV基金会成立版本继续往下走。3.x又搞模块化把一些不常用的功能拆成opencv_contrib需要自己编译集成。4.x则强化了性能砍掉了一堆老掉牙的API还把深度学习推理模块dnn扶正。现在稳定版已经4.8、4.9了但很多老项目还在用2.4或者3.4.3版本割裂得厉害。OpenCV的核心模块说白了就是几个关键部分。core模块是地基所有基本数据结构都在里面比如Mat、Rect、Point还有各种数学运算。没有core其他模块都转不起来。imgproc是图像处理的主战场滤波、边缘检测、形态学、几何变换、直方图全都在这里。这俩模块是任何时候都离不开的。然后是highgui干的是显示窗口、保存图片、处理鼠标键盘事件这类“杂活”。video模块处理光流、背景差分、均值漂移这些视频相关算法。calib3d做相机标定、立体视觉、位姿估计搞3D重建或者AR必须打交道的。features2d负责特征点检测和特征描述SIFT、SURF的“老家”以前在这里后来被挪走了但ORB、BRISK这些还留在里面。objdetect是传统目标检测的家比如Haar级联人脸检测、HOG行人检测。ml模块提供各种经典机器学习算法朴素贝叶斯、SVM、随机森林都有不过现在用的人少了大家都去搞深度学习。dnn模块是后起之秀从OpenCV 3.3之后开始逐步完善能直接读Caffe、TensorFlow、ONNX的模型做推理。注意dnn不需要额外编译contrib是官方内置的。版本差异这块是重头戏。1.x时代C语言风格满天飞IplImage*指针满天飞内存要自己手动释放。比如cvLoadImage加载图片用完必须cvReleaseImage不然就泄漏。那时候写代码每分配一个对象就得惦记释放特别累。2.x改成cv::Mat之后引用计数自动管理舒服太多了。所以如果你手里还有1.x的老师代码别傻乎乎去兼容直接改成Mat重写吧。常量名的变化也是个大地雷。2.x时代有个CV_BGR2GRAY用来做颜色空间转换。到了4.x这个常量变成了cv::COLOR_BGR2GRAY。你要是按老代码直接写cvCvtColor(img, gray, CV_BGR2GRAY)编译直接报“标识符未定义”。图像加载的flag也一样2.x的CV_LOAD_IMAGE_COLOR在4.x里用cv::IMREAD_COLOR。还有画矩形的CV_DRAW_RICH这类常量也被改了。这种刻意为之的破坏性变更就是为了逼你更新代码。函数名和头文件的变动更坑。以SIFT为例2.x里cv::SIFT就在opencv2/features2d/features2d.hpp里一包到底。到了3.xSIFT被挪到了opencv2/xfeatures2d/nonfree.hpp而且需要编译opencv_contrib才能用。到了4.x你连头文件都搜不到了因为xfeatures2d模块默认不包含。很多老项目从2.x升级到4.x卡在SIFT上的人一大片。当时在代码里挖了个注释“这里踩过坑别指望cv::SIFT还能用了要么改用ORB要么自己去编译contrib。”话说回来如果你只是为了跑通某个demo可以先用ORB顶一顶速度和效果也还行。Python接口的差异也不小。最典型的是cv2.findContours的返回值。OpenCV 3.x里它返回三个值image, contours, hierarchy其中image是会变动的实际上就是输入图像的一个修改版。但OpenCV 4.x里返回值改成了两个只返回contours, hierarchy。很多教程还是老写法_, contours, hierarchy cv2.findContours(...)。你在OpenCV 4上运行直接给你报not enough values to unpack。我见过不少新手折腾半天还以为是图像格式问题。其实很简单按住版本判断一下就行。处理兼容性的建议是写个分支判断opencv_version或者干脆统一用新写法毕竟现在谁还在用3.x的老古董说到版本兼容我习惯在项目里加个宏比如#if CV_VERSION_MAJOR 4然后选择调用新版还是旧版API。别怕麻烦C预处理比运行时判断好用多了。还有一个细节Debug和Release的OpenCV库文件必须分开混用绝对出错。有些人直接用系统包管理器装一个库结果自己编译时链接到错的那份程序跑起来疯狂崩溃查半天查不出原因。建议直接下载官方预编译包或者自己从源码编译路径写清楚别靠环境变量瞎指。DNN模块是4.x最值得期待的部分。你只要把训练好的模型导出成ONNX格式OpenCV就能直接加载不需要额外装TensorFlow和PyTorch。做推理时输入图像要先改成cv::Mat再转成blob最后塞进网络。这里面坑也不少比如输入尺寸、通道顺序、归一化系数稍有不慎结果就是歪的。我一般在代码里写注释“先看模型的输入要求别把BGR当成RGB这里栽过跟头。”如果有GPU可以试试切换到CUDA后端速度能提升不少但模型格式和层支持都有限制别抱太高期望。末尾提一句个人经验。别整天追新版本关键看项目需求。OpenCV 4.x对于普通图像处理任务已经非常稳定了没必要再守着2.x的旧代码。如果你刚接触OpenCV直接学4.x老博客里的代码只能当参考遇到编译报错不要硬抠先去查官方迁移文档。开个终端打印一下cv::getVersionString()心里就有数了。最后写代码时多留点注释别等到半年之后再回来调试自己都不认得自己写的“// 这里为什么用IMREAD_GRAYSCALE”到底是想干什么。
返回列表