• 基于OpenCV的交通标志识别(SVM+Hu不变矩, 部分测试源代码)


    最近跟着老师做一个交通识别的项目, 总算明白了一个道理, 这水啊, 不去亲自蹚上一遭就不知道有多深, 更根本的原因当然还是自己学的不够扎实, 不够好.

    经过了一个寒假的折磨,终于做出了一个原型来, 想到了自己当时被折磨的头疼的样子,想着将一部分源代码发上来, 希望可以帮助到别人.

    呵呵,废话不多说了

    这里我发的是一个手写字符识别的程序(这是在编写交通标志的过程中产生的,因为当时手头的交通标志的样本够,所以从网上下载了手写字符的样本库来测试SVM)

    //添加使用到的头文件
    #include <opencv2/opencv.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <opencv2/core/core.hpp>
    #include <opencv2/ml/ml.hpp>
    #include <iostream>
    #include <fstream>
    #include "stdlib.h"
    //声明命名空间
    using namespace std;
    using namespace cv;
    using namespace cv::ml;
    
    //!训练数据参数
    const int sample_num_perclass = 40;     //训练每类图片数量
    const int class_num = 3;                //训练类数
    //!所有图片尺寸归一化
    const int image_cols = 16;              //定义图片尺寸
    const int image_rows = 28;              //定义图片尺寸
    //!生成的训练文件保存位置
    char SVMName[40] = "SVM.xml";              //分类器的训练生成的名字,读取时也按照这个名字来
    #define RW      1                       //0为读取现有的分类器,1表示重新训练一个分类器
    //!读取的图像的路径
    char path[40] = "/home/aimer/Desktop/test2.png";
    //!程序入口
    double Hu[7];       //存储得到的Hu矩阵
    Moments mo;         //矩变量
    cv::Size size = cv::Size(image_cols, image_rows);
    int main(void)
    {
    #if RW
        //!读取训练数据
        Mat trainingData = Mat::zeros(sample_num_perclass*class_num, 7, CV_32FC1);          //填入图像的7个Hu矩
        Mat trainingLabel = Mat::zeros(sample_num_perclass*class_num, 1, CV_32SC1);
        char buf[50];                       //字符缓冲区
        for(int i=0;i<class_num;i++)        //不同了类的循环
        {
            for(int j=0;j<sample_num_perclass;j++)      //一个类中的图片数量
            {
                //!生成图片的路径(不同类的图片被放在了不同的文件夹下)
                sprintf(buf, "/home/aimer/Desktop/charSamples/%d/%d.png", i, j+1);
                //!读取
                Mat src = imread(buf, 0);
                //!重设尺寸(归一化)
                Mat reImg;
                resize(src, reImg, size, CV_INTER_CUBIC);
                Mat canny;
                Canny(reImg, canny, 200, 120);
                //!求Hu矩
                mo = moments(canny);
                HuMoments(mo, Hu);
                //!将Hu矩填入训练数据集里
                float *dstPoi = trainingData.ptr<float>(i*sample_num_perclass+j);  //指向源的指针
                for(int r=0;r<7;r++)
                    dstPoi[r] = (float)Hu[r];
                //!添加对该数据的分类标签
                int *labPoi = trainingLabel.ptr<int>(i*sample_num_perclass+j);
                labPoi[0] = i;
            }
        }
        imwrite("res.png", trainingData);
    
        //!创建SVM支持向量机并训练数据
        Ptr<SVM> svm = SVM::create();
        svm->setType(SVM::C_SVC);
        svm->setC(0.01);
        svm->setKernel(SVM::LINEAR);
        svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 10000, 1e-6));
        svm->train(trainingData, ROW_SAMPLE, trainingLabel);
        svm->save(SVMName);
    #else
        //读取xml文件
        Ptr<SVM> svm=SVM::load<SVM>(SVMName);
    #endif
        //!读取一副图片进行测试
        Mat temp = imread("/home/aimer/Desktop/test2.png", 0);
        Mat dst;
        resize(temp, dst, size, CV_INTER_CUBIC);
        Mat canny;
        Canny(dst, canny, 200, 120);
        mo = moments(canny);
        HuMoments(mo, Hu);
        Mat pre(1, 7, CV_32FC1);
        float *p = pre.ptr<float>(0);
        for(int i=0;i<7;i++)
            p[i] = Hu[i];
        float res = svm->predict(pre);
        cout<<res<<endl;
        return 0;
    }

    整体思路是:读取图片(程序没有做灰度处理,因为读取到的时候就是灰度图了,与imread的参数有关),然后归一化,求出七个不变矩,然后填充样进行训练,训练完成后读取一幅图片进行测试.

    环境为:Ubuntu 16.04 64位+OpenCV 3.1.0+Qt 4.8

    注意一点的是:素材文件夹下面的图片名字要改成数字(每个文件下的文件名从1开始,例如:1.png;并且不能断开,例如:1.png,3.png这是不允许的,程序中被没有加入这些判断检测程序,可以选择自己加上这些代码,这样就免去了对文件重命名的烦恼)

    样本的链接:

    链接:http://pan.baidu.com/s/1pLPeZkZ 密码:26eb

    感谢这位网上大咖, 看了他的文章对望帮助很大, 再次感谢

    http://www.cnblogs.com/ronny/p/opencv_road_more_01.html

    这是他写的关于神经网络识别车牌号的代码

  • 相关阅读:
    hutool 糊涂
    java 连接 Redis 工具
    生成6位验证码
    @FeignClient定义冲突解决
    Seate分布式事务解决方案
    算法——最小生成树的关键边和伪关键边
    《Kubernetes权威指南》读书笔记
    Docker——容器卷管理
    算法——课程表 II(有向图拓扑排序)
    Docker——网络
  • 原文地址:https://www.cnblogs.com/tcysky/p/6542882.html
Copyright © 2020-2023  润新知