C++结合OpenCV进行图像处理与分类

⭐️我叫忆_恒心,一名喜欢书写博客的在读研究生👨‍🎓。
如果觉得本文能帮到您,麻烦点个赞👍呗!

近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧,喜欢的小伙伴给个三连支持一下呗。👍⭐️❤️
Qt5.9专栏定期更新Qt的一些项目Demo
项目与比赛专栏定期更新比赛的一些心得面试项目常被问到的知识点。

在这里插入图片描述

一、引言

在当今数字化时代,图像处理技术在各个领域得到了广泛应用。无论是自动驾驶、医学影像分析,还是安防监控、虚拟现实,图像处理都扮演着重要角色。OpenCV(Open Source Computer Vision Library)作为一个开源的计算机视觉库,提供了丰富的图像处理函数和工具,使得图像处理变得更加简单和高效。本文将介绍如何使用C++结合OpenCV进行基础的图像处理操作。
在这里插入图片描述

二、 安装OpenCV

Windows系统详细的环境安装,可以参考我之前写的这一篇文章。
VS2019中配置C++ OpenCV 4.5.4完整指南

在使用OpenCV之前,我们需要先在开发环境中安装OpenCV库。以下是Windows和Ubuntu系统中安装OpenCV的基本步骤:

1. Windows系统:

  1. 下载OpenCV安装包:OpenCV官网
  2. 解压安装包到指定目录。
  3. 配置环境变量,将OpenCV的bin目录添加到系统的PATH中。
  4. 在C++项目中添加OpenCV库的包含路径和库文件路径。

2. Ubuntu系统:

sudo apt update
sudo apt install libopencv-dev

三、 图像读取与显示

首先,我们来看一个简单的图像读取与显示的示例程序:

#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    // 读取图像
    cv::Mat image = cv::imread("example.jpg");
    
    // 检查图像是否读取成功
    if(image.empty()) {
        std::cout << "无法打开图像文件" << std::endl;
        return -1;
    }
    
    // 显示图像
    cv::imshow("Display Image", image);
    cv::waitKey(0); // 等待按键按下
    
    return 0;
}

在这个示例中,我们使用cv::imread函数读取一张图像,并使用cv::imshow函数显示图像。cv::waitKey(0)函数用于等待用户按键,以便窗口不会立即关闭。

四、 图像预处理

图像预处理是图像处理中的重要步骤,包括图像的灰度化、二值化、平滑处理等。以下是一个简单的图像预处理示例:

#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    cv::Mat image = cv::imread("example.jpg", cv::IMREAD_GRAYSCALE); // 读取灰度图像

    if(image.empty()) {
        std::cout << "无法打开图像文件" << std::endl;
        return -1;
    }

    cv::Mat blurredImage;
    cv::GaussianBlur(image, blurredImage, cv::Size(5, 5), 1.5); // 高斯模糊处理

    cv::imshow("Original Image", image);
    cv::imshow("Blurred Image", blurredImage);
    cv::waitKey(0);
    
    return 0;
}

在这个示例中,我们使用cv::imread函数以灰度模式读取图像,并使用cv::GaussianBlur函数对图像进行高斯模糊处理。

五、图像形状检测

OpenCV还提供了丰富的形状检测功能,例如边缘检测和轮廓检测。以下是一个简单的边缘检测示例:

#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    cv::Mat image = cv::imread("example.jpg", cv::IMREAD_GRAYSCALE);
    
    if(image.empty()) {
        std::cout << "无法打开图像文件" << std::endl;
        return -1;
    }

    cv::Mat edges;
    cv::Canny(image, edges, 50, 150); // Canny边缘检测

    cv::imshow("Edges", edges);
    cv::waitKey(0);
    
    return 0;
}

在这个示例中,我们使用cv::Canny函数进行边缘检测,并显示结果图像。

六、图像分类

图像分类是计算机视觉中的重要任务,常用于自动驾驶、安防监控、医疗诊断等领域。通过对图像内容进行分类,我们可以实现对不同类别物体的识别和区分。

1.1 使用Bag of Words (BOW)算法进行图像分类

Bag of Words (BOW)算法是一种经典的图像分类方法,通过将图像表示为特征词袋进行分类。下面是使用OpenCV和C++实现BOW算法进行图像分类的示例代码。

1.2 环境准备

首先,确保已安装OpenCV库,并配置好C++开发环境。需要安装额外的库如opencv_contrib,以便使用BOW相关模块。

1.3 示例代码

以下是实现BOW算法进行图像分类的代码:

#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <opencv2/ml.hpp>
#include <iostream>
#include <vector>

using namespace cv;
using namespace cv::ml;
using namespace std;
using namespace cv::xfeatures2d;

void extractFeatures(const vector<string>& imagePaths, vector<Mat>& features, Ptr<SIFT> detector) {
    for (const auto& path : imagePaths) {
        Mat image = imread(path, IMREAD_GRAYSCALE);
        vector<KeyPoint> keypoints;
        Mat descriptors;
        detector->detectAndCompute(image, noArray(), keypoints, descriptors);
        features.push_back(descriptors);
    }
}

int main() {
    // 图像路径
    vector<string> trainImages = {"image1.jpg", "image2.jpg", "image3.jpg"};
    vector<string> testImages = {"test1.jpg", "test2.jpg"};

    // 创建SIFT特征检测器
    Ptr<SIFT> detector = SIFT::create();

    // 提取训练集特征
    vector<Mat> trainFeatures;
    extractFeatures(trainImages, trainFeatures, detector);

    // 聚类,创建词典
    BOWKMeansTrainer bowTrainer(100); // 词典大小
    for (const auto& feature : trainFeatures) {
        bowTrainer.add(feature);
    }
    Mat dictionary = bowTrainer.cluster();

    // 创建BOW图像描述器
    Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("FlannBased");
    BOWImgDescriptorExtractor bowDE(detector, matcher);
    bowDE.setVocabulary(dictionary);

    // 训练分类器
    Ptr<SVM> svm = SVM::create();
    Mat trainData, labels;
    for (size_t i = 0; i < trainImages.size(); ++i) {
        Mat bowDescriptor;
        bowDE.compute(imread(trainImages[i], IMREAD_GRAYSCALE), bowDescriptor);
        trainData.push_back(bowDescriptor);
        labels.push_back((float)i); // 假设每个图像都有不同的标签
    }
    svm->train(trainData, ROW_SAMPLE, labels);

    // 测试分类器
    for (const auto& path : testImages) {
        Mat testImage = imread(path, IMREAD_GRAYSCALE);
        Mat bowDescriptor;
        bowDE.compute(testImage, bowDescriptor);
        float response = svm->predict(bowDescriptor);
        cout << "Image: " << path << " classified as: " << response << endl;
    }

    return 0;
}

result

Image: test1.jpg classified as: 0
Image: test2.jpg classified as: 1

七、适合图像分类的优秀的仓库

我可以为您提供一些图片的链接,您可以使用这些图片作为博客中的例子。以下是一些公共领域图片资源网站的链接,您可以从这些网站下载适合用于图像分类任务的图片:

  1. Pixabay - 提供大量免费图片,适用于个人和商业用途。

    • 链接: Pixabay
  2. Unsplash - 一个提供高分辨率照片的平台,所有照片均可免费使用。

    • 链接: Unsplash
  3. Pexels - 提供免费且高质量的图片,可用于商业用途,无需署名。

    • 链接: Pexels
  4. Open Images Dataset - Google 提供的一个大规模图片数据集,可用于图像识别和分类。

    • 链接: Open Images Dataset
      在这里插入图片描述
  5. MNIST Database - 手写数字的图片数据集,常用于图像分类和机器学习任务。

    • 链接: MNIST Database
      在这里插入图片描述
      在这里插入图片描述
  6. CIFAR-10 and CIFAR-100 - 包含多种类别的图片数据集,适用于图像分类。

    • 链接: CIFAR-10/CIFAR-100
  7. ImageNet - 一个非常大的图像数据库,用于视觉对象识别研究。

    • 链接: ImageNet
  8. Flickr - 通过Flickr的Creative Commons搜索,您可以找到许多可用于非商业或商业用途的图片。

    • 链接: Flickr Creative Commons
  9. Getty Images - 虽然Getty Images主要是版权图片,但它们也提供了一些免费图片的集合。

    • 链接: Getty Images
  10. NASA Image and Video Library - NASA提供的图片和视频资源,适合用于科学和教育目的。

    • 链接: NASA Image and Video Library

请注意,使用图片时,您应遵守每个网站的使用条款和版权信息。对于商业用途,建议仔细检查图片的许可证,确保合法使用。

八、 结论

通过以上步骤,我们使用C++和OpenCV实现了基于BOW算法的图像分类。本文介绍了从特征提取、词典创建到模型训练和分类的全过程。这仅仅是图像分类的入门,OpenCV还支持更多复杂的算法和深度学习模型,读者可以进一步探索,以便在实际项目中更好地应用这些技术。希望本文对您在学习和应用图像分类技术方面有所帮助。

最后,最后
如果觉得有用,麻烦三连👍⭐️❤️支持一下呀,希望这篇文章可以帮到你,你的点赞是我持续更新的动力

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/682960.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

选择排序-Java版本

选择排序 算法的思想&#xff1a;java模拟 算法的思想&#xff1a; 每遍历一次就找一个最小的数 *外层 一共遍历 length-1次 总遍历次数符合等差数列 时间复杂度为O(n^2)内部查找 并 返回 数值 和 下标 java模拟 public static void selectSort(int[] arr) {for(int i 0;i<…

Flask 学习笔记 总结

python基础 服务端开发编程 第一个是赋值运算&#xff0c;第二是乘法&#xff0c;最后是一个是幂&#xff08;即a2&#xff09; a 2 a * 2 a ** 2 Python支持多重赋值&#xff1a; a, b, c 2, 3, 4 这句命令相当于&#xff1a; a 2 b 3 c 4 Python支持对字符串的灵活…

网络编程(一)

网络编程&#xff08;一&#xff09; 网络基础网络体系结构**OSI的7层模型**&#xff1a;&#xff08;理想化&#xff09;**每层的功能** **TCP/IP的4层模型**&#xff1a;&#xff08;在使用&#xff09;常见的协议IP地址IPV4分类A类&#xff08;第1位固定为0&#xff09;B类&…

10个令人惊叹的Python自动化脚本

大家好&#xff0c;Python凭借其简单和通用性&#xff0c;能够为解决每天重复同样的工作提供最佳方案。本文将介绍10个Python自动化脚本&#xff0c;可以帮助自动化完成任务&#xff0c;提高工作效率&#xff0c;它们可以成为项目运行中的便捷工具&#xff0c;可以收藏这些脚本…

conflicting types for 错误问题

操作系统真象还原中&#xff0c;第十一章出现的问题&#xff1a; 怎样编译都会出现一个conflicting types for ’xxx‘的错误 出现这个错误的原因&#xff1a; 头文件声明和定义参数稍有不同 头文件中声明 void Hanlder(const char * buf); 在定义时写作 void Hanlder(char…

C# WPF入门学习主线篇(六)—— TextBox常见属性和事件

欢迎回到C# WPF入门学习系列的第六篇。在前面的文章中&#xff0c;我们探讨了按钮&#xff08;Button&#xff09;的事件处理。今天&#xff0c;我们将继续学习另一个常用的WPF控件——TextBox。本文将介绍 TextBox 的常见属性和事件&#xff0c;并通过示例代码展示如何在实际应…

用这个AI工具,做公众号爆款图文,5分钟一篇10w+,居然这么简单!(附工具教程)

文章首发于公众号&#xff1a;X小鹿AI副业 大家好&#xff0c;我是程序员X小鹿&#xff0c;前互联网大厂程序员&#xff0c;自由职业2年&#xff0c;也一名 AIGC 爱好者&#xff0c;持续分享更多前沿的「AI 工具」和「AI副业玩法」&#xff0c;欢迎一起交流~ 之前X小鹿一直在各…

泵制造5G智能工厂工业物联数字孪生可视化,推进制造业数字化转型

泵制造5G智能工厂工业物联数字孪生可视化&#xff0c;推进制造业数字化转型。泵制造行业&#xff0c;作为工业领域的核心部分&#xff0c;更是急需通过技术创新实现生产流程的智能化和高效化。而5G智能工厂工业物联数字孪生可视化技术的出现&#xff0c;为泵制造业的数字化转型…

代码随想录算法训练营第四十四天 | 01背包问题理论基础、01背包问题滚动数组、416. 分割等和子集

背包问题其实有很多种&#xff0c;01背包是最基础也是最经典的&#xff0c;软工计科学生一定要掌握的。 01背包问题 代码随想录 视频讲解&#xff1a;带你学透0-1背包问题&#xff01;| 关于背包问题&#xff0c;你不清楚的地方&#xff0c;这里都讲了&#xff01;| 动态规划经…

YOLO10:手把手安装教程与使用说明

目录 前言一、YOLO10检测模型二、YOLO安装过程1.新建conda的环境 yolo10安装依赖包测试 总结 前言 v9还没整明白&#xff0c;v10又来了。而且还是打败天下无敌手的存在&#xff0c;连最近很火的RT-DETR都被打败了。那么&#xff0c;笑傲目标检测之林的v10又能持续多久呢&#…

2024第三届全国大学生数据分析大赛,有没有没有思路的朋友?

大家好呀&#xff0c;2024第三届全国大学生数据分析大赛准备开始咯&#xff0c;大家是不是没有思路呀。 本论文可以保证原创&#xff0c;保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊弄人的垃圾半成品论文。 比赛现在还能报名哈&#xff01;6-7才截…

图像背景去除工具:removebg

文章目录 简介面向不同用户价格 简介 removebg&#xff0c;就是remove background&#xff0c;是一款智能图片背景去除工具。 在免费使用时&#xff0c;用到的是本地的CPU。我第一次试用时&#xff0c;图片刚上传之后&#xff0c;电脑的帧率便直线下降&#xff0c;鼠标都拖不…

买视觉检测设备需要多少钱?

随着工业自动化的发展&#xff0c;其应用范围逐步提高&#xff0c;其中母子图像传感器、CMOS和CCD摄像机、DSP、ARM嵌入式技术、图像处理和模式识别技术的快速发展&#xff0c;有效地推动了视觉检测设备的发展。在机器视觉领域中&#xff0c;常见的就是视觉检测、视觉识别、视觉…

Win11中Yolo V10安装过程记录

1. 配置Anaconda环境&#xff1a; conda create -n yolov10 python3.9 conda activate yolov10 pip install -r requirements.txt pip install -e . 这里由于torch2.0.1太慢&#xff0c;单独用pytorch官网安装流程&#xff08;选择支持GPU版本&#xff09;&#xff1a; con…

数据治理挑刺行动:深化治理,提升数据质量

在当今信息化社会&#xff0c;数据已经成为推动经济发展、社会进步的重要驱动力。然而&#xff0c;随着数据量的爆炸式增长&#xff0c;数据质量问题也日益凸显&#xff0c;给各行各业带来了不小的挑战。为了应对这一挑战&#xff0c;深化数据治理&#xff0c;提升数据质量已成…

【CT】LeetCode手撕—3. 无重复字符的最长子串

目录 题目1- 思路1-1 模式1&#xff1a;涉及去重判断1-2 模式2&#xff1a;遍历字符串区间 2- 题解⭐无重复字符的最长子串——题解思路 3- ACM实现 原题链接&#xff1a;3. 无重复字符的最长子串 题目 无重复字符的最长子串 给定一个字符串 s &#xff0c;请你找出其中不含有…

kubernetes负载均衡---MetalLB

https://github.com/metallb/metallb 参考 &#xff1a; https://mp.weixin.qq.com/s/MBOWfcTjFMmgJFWw-FIk0Q 自建的Kubernetes集群&#xff0c;默认情况下是不支持负载均衡的。当需要提供服务的外部访问时&#xff0c;可使用 Ingress、NodePort等方式。他们都存在一些问题 …

python基础篇(1):type()

1 type()函数 type()函数是Python内置的函数之一&#xff0c;它用于获取一个对象的数据类型。 一般语法如下&#xff1a; type(object) 其中&#xff0c;object是您要检查其类型的变量或对象。type()函数将返回一个表示对象类型的类型对象。 2 使用方式 &#xff08;1&…

C语言中指针的说明

什么是指针&#xff1f; 在C语言当中&#xff0c;我们可以将指针理解为内存当中存储的地址&#xff0c;就像生活当中&#xff0c;一个小区里面&#xff0c;在小区里面有很单元&#xff0c;每一栋单元&#xff0c;单元内的房间有着不同的房间号&#xff0c;我们可以同过几栋几单…

推荐系统学习 一

参考&#xff1a;一文看懂推荐系统&#xff1a;召回08&#xff1a;双塔模型——线上服务需要离线存物品向量、模型更新分为全量更新和增量更新_数据库全量更新和增量更新流程图-CSDN博客 一文看懂推荐系统&#xff1a;概要01&#xff1a;推荐系统的基本概念_王树森 小红书-CSD…