版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/heroacool/article/details/50997024
<div class="markdown_views">
<p>物体识别中经常遇到多分类器问题,svm是比较成熟和直接的想法。一般来说使用svm作为多分类器主要有以下思路:</p>
一对多(one-vs-all)。训练时依次将目标类别作为正样本,其余样本作为负样本,以此训练n个svm。这个在Andrew Ng的Machine leaning的课上介绍过。
缺点:因为训练集是1:N的情况,存在较大的bias,不是特别实用。
一对一(one-vs-one)。训练时,任意两类样本之间训练一个svm,则n类别,训练出(n-1)n/2个svm。在runtime时,对一个未知样本分类,则使用投票的法方法。libsvm即使用的该种方法。
缺点:类别多的时候,(n-1)n/2个支持向量机,计算代价大。
层次支持向量机。首先将所有类别分类为两个子类,再将子类进一步划分为两个子类,直到单独子类为止。好像一棵树耶。具体请参考:刘志刚, 李德仁, 秦前清, 等. 支持向量机在多类分类问题中的推广[J]. 2004.
DAG-SVMS。由Platt提出的决策导向的循环图DDAG导出的,是针对“一对一”SVMS存在误分、拒分现象提出的。请参考论文
简单示例
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp> #include
"opencv2/imgcodecs.hpp" #include <opencv2/highgui.hpp> #include <opencv2/ml.hpp> using
namespace cv; using
namespace cv::ml; Vec3b getRandomColor(){ RNG rng(clock());
return Vec3b(rng.next() %
255, rng.next() %
255, rng.next() %
255); }
int main(
int, char
**) {
int width =
512, height =
512; Mat
image = Mat::zeros(height, width, CV_8UC3);
int labels[
4] = {
1,
2,
3,
4};
float trainingData[
4][
2] = { {
100,
10}, {
10,
500}, {
500,
10}, {
500,
500} }; Mat trainingDataMat(
4,
2, CV_32FC1, trainingData); Mat labelsMat(
4,
1, CV_32SC1, labels);
Ptr<SVM> svm = SVM::create(); svm->setType(SVM::C_SVC); svm->setKernel(SVM::POLY); svm->setDegree(
1.0); svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER,
100,
1e-6));
svm->train(trainingDataMat, ROW_SAMPLE, labelsMat);
Vec3b green(
0,
255,
0), blue (
255,
0,
0), red(
0,
0,
255),yellow(
0,
255,
255);
for (
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 = svm->predict(sampleMat); double ratio =
0.5;
if (response ==
1)
image.at<Vec3b>(i,j) = green
*ratio;
else
if (response ==
2)
image.at<Vec3b>(i,j) = blue
*ratio;
else
if(response ==
3){
image.at<Vec3b>(i,j) = red
*ratio; }
else
if(response ==
4){
image.at<Vec3b>(i,j) = yellow
*ratio; } } }
int thickness = -
1;
int lineType =
8;
circle(
image, Point(
100,
10),
5, Scalar(
0,
255,
0), thickness, lineType );
circle(
image, Point(
10,
500),
5, Scalar(
255,
0,
0), thickness, lineType );
circle(
image, Point(
500,
10),
5, Scalar(
0,
0,
255), thickness, lineType );
circle(
image, Point(
500,
500),
5, Scalar(
0,
255,
255), thickness, lineType ); thickness =
2; lineType =
8; Mat sv = svm->getSupportVectors(); std::cout << sv << std::endl;
for (
int i =
0; i < sv.rows; ++i){ const
float* v = sv.ptr<
float>(i);
circle(
image, Point( (
int) v[
0], (
int) v[
1]),
6, CV_RGB(
128,
128,
128),
2); } imwrite(
"result.png",
image);
imshow(
"SVM Simple Example",
image);
waitKey(
0); }
- 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
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
效果:
注意点:
使用RBF核或者使用autotrain,参数选择十分重要。不行你试试哟!!!