opencv图像直方图
【欢迎关注编码小哥,学习更多实用的编程方法和技巧】
1、基本直方图计算
// 灰度图直方图
cv::Mat calculateGrayscaleHistogram(const cv::Mat& image) {cv::Mat histogram;int histSize = 256; // 灰度级别float range[] = {0, 256};const float* histRange = {range};cv::calcHist(&image, // 输入图像1, // 图像数量0, // 通道索引cv::Mat(), // 掩膜histogram, // 输出直方图1, // 直方图维度&histSize, // 直方图大小&histRange // 像素值范围);return histogram;
}// 彩色图直方图
std::vector<cv::Mat> calculateColorHistogram(const cv::Mat& image) {std::vector<cv::Mat> histograms(3);int histSize = 256;float range[] = {0, 256};const float* histRange = {range};// 分离通道std::vector<cv::Mat> channels;cv::split(image, channels);// 计算每个通道直方图for (int i = 0; i < 3; i++) {cv::calcHist(&channels[i], // 输入通道1, // 图像数量0, // 通道索引cv::Mat(), // 掩膜histograms[i], // 输出直方图1, // 直方图维度&histSize, // 直方图大小&histRange // 像素值范围);}return histograms;
}
2、直方图可视化
class HistogramVisualizer {
public:// 绘制直方图static cv::Mat drawHistogram(const cv::Mat& histogram, int height = 400) {// 归一化直方图cv::Mat normalizedHist;cv::normalize(histogram, normalizedHist, 0, height, cv::NORM_MINMAX);// 创建绘图画布int width = 512;cv::Mat histImage(height, width, CV_8UC3, cv::Scalar(255, 255, 255));// 绘制直方图int binWidth = cvRound((double)width / histogram.rows);for (int i = 1; i < histogram.rows; i++) {cv::line(histImage, cv::Point(binWidth * (i - 1), height - cvRound(normalizedHist.at<float>(i - 1))),cv::Point(binWidth * i, height - cvRound(normalizedHist.at<float>(i))),cv::Scalar(0, 0, 0), 2);}return histImage;}// 绘制彩色直方图static cv::Mat drawColorHistogram(const std::vector<cv::Mat>& histograms) {int height = 400;int width = 512;cv::Mat histImage(height, width, CV_8UC3, cv::Scalar(255, 255, 255));std::vector<cv::Scalar> colors = {cv::Scalar(255, 0, 0), // 蓝色cv::Scalar(0, 255, 0), // 绿色cv::Scalar(0, 0, 255) // 红色};// 归一化直方图std::vector<cv::Mat> normalizedHists(3);for (int i = 0; i < 3; i++) {cv::normalize(histograms[i], normalizedHists[i], 0, height, cv::NORM_MINMAX);}// 绘制直方图int binWidth = cvRound((double)width / histograms[0].rows);for (int i = 1; i < histograms[0].rows; i++) {for (int channel = 0; channel < 3; channel++) {cv::line(histImage, cv::Point(binWidth * (i - 1), height - cvRound(normalizedHists[channel].at<float>(i - 1))),cv::Point(binWidth * i, height - cvRound(normalizedHists[channel].at<float>(i))),colors[channel], 2);}}return histImage;}
};
3、直方图均衡化
class HistogramEqualizer {
public:// 灰度图均衡化static cv::Mat equalizeGrayscaleImage(const cv::Mat& image) {cv::Mat equalizedImage;cv::equalizeHist(image, equalizedImage);return equalizedImage;}// 彩色图均衡化static cv::Mat equalizeColorImage(const cv::Mat& image) {// 转换到YUV空间cv::Mat yuvImage;cv::cvtColor(image, yuvImage, cv::COLOR_BGR2YUV);// 分离通道std::vector<cv::Mat> channels;cv::split(yuvImage, channels);// 仅均衡化亮度通道cv::equalizeHist(channels[0], channels[0]);// 合并通道cv::merge(channels, yuvImage);// 转换回BGRcv::Mat equalizedImage;cv::cvtColor(yuvImage, equalizedImage, cv::COLOR_YUV2BGR);return equalizedImage;}// 自适应直方图均衡化(CLAHE)static cv::Mat adaptiveHistogramEqualization(const cv::Mat& image, double clipLimit = 2.0) {cv::Mat yuvImage;cv::cvtColor(image, yuvImage, cv::COLOR_BGR2YUV);std::vector<cv::Mat> channels;cv::split(yuvImage, channels);// 创建CLAHE对象cv::Ptr<cv::CLAHE> clahe = cv::createCLAHE(clipLimit, cv::Size(8, 8));clahe->apply(channels[0], channels[0]);cv::merge(channels, yuvImage);cv::Mat equalizedImage;cv::cvtColor(yuvImage, equalizedImage, cv::COLOR_YUV2BGR);return equalizedImage;}
};
4、直方图比较
class HistogramComparator {
public:// 直方图比较方法enum CompareMethod {CORRELATION = cv::HISTCMP_CORREL,CHI_SQUARE = cv::HISTCMP_CHISQR,INTERSECTION = cv::HISTCMP_INTERSECT,BHATTACHARYYA = cv::HISTCMP_BHATTACHARYYA};// 比较两个直方图static double compareHistograms(const cv::Mat& hist1, const cv::Mat& hist2, CompareMethod method = CORRELATION) {return cv::compareHist(hist1 , hist2, method);}
};// 使用示例
cv::Mat image1 = cv::imread("image1.jpg", cv::IMREAD_GRAYSCALE);
cv::Mat image2 = cv::imread("image2.jpg", cv::IMREAD_GRAYSCALE);cv::Mat hist1 = calculateGrayscaleHistogram(image1);
cv::Mat hist2 = calculateGrayscaleHistogram(image2);double similarity = HistogramComparator::compareHistograms(hist1, hist2, HistogramComparator::CORRELATION);
std::cout << "Histogram similarity: " << similarity << std::endl; ```cpp
// 重新合并通道
cv::Mat processedImage;
cv::merge(channels, processedImage);
return processedImage;
}// 使用示例
cv::Mat inputImage = cv::imread("input.jpg");
cv::Mat outputImage = processImageChannels(inputImage);// 显示结果
cv::imshow("Processed Image", outputImage);
cv::waitKey(0);
cv::destroyAllWindows();
``` ```cpp
// 重新合并通道
cv::Mat processedImage;
cv::merge(channels, processedImage);
return processedImage;
}// 使用示例
cv::Mat inputImage = cv::imread("input.jpg");
cv::Mat outputImage = processImageChannels(inputImage);// 显示结果
cv::imshow("Processed Image", outputImage);
cv::waitKey(0);
cv::destroyAllWindows();
}
相关文章:

opencv图像直方图
【欢迎关注编码小哥,学习更多实用的编程方法和技巧】 1、基本直方图计算 // 灰度图直方图 cv::Mat calculateGrayscaleHistogram(const cv::Mat& image) {cv::Mat histogram;int histSize 256; // 灰度级别float range[] {0, 256};const float* histRange …...

OpenCV计算机视觉 03 椒盐噪声的添加与常见的平滑处理方式(均值、方框、高斯、中值)
上一篇文章:OpenCV计算机视觉 02 图片修改 图像运算 边缘填充 阈值处理 目录 添加椒盐噪声 图像平滑常见处理方式 均值滤波 (blur) 方框滤波 (boxFilter) 高斯滤波 (GaussianBlur) 中值滤波 (medianBlur) 添加椒盐噪声 def add_peppersalt_noise(image, n…...

【嵌入式C语言】内存分布
内存分布 内存分布图内存的属性:只读空间只读空间的特点编程注意事项 栈空间栈的工作原理栈的特点栈溢出与堆的区别 堆空间堆的特点内存分配函数内存泄漏总结 内存分布图 内存的属性: 在C语言中,内存的属性主要取决于它是如何分配的以及它在…...

【brainpan靶场渗透】
文章目录 一、基础信息 二、信息收集 三、反弹shell 四、提权 一、基础信息 Kali IP:192.168.20.146 靶机 IP:192.168.20.155 二、信息收集 似乎开放了9999,10000端口,访问页面没有太多内容,扫描一下目录 dirs…...

Java实现观察者模式
一、前言 观察者模式,又称为发布订阅模式,是一种行为设置模式,允许对象之间建立一对多的依赖关系,这样当一个对象状态改变时,它的所有依赖者(观察者)都会收到通知并自动更新。 二、具体实现 …...

通过百度api处理交通数据
通过百度api处理交通数据 1、读取excel获取道路数据 //道路名称Data EqualsAndHashCode public class RoadName {ExcelProperty("Name")private String name; }/*** 获取excel中的道路名称*/private static List<String> getRoadName() {// 定义文件路径&…...

探索CSDN博客数据:使用Python爬虫技术
探索CSDN博客数据:使用Python爬虫技术 在数字化的浪潮中,数据的获取与分析变得日益关键。CSDN作为中国领先的IT社区和服务平台,汇聚了海量的技术博客与文章,成为一座蕴藏丰富的数据宝库。本文将引领您穿梭于Python的requests和py…...

b站ip属地评论和主页不一样怎么回事
在浏览B站时,细心的用户可能会发现一个有趣的现象:某些用户的评论IP属地与主页显示的IP属地并不一致。这种差异引发了用户的好奇和猜测,究竟是什么原因导致了这种情况的发生呢?本文将对此进行深入解析,帮助大家揭开这一…...

如何查看服务器内存占用情况?
如何查看服务器的内存占用情况?你知道内存使用情况对服务器性能的重要性吗?内存是服务器运行的核心资源之一,了解内存的占用情况可以帮助你优化系统性能。 要查看服务器的内存占用情况,首先需要确定你使用的是哪种操作系统。不同…...

流架构的读书笔记(2)
流架构的读书笔记(2) 一、建模工具之一沃德利地图 推测技术的发展,交流和辩论思想的最有力的方法是沃德利地图 沃德利地图的制作步骤 1确定范围和用户需求 2确定满足用户需求所需的组件 3在一条范围从全新到被人们接受的演进轴上评估这些组成 部分的演…...

E6 中的 扩展运算符(Spread) 和 剩余运算符(Rest)
时间:2024.12.29 之前看到 Es6 中的 三点运算符,有如下的几种写法,有时候三点运算符放在左边,有时候三点运算符放在右边,老是混淆。今天记录下,加强理解。 先看一个问题 最近在看 《ECMAScript 6 入门》关于…...

Python的简单爬虫框架
爬虫为网络爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、…...

使用 uni-app 开发的微信小程序中,如何在从 B 页面回来时,重新拉取数据?
👨🏻💻 热爱摄影的程序员 👨🏻🎨 喜欢编码的设计师 🧕🏻 擅长设计的剪辑师 🧑🏻🏫 一位高冷无情的全栈工程师 欢迎分享 / 收藏 / 赞 / 在看…...

Windows API Set:那些“只存在但不被使用“的DLL
API Set 是什么? 想象一下,Windows就像一个大型图书馆,而API Set就是这个图书馆的索引系统。但这个索引系统非常特别:它是直接内置在Windows加载器中的"虚拟目录"。 // 一个典型的API Set映射示例 api-ms-win-core-mem…...

黑神话悟空鼠标光标分享
效果图: 鼠标光标特点 这套鼠标光标的设计灵感来源于《黑神话:悟空》游戏中的角色和元素,具有以下特点: • 主题鲜明:光标设计紧扣游戏主题,采用了游戏中的元素,让玩家在使用电脑时也能感受到…...

编写一个简单的引导加载程序(bootloader)
编写一个简单的引导加载程序(bootloader)通常用于嵌入式系统或自定义操作系统。这里,我将为你提供一个基于x86架构的简单汇编语言 bootloader 示例。这个 bootloader 将会在启动时打印一条消息到屏幕上。 使用 NASM 汇编器来编写这个 bootlo…...

【Linux基础】进程(上) —— 概念、状态、优先级与环境变量
目录 一、进程的概念 1. 什么是进程 PCB进程控制块的理解 2. 查看进程的方式 ps ajx 指令 getpid系统调用 3. 另外一种查看进程的方式(了解) 4. 进程的常见调用 fork 创建子进程 现象说明 二、进程的状态 1. 操作系统层面的进程状态 ① 运行状态 ② 阻塞状态 ③…...

Rust: enum 和 i32 的区别和互换
在Rust编程语言中,enum(枚举)和i32是两种不同类型的数据结构,它们各自有不同的用途和特性。 i32 i32是一个32位的有符号整数类型。它用于存储整数值,范围从-2,147,483,648到2,147,483,647。i32是Rust中的基本数据类型…...

2024年终回顾
前言 很久没有更新博客,因为工作内容主要是内场开发,后来有点和互联网脱轨,断断续续上来看一下。这个总结应该也很简单,涉及以下的几个内容进行逐一说明 一、就业问题 这个问题可能很尖锐,从大环境来说,去…...

RGB、HSV颜色模型及MATLAB互换应用实例
一、前言 RGB和HSV模型是数字图像处理中颜色空间中的两种重要表示方式,RGB和HSV都是描述颜色的数学模型,可以用于表示和处理图像中的颜色信息。 RGB模型是一种基于光的颜色模型,由红(Red)、绿(Green&#x…...

# 【超全面了解鸿蒙生命周期】-生命周期补充
【超全面了解鸿蒙生命周期】-生命周期补充 鸿蒙所有的生命周期函数梳理 文章目录 【超全面了解鸿蒙生命周期】-生命周期补充前言一、AbilityStage的生命周期二、ExtensionAbility卡片生命周期三、Web组件常用生命周期 前言 本文是继之前写的生命周期函数梳理的进一步补充&…...

黑神话悟空游戏鼠标光标使用教程与下载
效果图: 鼠标光标特点 这套鼠标光标的设计灵感来源于《黑神话:悟空》游戏中的角色和元素,具有以下特点: • 主题鲜明:光标设计紧扣游戏主题,采用了游戏中的元素,让玩家在使用电脑时也能感受到…...

【机器学习】梯度下降
文章目录 1. 梯度下降概念2. 梯度下降的技巧2.1 动态设置学习率2.2 Adagrad调整梯度2.3 随机梯度下降(SGD)2.4 特征缩放 3. 梯度下降理论基础 1. 梯度下降概念 梯度:Loss 对参数在某一点的偏微分,函数沿梯度的方向具有最大的变化…...

【leetcode 07】707.设计链表
要点⭐ 链表的常见操作 获取第n个节点的值 头部插入节点 尾部插入节点 第n个节点前插入(先立新,在破旧) 删除第n个节点 class ListNode{int val;ListNode next;ListNode(){};ListNode(int val){this.valval;} } class MyLinkedList {//链表大…...

【Spring】详解(上)
Spring 框架核心原理与应用(上) 一、Spring 框架概述 (一)诞生背景 随着 Java 应用程序规模的不断扩大以及复杂度的日益提升,传统的 Java开发方式在对象管理、代码耦合度等方面面临诸多挑战。例如,对象之…...

短视频矩阵系统后端源码搭建实战与技术详解,支持OEM
一、引言 随着短视频行业的蓬勃发展,短视频矩阵系统成为了众多企业和创作者进行多平台内容运营的有力工具。后端作为整个系统的核心支撑,负责处理复杂的业务逻辑、数据存储与交互,其搭建的质量直接影响着系统的性能、稳定性和可扩展性。本文将…...

力扣每日刷题
24. 两两交换链表中的节点 - 力扣(LeetCode) 递归写法 做题思路:把需要交换的两个数的前一个数作为参数传入,然后使用一个变量保存这两个变量的后一个数,交换这个两个数,最后把第二个数(原第一…...

QT的信号和槽页面的应用
完善对话框,点击登录弹出对话框,如果账号和密码匹配,则弹出信息对话框,给出提示”登录成功“,提供一个Ok按钮,用户点击Ok后,关闭登录界面,跳转到其他界面 如果账号和密码不匹配&…...

【Java】线程相关面试题 (基础)
文章目录 线程与进程区别并行与并发区别解析概念含义资源利用执行方式应用场景 创建线程线程状态如何保证新建的三个线程按顺序执行wait方法和sleep方法的不同所属类和使用场景方法签名和参数说明调用wait方法的前提条件被唤醒的方式与notify/notifyAll方法的协作使用示例注意事…...

【数字化】华为一体四面细化架构蓝图
导读:华为的“一体四面”企业架构设计方法是一种综合性的管理框架,它通过业务架构、信息架构、应用架构和技术架构的集成设计,构建出一个既符合业务需求,又具备高度灵活性和可扩展性的IT系统。这种架构设计方法强调从业务视角出发…...