当前位置: 首页 > article >正文

【学习OpenCV4】基于OpenCV的手写数字识别

本内容分享于课程《OpenCV入门精讲(C++/Python双语教学)》,地址:

OpenCV入门精讲(C++/Python双语教学)

如果想提升C++的编程水平,可以参考课程:

C++进阶学习

OpenCV课程中还有很多有趣且实用的案例,这些案例都以C++和Python两种语言实现,对其中的代码都有详细的讲解。
在这里插入图片描述

基于OpenCV的手写数字识别案例从’digits.png’加载手写数字识别的数据集,然后训练一个SVM和KNearest 分类器并评估它们的准确率。
数据集会经过如下的预处理:

  • 基于图像的矩去扭曲 (参见函数deskew())
  • 数字图像被分割成4个10x10的cells和16个bin,为每个bin计算定向梯度直方图
  • 使用Hellinger度量将直方图转换为space(see [1] (RootSIFT))

代码如下

int main(int /* argc */, char *argv[])
{
    help(argv);

    vector<Mat> digits; // 训练数据
    vector<int> labels; // 标签

    // 加载训练数据和标签
    load_digits(DIGITS_FN, digits, labels);

    cout << "preprocessing..." << endl;

    // 数据打乱
    shuffle(digits, labels);

    vector<Mat> digits2;

    // 扭曲图像
    for (size_t i = 0; i < digits.size(); i++)
    {
        Mat deskewed_digit;
        deskew(digits[i], deskewed_digit);
        digits2.push_back(deskewed_digit);
    }

    Mat samples;

    // 预处理求hog算子
    preprocess_hog(digits2, samples);
    // imshow("samples", samples);
    // waitKey(0);

    // 90%的数据做训练集
    int train_n = (int)(0.9 * samples.rows);
    Mat test_set;

    // 存储测试数据
    vector<Mat> digits_test(digits2.begin() + train_n, digits2.end());
    // 马赛克式将小图像拼成大图像
    mosaic(25, digits_test, test_set);
    imshow("test set", test_set);
    imwrite("test_image.jpg", test_set);

    // 训练数据和测试数据划分
    Mat samples_train = samples(Rect(0, 0, samples.cols, train_n));
    Mat samples_test = samples(Rect(0, train_n, samples.cols, samples.rows - train_n));
    vector<int> labels_train(labels.begin(), labels.begin() + train_n);
    vector<int> labels_test(labels.begin() + train_n, labels.end());

    Ptr<ml::KNearest> k_nearest;
    Ptr<ml::SVM> svm;
    vector<float> predictions;
    Mat vis;

    // K最近邻算法
    cout << "training KNearest..." << endl;
    k_nearest = ml::KNearest::create();
    // 模型训练
    k_nearest->train(samples_train, ml::ROW_SAMPLE, labels_train);

    // KNearest做结果预测
    k_nearest->findNearest(samples_test, 4, predictions);
    // 模型评估,计算错误率
    evaluate_model(predictions, digits_test, labels_test, vis);
    imshow("KNearest test", vis);
    imwrite("KNearest-test.jpg", vis);
    k_nearest.release();

    // SVM算法
    cout << "training SVM..." << endl;
    svm = ml::SVM::create();
    svm->setGamma(5.383);
    svm->setC(2.67);
    svm->setKernel(ml::SVM::RBF);
    svm->setType(ml::SVM::C_SVC);
    svm->train(samples_train, ml::ROW_SAMPLE, labels_train);

    // predict digits with SVM
    svm->predict(samples_test, predictions);
    evaluate_model(predictions, digits_test, labels_test, vis);
    imshow("SVM test", vis);
    imwrite("SVM-test.jpg", vis);
    cout << "Saving SVM as \"digits_svm.yml\"..." << endl;
    // 训练的结果保存
    svm->save("digits_svm.yml");
    svm.release();

    waitKey();

    return 0;
}

训练结果如下:

KNearest  error: 2.80 %
SVM  error: 2.40 %

测试图片如下:
在这里插入图片描述

KNearest算法测试结果(红色标识为识别错误的结果):
在这里插入图片描述

SVM算法测试结果(红色标识为识别错误的结果):
在这里插入图片描述

更多学习可以参考图书:

《学习OpenCV4:基于Python的算法实战》

《深度学习计算机视觉实战》


http://www.kler.cn/a/6584.html

相关文章:

  • 【Prompt Engineering】7 聊天机器人
  • Loki 微服务模式组件介绍
  • Django 提供的会话(Session)相关的设置说明
  • 使用Python开发高级游戏:创建一个3D射击游戏
  • 深度学习推理速度优化指南
  • run postinstall error, please remove node_modules before retry!
  • Chrome 112 发布,删除 Chrome Apps、支持 CSS 嵌套
  • React的合成事件
  • C#收集SMD零件计数器数料机
  • AI大模型争议的背后,是技术以人为本的初衷
  • Tomcat面试题+http面试题+Nginx面试题+常见面试题
  • 读《高效能人士的七个习惯》的一些感悟
  • CSS基础
  • 从零开始实现一个C++高性能服务器框架----协程模块
  • 【MySQL】表的基本约束
  • CSS特殊样式
  • 编译Linux内核一定要知道的几个小Tips
  • 数据结构_第五关:单链表OJ题练习
  • 反射学习总结
  • ABC296E Transition Game
  • c++实现sqlite的增删改查
  • 如何下载ChatGPT-ChatGPT如何写作
  • 中华好诗词(六)
  • ChatGPT 从注册到自建应用
  • Linux【环境变量】
  • Apple Pencil性价比高吗?第三方平替电容笔排名