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还支持更多复杂的算法和深度学习模型,读者可以进一步探索,以便在实际项目中更好地应用这些技术。希望本文对您在学习和应用图像分类技术方面有所帮助。

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Oracle中unique索引的作用是啥

在Oracle数据库中&#xff0c;UNIQUE索引是一种特殊的索引&#xff0c;它除了提供常规索引的快速检索功能外&#xff0c;还强制其索引列或列组合的值必须是唯一的。以下是UNIQUE索引的主要作用&#xff1a; 数据完整性&#xff1a;UNIQUE索引确保表中没有两行具有相同的索引列…

数据库(24)——外键约束

概念 外键用来让两张表的数据之间建立连接&#xff0c;从而保证数据的一致性和完整性。 具有外键的表称为子表&#xff0c;关联的表称为父表。 语法 添加外键 CREATE TABLE 表名( 字段名 数据类型, .. [CONSTRAINT] [外键名称] FOREIGN KEY (外键字段名) REFERENCES 主表(主…

CGS与MGS的矩阵正交化-C语言实现

格拉姆-施密特正交化和改进的格拉姆-施密特正交化 格拉姆-施密特正交化CGS 数学公式 代码实现&#xff1a; 过程版 矩阵运算实现的难点在于每次运算都是一个向量&#xff0c;需要for循环进行&#xff0c;会带来运算时在代码中的复杂&#xff0c;进而难以理解代码的过程 Q矩阵…

软件测试——白盒测试

目录 学习视频来源&#xff1a;1.01什么是白盒测试(Av809778070,P1)_哔哩哔哩_bilibili 1.语句覆盖 2.判定覆盖 3.条件覆盖 4.判定条件覆盖 5.条件组合覆盖 6.路径覆盖 7.基本路径覆盖 学习视频来源&#xff1a;1.01什么是白盒测试(Av809778070,P1)_哔哩哔哩_bilibili …

正则表达式运用

已经写了表达式&#xff0c;下一步就是匹配字符串得到结果 使用matcher的源码&#xff08;匹配&#xff09;普通方法&#xff0c;find&#xff08;寻找&#xff09;合适的代码&#xff0c;看字符串是否匹配成功 是否可以匹配上 匹配么&#xff0c;匹配就留下&#xff0c;fin…

基于SVD的点云配准

前言 为了更加深入透彻的理解点云配准,所以打算从头实现一次配准的过程,从关键点提取、特征提取、对应关系确定、SVD确定变换矩阵,一步一步完成。 首先介绍一下配准过程中用到的一些函数 1. ISS3D关键点提取 具体来说,它使用ISS(Intrinsic Shape Signatures)关键…

Go 语言基础

1. 理解语句和标记 Go程序由一系列语句组成,而Go语句由一系列标记组成。这里,标记指的是语句中任何有意义的对象,包括如下。 关键字:用于特殊 Go 功能的保留字。操作符和标点符号:用于数学运算或执行特殊操作的符号。标识符:用于标识诸如存储位置或执行操作的函数等事物的…

热线系统自主可控改造:构建安全、高效的服务新纪元

一、引言&#xff1a;热线系统的重要性与挑战 在信息化时代&#xff0c;热线系统作为企业与客户沟通的关键渠道&#xff0c;承载着重要的信息传递和服务功能。然而&#xff0c;随着技术的不断进步和网络安全威胁的日益严峻&#xff0c;传统的热线系统面临着诸多挑战。这些挑战…

性能工具之 JMeter 常用组件介绍(三)

文章目录 一、常用组件介绍二、Sampler&#xff1a;取样器三、Controller:控制器&#xff08;逻辑控制器&#xff09;四、Pre Processor:预处理五、Post Processor:请求之后的处理六、Assertions:断言七、Timer:定时器八、Test Fragment&#xff1a;片段九、Config Element:配置…

STM32 SPI驱动读取LSM6DSRTR

提示&#xff1a;通过SPI驱动读取传感器数据 文章目录 前言一、LSM6DSRTR二、配置步骤1.配置SPI2.引入 LSM驱动库3.结果 总结 前言 制作一个倾角传感器&#xff0c;通过SPI读取LSM6DSRTR的加速度数据转换为角度&#xff0c;不用IIC的原因是考虑IIC通讯的协议过于繁琐&#xff…

springCloudAlibaba之服务熔断组件---sentinel

sentinel组件学习 sentinel学习sentinel容错机制使用代码方式进行QPS流控-流控规则初体验使用SentinelResource注解进行流控使用注解方式 sentinel学习 服务雪崩 服务雪崩效应&#xff1a;因服务提供者的不可用导致服务调用者的不可用&#xff0c;并将不可用逐渐放大的过程。 …

心链10----查询修改加入队伍业务实现

心链 — 伙伴匹配系统 接口设计 查询队伍列表 :::success 分页展示队伍列表&#xff0c;根据名称、最大人数等搜索队伍 P0&#xff0c;信息流中不展示已过期的队伍 从请求参数中取出队伍名称等查询条件&#xff0c;如果存在则作为查询条件不展示已过期的队伍&#xff08;根…

docker实战命令大全

文章目录 1 环境准备1.1 移除旧版本Docker1.2安装工具包1.3配置docker yum源 2 安装最新docker2.1 设置开机自启docker2.2配置加速器 3 实操-镜像3.1搜索镜像3.2下载镜像3.3查看镜像3.4 删除镜像 4 实操-容器4.1运行nginx容器4.2 查看容器4.3启动容器4.5关闭容器4.6查看容器日志…

功能强大的开源数据中台系统 DataCap 2024.03.5 发布

推荐一套基于 SpringBoot 开发的简单、易用的开源权限管理平台&#xff0c;建议下载使用: https://github.com/devlive-community/authx 推荐一套为 Java 开发人员提供方便易用的 SDK 来与目前提供服务的的 Open AI 进行交互组件&#xff1a;https://github.com/devlive-commun…

2个不同node版本的前端项目,用到的一个node版本管理工具nvm,可一键切换node版本

背景&#xff1a; 对于需要在电脑运行2个不同的前端项目&#xff0c;但是使用的node版本不同&#xff0c;为了快捷切换和管理node版本&#xff0c;所以需要用到一个非常方便的工具&#xff0c;那就是下边的nvm&#xff0c;一个命令就可以非常方便的切换你想要的node。 1、下载…

分布式光纤测温DTS与光纤光栅FBG解调仪有什么区别?

分布式光纤测温DTS和光纤光栅FBG解调仪之间存在本质区别。分布式光纤测温DTS是一种完全分布式的温度监测技术&#xff0c;意味着光纤的整个长度都充当传感器&#xff0c;可以感知任何位置的温度变化。然而&#xff0c;由于空间分辨率的限制&#xff0c;目前国内外的大多数技术只…

Three.js中的Raycasting技术:实现3D场景交互事件的Raycaster详解

前言 在Web开发中&#xff0c;Three.js是一个极为强大的库&#xff0c;它让开发者能够轻松地在浏览器中创建和展示3D图形。随着3D技术在网页设计、游戏开发、数据可视化等领域的广泛应用&#xff0c;用户与3D场景的交互变得日益重要。而要实现这种交互&#xff0c;一个核心的技…

探索地产营销管理系统业务架构的设计与应用

随着城市化进程的加速和人们对居住环境需求的不断提升&#xff0c;地产行业正迎来前所未有的发展机遇和挑战。在这个背景下&#xff0c;地产营销管理系统作为地产开发企业营销管理的重要工具&#xff0c;扮演着至关重要的角色。本文将深入探讨地产营销管理系统业务架构的设计与…

java中的面试高频问题----2

一、进程、线程、协程有什么区别&#xff1f; 1.进程&#xff1a;进程是操作系统中独立运行的程序实例&#xff0c;每个进程都有自己的内存空间和系统资源&#xff1b;进程之间相互独立&#xff0c;每个进程有自己的内存地址空间&#xff0c;一个进程无法直接访问另一个进程的…

H3C运维工程师面经

H3C运维工程师面经 1、常用linux命令:top的作用1.1.系统监控与性能分析:1.2.进程管理:1.3.资源使用统计:1.4.自定义视图与交互操作:2、接触过的linux系统、小版本是多少?2.1CentOS的版本CentOS 8系列:CentOS 7系列:CentOS 6系列:2.2Ubuntu版本Ubuntu LTS版本:Ubuntu非…