OpenCV3.0或OpenCV3.1的SVM操作
来源:互联网 发布:现在开淘宝店晚吗 编辑:程序博客网 时间:2024/06/04 19:07
OpenCV2.0 SVM代码及其分析
OpenCV 在很久以前就集成了SVM的功能,现在OpenCV升级到了3.0和3.1了,很多人都不习惯了怎么调用OpenCV中的SVM功能了。在之前OpenCV的SVM调用一直有个案例:首先,给定几组训练数据,并且给了label所对应的值。然后经过训练之后,对图像的各个位置进行预测是1还是-1。如果是1的话,用绿色来表示,如果是-1呢,用蓝色表示。并且还画出几个支持向量。
下面给了OpenCV2.0 的SVM代码(勿喷,直接从OpenCV官方网址复制下来的)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
OpenCV 3.0、OpenCV3.1 的SVM训练代码
下面给出了正确的,记住是正确的代码:
例子1:
#include "stdafx.h"#include "opencv2/opencv.hpp"using namespace cv;using namespace cv::ml;int main(int, char**){int width = 512, height = 512;Mat image = Mat::zeros(height, width, CV_8UC3); //创建窗口可视化 // 设置训练数据int labels[10] = { 1, -1, 1, 1,-1,1,-1,1,-1,-1 };Mat labelsMat(10, 1, CV_32SC1, labels);float trainingData[10][2] = { { 501, 150 },{ 255, 10 },{ 501, 255 },{ 10, 501 },{ 25, 80 },{ 150, 300 },{ 77, 200 } ,{ 300, 300 } ,{ 45, 250 } ,{ 200, 200 } };Mat trainingDataMat(10, 2, CV_32FC1, trainingData);// 创建分类器并设置参数Ptr<SVM> model = SVM::create();model->setType(SVM::C_SVC);model->setKernel(SVM::LINEAR); //核函数//设置训练数据 Ptr<TrainData> tData = TrainData::create(trainingDataMat, ROW_SAMPLE, labelsMat);// 训练分类器model->train(tData);Vec3b green(0, 255, 0), blue(255, 0, 0);// Show the decision regions given by the SVMfor (int i = 0; i < image.rows; ++i)for (int j = 0; j < image.cols; ++j){Mat sampleMat = (Mat_<float>(1, 2) << j, i); //生成测试数据float response = model->predict(sampleMat); //进行预测,返回1或-1if (response == 1)image.at<Vec3b>(i, j) = green;else if (response == -1)image.at<Vec3b>(i, j) = blue;}// 显示训练数据int thickness = -1;int lineType = 8;Scalar c1 = Scalar::all(0); //标记为1的显示成黑点Scalar c2 = Scalar::all(255); //标记成-1的显示成白点 //绘图时,先宽后高,对应先列后行for (int i = 0; i < labelsMat.rows; i++){const float* v = trainingDataMat.ptr<float>(i); //取出每行的头指针Point pt = Point((int)v[0], (int)v[1]);if (labels[i] == 1)circle(image, pt, 5, c1, thickness, lineType);elsecircle(image, pt, 5, c2, thickness, lineType);}imshow("SVM Simple Example", image);waitKey(0);}
例子2:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
运行的效果如下:
为了保证代码可读性,代码没有用using namespace cv
或using namespace cv::ml;
之类的代码,全部都写完整的名称,命名空间+类名。比如设置SVM的核类型为线性,写成svm->setKernel(cv::ml::SVM::KernelTypes::LINEAR);
。当然,这个只是一处地方,其他的请自己阅读。
代码的注意事项
虽然,大家的目标很明确:导入训练数据+label –> Mat, 训练,预测,显示这些目标。但是仍然避免不了代码错误。下面就是我遇到的代码的问题。
标签以及变成Mat的数据类型
其实,在本代码中出现了一种情况就是数据类型,下面均以标签为例:
这个是OpenCV3.0、OpenCV3.1正确的代码:
- 1
- 2
下面是OpenCV 2.X 正确代码
- 1
- 2
如果将OpenCV 2.X的代码换到OpenCV 3.1、OpenCV3.0代码会有什么样子的结果呢?
这个很熟悉吧所以,如果傻乎乎的换,这个是行不通的。
下面对于label
和labelMat
按照不同的情况进行分析。
首先,这个labelMat
和trainingMat
到底能取哪几种类型?
下面,请看OpenCV3.1 源码中的一个部分:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
为了方便起见,将这个函数的代码的其他部分删除了。首先解释一下:samples
就是训练的数据。response
就是标签。通过上面,我们知道再来用Mat的时候,只能用CV_32F
和CV_32S
。所以说,如果这些矩阵不能写什么CV_8UC1
之类的了,这个是错误的。
假设我们写其他的情况,比如
label为int,labelsMat为CV_32SC1
这个是正确的。
label为float,labelsMat为CV_32FC1
这个会出现错误,这个我还没有分析出来是什么原因。错误的截图如下:。
下面的错误均表示为截图所示的错误。
label为int,labelsMat为CV_32FC1
同样的,这个是错误。当我们用Imagewatch插件去观察labelsMat的值的时候发现这个labelsMat的值为。好吧,这个很明显了。
label为float,labelsMat为CV_32SC1
这个是可以运行的,但是结果肯定是错误的。同样的,值不对。
- OpenCV3.0或OpenCV3.1的SVM操作
- OpenCV3.0或OpenCV3.1的SVM操作
- OpenCV3.0或OpenCV3.1的SVM操作
- OpenCV3.0或OpenCV3.1的SVM操作
- OCR svm opencv3.1
- OpenCV3.0 中SVM的使用方法
- opencv3.1中svm的使用范例
- opencv3 SVM
- opencv3.3 svm的使用
- OpenCv3.0+SVM的使用心得(一)
- OpenCv3.0+SVM的使用心得(二)
- OpenCv3.0+SVM的使用心得(一)
- OpenCv3.0+SVM的使用心得(二)
- 模式识别之(一)SVM的opencv3.0实现
- 基于SVM的分类识别 opencv3.1.0
- Cascade Latent-SVM -base opencv3.0 beta
- OpenCV3.0 HOG+SVM行人检测器
- OpenCV3.0 HOG+SVM行人检测器
- PCA(主成分分析) 降维算法详解 和代码
- websocket头解析
- LeetCode 48. Rotate Image (Medium)
- spring aop获取目标对象的方法对象(包括方法上的注解)
- 12月份的新业务、新系统架构
- OpenCV3.0或OpenCV3.1的SVM操作
- conda 安装指定版本的指定包
- Linux企业运维人员最常用150个命令汇总
- echarts x轴文字显示不全(xAxis文字倾斜比较全面的3种做法值得推荐)
- spark 统计线上日志ip分组统计
- ENVI教程:InSAR技术选择GCP,用于轨道精炼
- 深入浅出Swarm
- js定时器倒计时
- 详解sys_read和sys_write