OpenCV学习笔记(二十六)——小试SVM算法ml OpenCV学习笔记(二十七)——基于级联分类器的目标检测objdect OpenCV学习笔记(二十八)——光流法对运动目标跟踪Video Ope
OpenCV学习笔记(二十六)——小试SVM算法ml
总感觉自己停留在码农的初级阶段,要想更上一层,就得静下心来,好好研究一下算法的东西。OpenCV作为一个计算机视觉的开源库,肯定不会只停留在数字图像处理的初级阶段,我也得加油,深入研究它的算法库。就从ml入手吧,最近做东西遇到随机森林,被搞的头大,深深感觉自己肚子里货太少,关键时刻调不出东西来。切勿浮躁,一点点研究吧。
这次就先介绍一下机器学习中的一个常用算法SVM算法,即支持向量机Support Vector Machine(SVM),是一种有监督学习方法,更多介绍请见维基百科http://zh.wikipedia.org/wiki/SVM。
OpenCV开发SVM算法是基于LibSVM软件包开发的,LibSVM是台湾大学林智仁(Lin Chih-Jen)等开发设计的一个简单、易于使用和快速有效的SVM模式识别与回归的软件包。用OpenCV使用SVM算法的大概流程是
1)设置训练样本集
需要两组数据,一组是数据的类别,一组是数据的向量信息。
2)设置SVM参数
利用CvSVMParams类实现类内的成员变量svm_type表示SVM类型:
CvSVM::C_SVC C-SVC
CvSVM::NU_SVC v-SVC
CvSVM::ONE_CLASS 一类SVM
CvSVM::EPS_SVR e-SVR
CvSVM::NU_SVR v-SVR
成员变量kernel_type表示核函数的类型:
CvSVM::LINEAR 线性:u‘v
CvSVM::POLY 多项式:(r*u'v + coef0)^degree
CvSVM::RBF RBF函数:exp(-r|u-v|^2)
CvSVM::SIGMOID sigmoid函数:tanh(r*u'v + coef0)
成员变量degree针对多项式核函数degree的设置,gamma针对多项式/rbf/sigmoid核函数的设置,coef0针对多项式/sigmoid核函数的设置,Cvalue为损失函数,在C-SVC、e-SVR、v-SVR中有效,nu设置v-SVC、一类SVM和v-SVR参数,p为设置e-SVR中损失函数的值,class_weightsC_SVC的权重,term_crit为SVM训练过程的终止条件。其中默认值degree = 0,gamma = 1,coef0 = 0,Cvalue = 1,nu = 0,p = 0,class_weights = 0
3)训练SVM
调用CvSVM::train函数建立SVM模型,第一个参数为训练数据,第二个参数为分类结果,最后一个参数即CvSVMParams
4)用这个SVM进行分类
调用函数CvSVM::predict实现分类
5)获得支持向量
除了分类,也可以得到SVM的支持向量,调用函数CvSVM::get_support_vector_count获得支持向量的个数,CvSVM::get_support_vector获得对应的索引编号的支持向量。
实现代码如下:
- // step 1:
- float labels[4] = {1.0, -1.0, -1.0, -1.0};
- Mat labelsMat(3, 1, CV_32FC1, labels);
- float trainingData[4][2] = { {501, 10}, {255, 10}, {501, 255}, {10, 501} };
- Mat trainingDataMat(3, 2, CV_32FC1, trainingData);
- // step 2:
- CvSVMParams params;
- params.svm_type = CvSVM::C_SVC;
- params.kernel_type = CvSVM::LINEAR;
- params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
- // step 3:
- CvSVM SVM;
- SVM.train(trainingDataMat, labelsMat, Mat(), Mat(), params);
- // step 4:
- Vec3b green(0, 255, 0), blue(255, 0, 0);
- for (int i=0; i<image.rows; i++)
- {
- for (int j=0; j<image.cols; j++)
- {
- Mat sampleMat = (Mat_<float>(1,2) << i,j);
- float response = SVM.predict(sampleMat);
- if (fabs(response-1.0) < 0.0001)
- {
- image.at<Vec3b>(j, i) = green;
- }
- else if (fabs(response+1.0) < 0.001)
- {
- image.at<Vec3b>(j, i) = blue;
- }
- }
- }
- // step 5:
- int c = SVM.get_support_vector_count();
- for (int i=0; i<c; i++)
- {
- const float* v = SVM.get_support_vector(i);
- }
OpenCV学习笔记(二十七)——基于级联分类器的目标检测objdect
OpenCV支持的目标检测的方法是利用样本的Haar特征进行的分类器训练,得到的级联boosted分类器(Cascade Classification)。注意,新版本的C++接口除了Haar特征以外也可以使用LBP特征。
先介绍一下相关的结构,级联分类器的计算特征值的基础类FeatureEvaluator,功能包括读操作read、复制clone、获得特征类型getFeatureType,分配图片分配窗口的操作setImage、setWindow,计算有序特征calcOrd,计算绝对特征calcCat,创建分类器特征的结构create函数。级联分类器类CascadeClassifier。目标级联矩形的分组函数groupRectangles。
接下来,我尝试使用CascadeClassifier这个级联分类器类检测视频流中的目标(haar支持的目标有人脸、人眼、嘴、鼻、身体。这里尝试比较成熟的人脸和眼镜)。用load函数加载XML分类器文件(目前提供的分类器包括Haar分类器和LBP分类器(LBP分类器数据较少))具体步骤如下:
这里再补充一点:后来我又进行了一些实验,对正面人脸分类器进行了实验,总共有4个,alt、alt2、alt_tree、default。对比下来发现alt和alt2的效果比较好,alt_tree耗时较长,default是一个轻量级的,经常出现误检测。所以还是推荐大家使用haarcascade_frontalface_atl.xml和haarcascade_frontalface_atl2.xml。
1)加载级联分类器
调用CascadeClassifier类成员函数load实现,代码为:
- CascadeClassifier face_cascade;
- face_cascade.load("haarcascade_frontalface_alt.xml");
2)读取视频流
这部分比较基础啦~~从文件中读取图像序列,读取视频文件,读取摄像头视频流看过我之前的文章,这3种方法应该了然于心。
3)对每一帧使用该分类器
这里先将图像变成灰度图,对它应用直方图均衡化,做一些预处理的工作。接下来检测人脸,调用detectMultiScale函数,该函数在输入图像的不同尺度中检测物体,参数image为输入的灰度图像,objects为得到被检测物体的矩形框向量组,scaleFactor为每一个图像尺度中的尺度参数,默认值为1.1,minNeighbors参数为每一个级联矩形应该保留的邻近个数(没能理解这个参数,-_-|||),默认为3,flags对于新的分类器没有用(但目前的haar分类器都是旧版的,CV_HAAR_DO_CANNY_PRUNING利用Canny边缘检测器来排除一些边缘很少或者很多的图像区域,CV_HAAR_SCALE_IMAGE就是按比例正常检测,CV_HAAR_FIND_BIGGEST_OBJECT只检测最大的物体,CV_HAAR_DO_ROUGH_SEARCH只做初略检测),默认为0.minSize和maxSize用来限制得到的目标区域的范围。这里调用的代码如下:
- face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
4)显示目标
这个也比较简单,调用ellips函数将刚才得到的faces矩形框都显示出来
更进一步,也可以在得到的每一幅人脸中得到人眼的位置,调用的分类器文件为haarcascade_eye_tree_eyeglasses.xml,先将脸部区域选为兴趣区域ROI,重复上诉步骤即可,这里就不详细介绍了。当然,感兴趣的朋友也可以试试其他的xml文件作为分类器玩一下啊,感觉LBP特征虽然xml文件的大小很小,但效果还可以,不过我没有做过多的测试。光说不练假把式,最后贴上效果图和源代码的下载地址
代码下载地址:http://download.csdn.net/detail/yang_xian521/3800468
OpenCV学习笔记(二十八)——光流法对运动目标跟踪Video
OpenCV配套的教程Tutorials对于Video的部分,没有实例进行说明,我只能摸石头过河啦,之前试过一个camShift做目标检测,这次试一试光流法做运动估计。这里使用的光流法是比较常用的 Lucas-Kanade方法。对于光流法的原理,我就不过多介绍了,主要讲使用OpenCV如何实现。
首先利用goodFeaturesToTrack函数得到图像中的强边界作为跟踪的特征点,接下来要调用calcOpticalFlowPyrLK函数,输入两幅连续的图像,并在第一幅图像里选择一组特征点,输出为这组点在下一幅图像中的位置。再把得到的跟踪结果过滤一下,去掉不好的特征点。再把特征点的跟踪路径标示出来。说着好简单哦~~
程序的效果和代码下载http://download.csdn.net/detail/yang_xian521/3811478
OpenCV学习笔记(二十九)——视频前景的提取Video
视频捕捉的对象中,背景通常保持不变。一般分析中关注移动的前景物体,威力提取出前景物体,需要建立背景的模型,将模型和当前帧进行比对检测前景物体。前景提取应用非常广泛,特别是在智能监控领域中。
如果有不含前景物体的背景图片,提取前景的工作相对容易,只需要比对当前帧和背景图片的不同,调用函数absdiff实现。但是大多数情况,获得背景图片是不可能的,比如在复杂的场景下,或者有光线条件的变化。因此,就需要动态的变换背景。一种简单的办法是对所观察到的图片取平均,但这样做也有很多弊端,首先,这种办法在计算背景图片的前需要输入大量的图片,其次我们进行取平均的过程中不能有前景物体进入。所以一种相对好的办法是动态建立背景图片并实时更新。
具体的实现过程主要分为两部分:一部分是调用absdiff函数找出当前图片和背景图片的区别,这之中使用了threshold函数去除为前景,当前图片像素与背景图片像素变化超过一定阈值的时候才认定其为前景;另一个工作是更新背景图片,调用函数accumulateWeighted,根据权重参数可以调整背景更新的速度,将当前图片更新到背景中,这里巧妙利用得到的前景提取结果作为mask,在更新背景图片的过程中避免了前景的干扰。
程序效果如图,代码下载地址为http://download.csdn.net/detail/yang_xian521/3814878
虽然可以调整阈值参数和权重更新速度调节前景提取的结果,但从测试视频可以发现,树叶的运动对结果的干扰还是不小的,特别对于第一帧出现前景的情况,由于后续更新背景都是对前景mask后对背景进行更新的,所以第一帧的前景部分对背景的影响因子很难被更新掉。这里提出一种改进的办法——混合高斯模型。可以使一个像素具有更多的信息,这样可以有效的减少类似树叶的不停飘动,水波的不停荡漾这种对前景的干扰。这个精密的算法比之前我所介绍的简单方法要复杂很多,不易实现。还好,OpenCV已经为我们做好了相关工作,将其封装在类BackgroundSubtractorMOG,使用起来非常方便。实现代码如下:
- Mat frame;
- Mat foreground; // 前景图片
- namedWindow("Extracted Foreground");
- // 混合高斯物体
- BackgroundSubtractorMOG mog;
- bool stop(false);
- while (!stop)
- {
- if (!capture.read(frame))
- {
- break;
- }
- // 更新背景图片并且输出前景
- mog(frame, foreground, 0.01);
- // 输出的前景图片并不是2值图片,要处理一下显示
- threshold(foreground, foreground, 128, 255, THRESH_BINARY_INV);
新程序的效果图如下,下载地址为 http://download.csdn.net/detail/yang_xian521/3815366
OpenCV学习笔记(三十)——解开VideoInput面纱highgui
最近做一个东西,摄像头使用的高清摄像头,采集出来的视频是D1格式(720*480)。使用VideoCapture发现速度很忙,网上的朋友说VideoCapture提供的读写功能采用VFW,效率低下且有些格式支持不好。而 OpenCV 2.0 内置了videoInput Library,可以自动在VFW和DirectShow间切换。videoInput是老外写的功能强大的开源视频处理库。是一个第三方库,2.0~2.2的版本专门有一个3rdparty对该库进行支持,而在最新的2.3版本中,已经讲videoInput库集成到highgui中了,想使用它的话,只需要在cmake中设置宏WITH_VIDEOiNPUT=OFF/ON即可。好像我使用的2.3.1自带的那个build文件夹下面的库就是在ON条件下编译得到的,所以就不用cmake重新编译了。2.3中使用手册和教程对VideoInput类只字未提,我只好自己摸索了。还好有源代码可以看,开源伟大。
网上见过其他朋友写过2.2实现VideoInput的使用,我实验发现2.3中的使用方法基本没有变化。后面再把配套例程奉上,先把VideoInput类内的公有成员函数一一介绍一下,该类还有个相关的类是VideoDevice。包括控制是否在控制台输出信息开关setVerbose函数,打印出可用视频设备信息的函数listDevices,之后可以得到设备名函数getDeviceName,视频捕捉的回调函数设置函数setUseCallback,调整捕捉帧率的函数setIdealFramerate(默认30fps,可修改,但不能被保证准确,directshow会尝试一个邻近的帧率),防止设备休眠重新连接的函数setAutoReconnectOnFreeze,开启设备函数setupDevice,在setpuDevice之前可以设置视频制式,调用函数为setFormat,检测是否有新的帧函数isFrameNew,检测视频是否开启isDeviceSetup,获得数据的函数getPixels(注意这里获得的数据时uchar型的指针),显示视频设置窗口函数showSettingsWindow,控制视频设置的相关函数有setVideoSettingFilter、setVideoSettingFilterPct、getVideoSettingFilter、setVideoSettingCamera、setVideoSettingCameraPct、getVideoSettingCamera,获得视频宽高信息的函数有getWidth、getHeight、getSize,停止设备函数stopDevice,重启设备函数restartDevice。
讲了这么多函数,还是直接上代码说话吧,我这是找的VideoInput注释中的一个例程。
- //create a videoInput object
- videoInput VI;
- //Prints out a list of available devices and returns num of devices found
- int numDevices = VI.listDevices();
- int device1 = 0; //this could be any deviceID that shows up in listDevices
- int device2 = 1; //this could be any deviceID that shows up in listDevices
- //if you want to capture at a different frame rate (default is 30)
- //specify it here, you are not guaranteed to get this fps though.
- //VI.setIdealFramerate(dev, 60);
- //setup the first device - there are a number of options:
- VI.setupDevice(device1); //setup the first device with the default settings
- //VI.setupDevice(device1, VI_COMPOSITE); //or setup device with specific connection type
- //VI.setupDevice(device1, 320, 240); //or setup device with specified video size
- //VI.setupDevice(device1, 320, 240, VI_COMPOSITE); //or setup device with video size and connection type
- //VI.setFormat(device1, VI_NTSC_M); //if your card doesn't remember what format it should be
- //call this with the appropriate format listed above
- //NOTE: must be called after setupDevice!
- //optionally setup a second (or third, fourth ...) device - same options as above
- VI.setupDevice(device2);
- //As requested width and height can not always be accomodated
- //make sure to check the size once the device is setup
- int width = VI.getWidth(device1);
- int height = VI.getHeight(device1);
- int size = VI.getSize(device1);
- unsigned char * yourBuffer1 = new unsigned char[size];
- unsigned char * yourBuffer2 = new unsigned char[size];
- //to get the data from the device first check if the data is new
- if(VI.isFrameNew(device1)){
- VI.getPixels(device1, yourBuffer1, false, false); //fills pixels as a BGR (for openCV) unsigned char array - no flipping
- VI.getPixels(device1, yourBuffer2, true, true); //fills pixels as a RGB (for openGL) unsigned char array - flipping!
- }
- //same applies to device2 etc
- //to get a settings dialog for the device
- VI.showSettingsWindow(device1);
- //Shut down devices properly
- VI.stopDevice(device1);
- VI.stopDevice(device2);
from: http://blog.csdn.net/yang_xian521/article/category/910716
OpenCV学习笔记(二十六)——小试SVM算法ml OpenCV学习笔记(二十七)——基于级联分类器的目标检测objdect OpenCV学习笔记(二十八)——光流法对运动目标跟踪Video Ope相关推荐
- 计算机视觉与深度学习 | 基于Faster R-CNN的目标检测(深度学习Matlab代码)
===================================================== github:https://github.com/MichaelBeechan CSDN: ...
- 熬了几个大夜,学完一套985博士总结的「卷积神经网络、目标检测、OpenCV」学习笔记(20G高清/PPT/代码)...
AI 显然是最近几年非常火的一个新技术方向,从几年前大家认识到 AI 的能力,到现在产业里已经在普遍的探讨 AI 如何落地了. 我们可以预言未来在很多的领域,很多的行业,AI 都会在里边起到重要的作用 ...
- C#,人工智能,深度学习,目标检测,OpenCV级联分类器数据集的制作与《层级分类器一键生成器》源代码
一.目标识别技术概述 1.摘要 目标检测是计算机视觉中最基本和最具挑战性的问题之一,它试图从自然图像中的大量预定义类别中定位目标实例.深度学习技术已成为直接从数据中学习特征表示的强大策略,并在通用目标 ...
- 2021-01-24过去十年十大AI研究热点,分别为深度神经网络、特征抽取、图像分类、目标检测、语义分割、表示学习、生成对抗网络、语义网络、协同过滤和机器翻译。
专利申请量全球第一!清华人工智能发展报告:国内215所高校成立相关本科专业 发布时间:01-2415:20万象大会年度获奖创作者,东方财富网官方帐号 1月20日,清华大学人工智能研究院.清华-中国工程 ...
- OpenCV中基于Haar特征和级联分类器的人脸检测
使用机器学习的方法进行人脸检测的第一步需要训练人脸分类器,这是一个耗时耗力的过程,需要收集大量的正负样本,并且样本质量的好坏对结果影响巨大,如果样本没有处理好,再优秀的机器学习分类算法都是零. 今年3 ...
- OpenCV中基于Haar特征和级联分类器的人脸检测(三)
使用机器学习的方法进行人脸检测的第一步需要训练人脸分类器,这是一个耗时耗力的过程,需要收集大量的正负样本,并且样本质量的好坏对结果影响巨大,如果样本没有处理好,再优秀的机器学习分类算法都是零. 今年3 ...
- 目标检测之Yolo学习之路-Yolov1,Yolov2,Yolov3
目标检测之Yolo学习之路-Yolov1,Yolov2,Yolov3 前言: 计算机视觉在我们一般业务场景中主要分为图像分类,目标检测,语义分割,实例分割.众所周知图像分类仅仅是将图像分出类别,常用于 ...
- 传统的机器学习目标检测和深度学习的目标检测
概述: 目标分类:给一张图片,分类 目标检测:给一张图片,找到目标,并用矩形框画出 分类是对一幅图整体,检测是更进一步,找出一幅图中一部分.一般检测以分类为基础, 如用滑动窗口搜索,然后用分类器分类是 ...
- Multi-Modal 3D Object Detection in Autonomous Driving: a Survey(自动驾驶中的多模态3D目标检测综述)论文笔记
原文链接:https://arxiv.org/pdf/2106.12735.pdf 1.引言 1.1 单一传感器3D目标检测 基于图像的3D目标检测.低费用换来满意的性能.但存在遮挡. ...
最新文章
- redis设置主从复制-slave Replication--解决报错:(error) READONLY You can't write against a read only slave.
- mvc3 之三 符号列表
- windows7基本操作学习笔记
- java通过jdbc登陆系统_JDBC模拟登录
- python 获取本机IP的三种方式
- lunbuntu install mysql5.7
- Spring Boot之程序性能监控
- FIREDAC连接SQLITE乱码的解决
- 编程语言那么多,学哪个能拿高薪?
- 华三 h3c MVRP(GVRP)配置
- Repeater思路整理
- 星益80个在线小游戏HTML网页源码
- 解决爱思维尔期刊提供的Latex模板摘要部分改变字体颜色问题File ended while scanning use of \verbatim@start.
- 专业修图工具:Affinity Photo for mac
- iOS 10 相关问题
- 《Unity5.x从入门到精通》读书笔记(二)
- 16路4k相机拍照的jpeg照片共有多大
- [VOT12](2017CVPR) CSR-DCF: Discriminative Correlation Filter Tracker with Channel and Spatial
- JVM垃圾回收面试题
- halcon中阈值分割算子用法
热门文章
- MapReduce示例——WordCount(统计单词)
- 通过零知识证明,成为重要的区块链革新者
- Uber创始人:一个优秀创业者应具八种特质
- 实战并发编程 - 02解决并发问题常用套路
- android getview方法,android 获取view的getLeft(), getRight(), getTop(),... - 简书
- EFI启动PE加Linux,macOS安装盘制作并添加EFI和WinPE
- 公式编辑语言:LaTeX/Advanced Mathematics
- 小森生活一直服务器维护,《小森生活》怎么处理断线黑屏的问题 连接不上服务器解决办法...
- 2012计算机科学排名,2012年美国大学计算机科学专业研究生排名
- springboot 获取application参数_LOOK ! SpringBoot的外部化配置最全解析