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

openCV1-2 图像的直方图相关

通道合并与分离

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{Mat src = imread("D:\\souse\\opencv_tutorial_data-master\\images\\WindowsLogo.jpg");if (src.empty()) {return -1;}namedWindow("input", WINDOW_AUTOSIZE);imshow("input", src);vector<Mat> mv;//分离split(src, mv);imshow("input1", mv.at(0));imshow("input2", mv.at(1));imshow("input3", mv.at(2));Mat des;mv.at(0) = Scalar(0);//合并操作merge(mv, des);imshow("des",des);waitKey(0);std::cout << "Hello World!\n";return 0;
}

图像直方图统计

在这里插入图片描述
Bin:是直方图的基本统计单元,用于统计图像中特定范围内像素值的出现频率。

calcHist

CV_EXPORTS void calcHist( const Mat* images, int nimages,const int* channels, InputArray mask,OutputArray hist, int dims, const int* histSize,const float** ranges,bool uniform = true, bool accumulate = false );

函数cv::calcHist用于计算一个或多个数组的直方图。用于增加直方图 bin 的元组元素取自相应输入数组中相同位置的元素。下面的示例展示了如何为彩色图像计算二维色调 - 饱和度直方图:
@include snippets/imgproc_calcHist.cpp

@param images 源数组。它们都应该具有相同的深度,即CV_8U、CV_16U或CV_32F ,并且大小相同。每个数组可以有任意数量的通道。
@param nimages 源图像的数量。
@param channels 用于计算直方图的维度通道列表。第一个数组的通道从0到images[0].channels() - 1编号,第二个数组的通道从images[0].channels()到images[0].channels() + images[1].channels() - 1编号,依此类推。
@param mask 可选掩码。如果该矩阵不为空,它必须是与images[i]大小相同的8位数组。非零掩码元素标记在直方图中统计的数组元素。
@param hist 输出直方图,它是一个密集或稀疏的dims维数组。
@param dims 直方图维度,必须为正且不大于CV_MAX_DIMS(在当前OpenCV版本中等于32)。
@param histSize 每个维度的直方图大小数组。
@param ranges 每个维度的直方图 bin 边界的dims个数组的数组。
@param uniform 指示直方图是否均匀的标志。
@param accumulate 累加标志。如果设置了该标志,在分配直方图时,开始时不会将其清空。此功能使您能够从几组数组中计算单个直方图,或者及时更新直方图。

normalize

cv::normalize() 是 OpenCV 中用于归一化数组元素的函数,它可以将数组的值缩放到指定范围。以下是对该函数的详细解析:

void cv::normalize(InputArray src,            // 输入数组(如Mat)InputOutputArray dst,      // 输出数组(可与src相同,实现原地操作)double alpha = 1,          // 归一化后的最小值(或范数值,取决于norm_type)double beta = 0,           // 归一化后的最大值(仅用于NORM_MINMAX)int norm_type = NORM_L2,   // 归一化类型(如NORM_MINMAX、NORM_L1、NORM_L2等)int dtype = -1,            // 输出数组的类型(-1表示与输入相同)InputArray mask = noArray() // 可选掩码,非零元素参与计算
);

参数详解
src 输入数组(如直方图数据 b),通常是 Mat 类型。
dst 输出数组,可与 src 相同(原地操作)。若不同,需保证尺寸和通道数一致。
alpha 对于 NORM_MINMAX:归一化后的最小值。
对于其他归一化类型(如 NORM_L2):目标范数值。
beta 仅用于 NORM_MINMAX,表示归一化后的最大值。
norm_type 常用取值:
NORM_MINMAX:线性映射到 [alpha, beta] 范围。
NORM_L1:L1 范数(绝对值之和)归一化。
NORM_L2:L2 范数(欧几里得距离)归一化。
NORM_INF:无穷范数(最大值)归一化。
dtype
输出数组的类型。-1 表示与输入类型相同。
mask
可选掩码,仅掩码中非零元素参与计算。

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{Mat src = imread("D:\\souse\\opencv_tutorial_data-master\\images\\sp_noise.png");if (src.empty()) {cout << "读取失败"<<endl;return -1;}namedWindow("src", WINDOW_AUTOSIZE);imshow("src", src);//分离通道vector<Mat> mv;split(src, mv);//计算直方图int histSize=256;float range[] = { 0,255 };const float* hisRanges = range;Mat b, g, r;//原图像 原图像数量 通道 掩码 输出 维度  每个维度的bin数量  每个维度的取值范围 bin是否均匀分布 是否累积计算calcHist(&mv[0],1,0,Mat(),b,1,&histSize, &hisRanges);calcHist(&mv[1], 1, 0, Mat(), g, 1, &histSize, &hisRanges);calcHist(&mv[2], 1, 0, Mat(), r, 1, &histSize, &hisRanges);//绘制直方图Mat result= Mat::zeros(Size(600, 500), CV_8UC3);int margin = 50;//边缘大小int h = result.rows-2*margin;//最大高normalize(b, b, 0, h, NORM_MINMAX, -1, Mat());normalize(g, g, 0, h, NORM_MINMAX, -1, Mat());normalize(r, r, 0, h, NORM_MINMAX, -1, Mat());float step = 500.0 / 256;for (int i = 0; i < 255; i++) {// 绘制蓝色通道line(result,Point(step * i+50, 50 + h - b.at<float>(i, 0)),Point(step * (i + 1)+50, 50 + h - b.at<float>(i + 1, 0)),Scalar(255, 0, 0), 2, 8, 0);// 修复:添加绿色和红色通道的绘制(颜色参数修正)line(result,Point(step * i+50, 50 + h - g.at<float>(i, 0)),Point(step * (i + 1)+50, 50 + h - g.at<float>(i + 1, 0)),Scalar(0, 255, 0), 2, 8, 0);  // 绿色:(0,255,0)line(result,Point(step * i+50, 50 + h - r.at<float>(i, 0)),Point(step * (i + 1)+50, 50 + h - r.at<float>(i + 1, 0)),Scalar(0, 0, 255), 2, 8, 0);  // 红色:(0,0,255)}imshow("result", result);waitKey(0);
}

在这里插入图片描述

图像直方图均衡化

blog.csdnimg.cn/direct/9e84666228f141ea877bfe614947d21a.png)

#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{Mat src = imread("D:\\souse\\opencv_tutorial_data-master\\images\\age_gender.jpg");if (src.empty()) {cout << "读取失败" << endl;return -1;}namedWindow("src", WINDOW_AUTOSIZE);imshow("src", src);//=========================////转灰度图像Mat gray, des;cvtColor(src, gray, COLOR_BGR2GRAY);imshow("gray", gray);//均衡化equalizeHist(gray, des);imshow("des", des);//=========================////分离通道vector<Mat> mv;split(src, mv);//计算直方图int histSize = 256;float range[] = { 0,255 };const float* hisRanges = range;Mat b, g, r,g_z,d_z;//原图像 原图像数量 通道 掩码 输出 维度  每个维度的bin数量  每个维度的取值范围 bin是否均匀分布 是否累积计算calcHist(&mv[0], 1, 0, Mat(), b, 1, &histSize, &hisRanges);calcHist(&mv[1], 1, 0, Mat(), g, 1, &histSize, &hisRanges);calcHist(&mv[2], 1, 0, Mat(), r, 1, &histSize, &hisRanges);calcHist(&gray, 1, 0, Mat(), g_z, 1, &histSize, &hisRanges);calcHist(&des, 1, 0, Mat(), d_z, 1, &histSize, &hisRanges);//绘制直方图Mat result = Mat::zeros(Size(600, 500), CV_8UC3);Mat result1 = Mat::zeros(Size(600, 500), CV_8UC3);int margin = 50;//边缘大小int h = result.rows - 2 * margin;//最大高normalize(b, b, 0, h, NORM_MINMAX, -1, Mat());normalize(g, g, 0, h, NORM_MINMAX, -1, Mat());normalize(r, r, 0, h, NORM_MINMAX, -1, Mat());normalize(g_z, g_z, 0, h, NORM_MINMAX, -1, Mat());normalize(d_z, d_z, 0, h, NORM_MINMAX, -1, Mat());float step = 500.0 / 256;for (int i = 0; i < 255; i++) {// 绘制蓝色通道line(result,Point(step * i + 50, 50 + h - b.at<float>(i, 0)),Point(step * (i + 1) + 50, 50 + h - b.at<float>(i + 1, 0)),Scalar(255, 0, 0), 2, 8, 0);// 修复:添加绿色和红色通道的绘制(颜色参数修正)line(result,Point(step * i + 50, 50 + h - g.at<float>(i, 0)),Point(step * (i + 1) + 50, 50 + h - g.at<float>(i + 1, 0)),Scalar(0, 255, 0), 2, 8, 0);  // 绿色:(0,255,0)line(result,Point(step * i + 50, 50 + h - r.at<float>(i, 0)),Point(step * (i + 1) + 50, 50 + h - r.at<float>(i + 1, 0)),Scalar(0, 0, 255), 2, 8, 0);  // 红色:(0,0,255)line(result1,Point(step * i + 50, 50 + h - g_z.at<float>(i, 0)),Point(step * (i + 1) + 50, 50 + h - g_z.at<float>(i + 1, 0)),Scalar(0, 0, 255), 2, 8, 0);  // 红色:(0,0,255)line(result1,Point(step * i + 50, 50 + h - d_z.at<float>(i, 0)),Point(step * (i + 1) + 50, 50 + h - d_z.at<float>(i + 1, 0)),Scalar(0, 255, 0), 2, 8, 0);  // 红色:(0,0,255)}imshow("result", result);imshow("result1", result1);waitKey(0);}

绿色是灰度图,红色是均衡化处理之后的
在这里插入图片描述

相关文章:

  • Ubuntu更新源服务器时出现:pk-client-error-quark
  • OBS VLC 不显示
  • 高速信号处理中的去加重、预加重与均衡技术
  • Eigen矩阵存储顺序以及转换
  • Scrapy爬取heima论坛所有页面内容并保存到MySQL数据库中
  • 智能IoT未来与边缘生态共建 | 2025 高通边缘智能创新应用大赛第六场公开课来袭!
  • SIL2/PLd 认证 Inxpect毫米波安全雷达:3D 扫描 + 微小运动检测守护工业安全
  • 中国核电信息技术峰会|麒麟信安锻造电力“数智基座“,护航核电安全新生态
  • Java求职面经分享:Spring Boot到微服务,从理论到实践
  • Even Split_CodeForces - 1666E分析与解答
  • 使用docker compose部署dify(大模型开发使用平台)
  • 通过现代数学语言重构《道德经》核心概念体系,形成一个兼具形式化与启发性的理论框架
  • 如何在 FastAPI 中合理使用 Pydantic 的 Alias
  • Python安全密码生成器:告别弱密码的最佳实践
  • 【笔试强训day39】
  • vector
  • unittest
  • 腾讯2025年校招笔试真题手撕(一)
  • 嵌入式学习笔记 - 关于ARM编辑器compiler version 5 and compiler version 6
  • Facebook广告如何投放保健品类别?
  • 公司网站方案/seo网站诊断分析报告
  • 网站备案填写要求吗/四年级下册数学优化设计答案
  • 网站代码怎么做/今日新闻头条内容
  • 图书翻页的动画 做网站启动用/站长工具网站查询
  • 提供常州网站建设/没被屏蔽的国外新闻网站
  • 合肥有多少建网站公司/谷歌浏览器手机版