在opencv3中利用SVM进行图像目标检测和分类

采用鼠标事件,手动选择样本点,包括目标样本和背景样本。组成训练数据进行训练

1、主函数

#include "stdafx.h"
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace cv::ml;

Mat img,image;
Mat targetData, backData;
bool flag = true;
string wdname = "image";

void on_mouse(int event, int x, int y, int flags, void* ustc); //鼠标取样本点
void getTrainData(Mat &train_data, Mat &train_label);  //生成训练数据
void svm(); //svm分类

int main(int argc, char** argv)
{
    string path = "d:/peppers.png";
    img = imread(path);
    img.copyTo(image);
    if (img.empty())
    {
        cout << "Image load error";
        return 0;
    }
    namedWindow(wdname);
    setMouseCallback(wdname, on_mouse, 0);

    for (;;)
    {
        imshow("image", img);

        int c = waitKey(0);
        if ((c & 255) == 27)
        {
            cout << "Exiting ...\n";
            break;
        }
        if ((char)c == ‘c‘)
        {
            flag = false;
        }
        if ((char)c == ‘q‘)
        {
            destroyAllWindows();
            break;
        }
    }
    svm();
    return 0;
}

首先输入图像,调用setMouseCallback函数进行鼠标取点

2、鼠标事件

//鼠标在图像上取样本点,按q键退出
void on_mouse(int event, int x, int y, int flags, void* ustc)
{
    if (event == CV_EVENT_LBUTTONDOWN)
    {
        Point pt = Point(x, y);
        Vec3b point = img.at<Vec3b>(y, x);  //取出该坐标处的像素值,注意x,y的顺序
        Mat tmp = (Mat_<float>(1, 3) << point[0], point[1], point[2]);
        if (flag)
        {
            targetData.push_back(tmp); //加入正样本矩阵
            circle(img, pt, 2, Scalar(0, 255, 255), -1, 8); //画圆,在图上显示点击的点 

        }

        else
        {
            backData.push_back(tmp); //加入负样本矩阵
            circle(img, pt, 2, Scalar(255, 0, 0), -1, 8); 

        }
        imshow(wdname, img);
    }
}

用鼠标在图像上点击,取出当前点的红绿蓝像素值进行训练。先选择任意个目标样本,然后按"c“键后选择任意个背景样本。样本数可以自己随意决定。样本选择完后,按”q"键完成样本选择。

3、svm分类

void getTrainData(Mat &train_data, Mat &train_label)
{
    int m = targetData.rows;
    int n = backData.rows;
    cout << "正样本数::" << m << endl;
    cout << "负样本数:" << n << endl;
    vconcat(targetData, backData, train_data); //合并所有的样本点,作为训练数据
    train_label = Mat(m + n, 1, CV_32S, Scalar::all(1)); //初始化标注
    for (int i = m; i < m + n; i++)
        train_label.at<int>(i, 0) = -1;
}

void svm()
{
    Mat train_data, train_label;
    getTrainData(train_data, train_label); //获取鼠标选择的样本训练数据

    // 设置参数
    Ptr<SVM> svm = SVM::create();
    svm->setType(SVM::C_SVC);
    svm->setKernel(SVM::LINEAR);

    // 训练分类器
    Ptr<TrainData> tData = TrainData::create(train_data, ROW_SAMPLE, train_label);
    svm->train(tData);

    Vec3b color(0, 0, 0);
    // Show the decision regions given by the SVM
    for (int i = 0; i < image.rows; ++i)
    for (int j = 0; j < image.cols; ++j)
    {
        Vec3b point = img.at<Vec3b>(i, j);  //取出该坐标处的像素值
        Mat sampleMat = (Mat_<float>(1, 3) << point[0], point[1], point[2]);
        float response = svm->predict(sampleMat);  //进行预测,返回1或-1,返回类型为float
        if ((int)response != 1)
            image.at<Vec3b>(i, j) = color;  //将背景点设为黑色
    }

    imshow("SVM Simple Example", image); // show it to the user
    waitKey(0);
}

将正负样本矩阵,用vconcat合并成一个矩阵,用作训练分类器,并对相应的样本进行标注。最后将识别出的目标保留,将背景部分调成黑色。

4、完整程序

// svm.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace cv::ml;

Mat img,image;
Mat targetData, backData;
bool flag = true;
string wdname = "image";

void on_mouse(int event, int x, int y, int flags, void* ustc); //鼠标取样本点
void getTrainData(Mat &train_data, Mat &train_label);  //生成训练数据
void svm(); //svm分类

int main(int argc, char** argv)
{
    string path = "d:/peppers.png";
    img = imread(path);
    img.copyTo(image);
    if (img.empty())
    {
        cout << "Image load error";
        return 0;
    }
    namedWindow(wdname);
    setMouseCallback(wdname, on_mouse, 0);

    for (;;)
    {
        imshow("image", img);

        int c = waitKey(0);
        if ((c & 255) == 27)
        {
            cout << "Exiting ...\n";
            break;
        }
        if ((char)c == ‘c‘)
        {
            flag = false;
        }
        if ((char)c == ‘q‘)
        {
            destroyAllWindows();
            break;
        }
    }
    svm();
    return 0;
}

//鼠标在图像上取样本点,按q键退出
void on_mouse(int event, int x, int y, int flags, void* ustc)
{
    if (event == CV_EVENT_LBUTTONDOWN)
    {
        Point pt = Point(x, y);
        Vec3b point = img.at<Vec3b>(y, x);  //取出该坐标处的像素值,注意x,y的顺序
        Mat tmp = (Mat_<float>(1, 3) << point[0], point[1], point[2]);
        if (flag)
        {
            targetData.push_back(tmp); //加入正样本矩阵
            circle(img, pt, 2, Scalar(0, 255, 255), -1, 8); //画出点击的点 

        }

        else
        {
            backData.push_back(tmp); //加入负样本矩阵
            circle(img, pt, 2, Scalar(255, 0, 0), -1, 8); 

        }
        imshow(wdname, img);
    }
}

void getTrainData(Mat &train_data, Mat &train_label)
{
    int m = targetData.rows;
    int n = backData.rows;
    cout << "正样本数::" << m << endl;
    cout << "负样本数:" << n << endl;
    vconcat(targetData, backData, train_data); //合并所有的样本点,作为训练数据
    train_label = Mat(m + n, 1, CV_32S, Scalar::all(1)); //初始化标注
    for (int i = m; i < m + n; i++)
        train_label.at<int>(i, 0) = -1;
}

void svm()
{
    Mat train_data, train_label;
    getTrainData(train_data, train_label); //获取鼠标选择的样本训练数据

    // 设置参数
    Ptr<SVM> svm = SVM::create();
    svm->setType(SVM::C_SVC);
    svm->setKernel(SVM::LINEAR);

    // 训练分类器
    Ptr<TrainData> tData = TrainData::create(train_data, ROW_SAMPLE, train_label);
    svm->train(tData);

    Vec3b color(0, 0, 0);
    // Show the decision regions given by the SVM
    for (int i = 0; i < image.rows; ++i)
    for (int j = 0; j < image.cols; ++j)
    {
        Vec3b point = img.at<Vec3b>(i, j);  //取出该坐标处的像素值
        Mat sampleMat = (Mat_<float>(1, 3) << point[0], point[1], point[2]);
        float response = svm->predict(sampleMat);  //进行预测,返回1或-1,返回类型为float
        if ((int)response != 1)
            image.at<Vec3b>(i, j) = color;  //将背景设置为黑色
    }

    imshow("SVM Simple Example", image);
    waitKey(0);
}

输入原图像:

程序运行后显示:

时间: 2024-12-22 14:14:18

在opencv3中利用SVM进行图像目标检测和分类的相关文章

使用Caffe完成图像目标检测 和 caffe 全卷积网络

一.[用Python学习Caffe]2. 使用Caffe完成图像目标检测 标签: pythoncaffe深度学习目标检测ssd 2017-06-22 22:08 207人阅读 评论(0) 收藏 举报  分类: 机器学习(22)  深度学习(12)  版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 2. 使用Caffe完成图像目标检测 本节将以一个快速的图像目标检测网络SSD作为例子,通过Python Caffe来进行图像目标检测. 必须安装windows-ssd版本的Ca

目标检测与分类

目标检测的一般思路是 1.获取含有大量冗余特征的集合 2.利用机器学习的方法从特征集合中找出能够反映目标物体特性的特征 3.利用找到的特征构造分类器,实现目标检测 当前通用目标检测领域所使用的特征主要可以分为两类. 1.通过划分或变换得到的特征,如使用最广泛的Haar-like特征.这类特征的主要特点是:特征计算十分简单,特征集合的冗余信息能够很好地描述目标物体的特性.另外,只要图像大小确定,特征集合中各个特征的位置以及集合中总的特征数量就是固定的,这使得利用类Haar特征构建分类器比较简单:

卫星图像目标检测

1.You Only Look Twice: Rapid Multi-Scale Object Detection In Satellite Imagery 论文时间:2018.5 论文地址:https://arxiv.org/pdf/1805.09512.pdf 网络结构: 基于YOLOv2的改进网络结构,为了解决目标较小问题,输出特征图从13变成26,输入图像尺寸416 测试过程: 采用滑动窗口法选择416大小的区域,相邻区域之间重叠15%避免物体在边界被分割的情况.如下图 算法性能: 大于

tensorflow利用预训练模型进行目标检测(一):预训练模型的使用

一.运行样例 官网链接:https://github.com/tensorflow/models/blob/master/research/object_detection/object_detection_tutorial.ipynb  但是一直有问题,没有运行起来,所以先使用一个别人写好的代码 上一个在ubuntu下可用的代码链接:https://gitee.com/bubbleit/JianDanWuTiShiBie  使用python2运行,python3可能会有问题 该代码由https

第十八节、基于传统图像处理的目标检测与识别(HOG+SVM附代码)

其实在深度学习分类中我们已经介绍了目标检测和目标识别的概念.为了照顾一些没有学过深度学习的童鞋,这里我重新说明一次:目标检测是用来确定图像上某个区域是否有我们要识别的对象,目标识别是用来判断图片上这个对象是什么.识别通常只处理已经检测到对象的区域,例如,人们总是会使在已有的人脸图像的区域去识别人脸. 传统的目标检测方法与识别不同于深度学习方法,后者主要利用神经网络来实现分类和回归问题.在这里我们主要介绍如何利用OpecnCv来实现传统目标检测和识别,在计算机视觉中有很多目标检测和识别的技术,这里

航空遥感图像(Aerial Images)目标检测数据集汇总

常规目标检测数据集有很多,现在前沿的目标检测算法(如Faster R-CNN, Yolo, SSD, Mask R-CNN等)基本都是在这些常规数据集上实验的,但是,基于常规数据集训练的分类器,在航空遥感图像上的检测效果并不好,主要原因是航空遥感图像有其特殊性: 1,尺度多样性,航空遥感图像从几百米到近万米的拍摄高度都有,且地面目标即使是同类目标也大小不一,如港口的轮船大的有300多米,小的也只有数十米: 2,视角特殊性,航空遥感图像的视角基本都是高空俯视,但常规数据集大部分还是地面水平视角,所

目标检测 — two-stage检测

目前主流的目标检测算法主要是基于深度学习模型,其可以分成两大类:two-stage检测算法:one-stage检测算法.本文主要介绍第一类检测算法,第二类在下一篇博文中介绍. 目标检测模型的主要性能指标是检测准确度和速度,对于准确度,目标检测要考虑物体的定位准确性,而不单单是分类准确度.一般情况下,two-stage算法在准确度上有优势,而one-stage算法在速度上有优势.不过,随着研究的发展,两类算法都在两个方面做改进. two-stage检测算法将检测问题划分为两个阶段,首先产生候选区域

目标检测综述

这篇综述是我统计信号处理的作业,在这里分享一下,将介绍计算机视觉中的目标检测任务,论述自深度学习以来目标检测的常见方法,着重讲yolo算法,并且将yolo算法与其他的one-stage以及two-stage方法进行比较. 目录 1.介绍 2.YOLO 2.1 YOLOv1 2.2 YOLOv2 2.3 YOLOv3 3.其他方法 RCNN FastRCNN FasterRCNN SSD RetinaNet 4.实验结果比较 5.总结 参考文献 1. 介绍 目标检测在现实中的应用很广泛,我们需要检

4. 基于深度学习的目标检测算法的综述(转)

4. 基于深度学习的目标检测算法的综述(转) 原文链接:https://www.cnblogs.com/zyly/p/9250195.html 目录 一 相关研究 1.选择性搜索(Selective Search) 2.OverFeat 二.基于区域提名的方法 1.R-CNN 2.SPP-Net 3.Fast R-CNN 4.Faster R-CNN 5.R-FCN 三 端对端的方法 1.YOLO 2.SSD 四 总结 在前面几节中,我们已经介绍了什么是目标检测,以及如何进行目标检测,还提及了滑