OpenCV手工实现灰度及RGB直方图
手工实现灰度及RGB直方图 !库
1. 灰度图像直方图
算法
1. 图片灰度化;
2. 遍历Mat,统计各灰度级的像素个数;
3. 根据opencv画点线函数,绘制坐标轴及像素分布图
源码(编译环境:VS2017+OpenCV) 补充:三通道直方图(即RGB彩色图象直方图在后面)
#include <iostream>
#include <string>
#include <algorithm>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
//直方图绘制函数,参数vector<int> nums 是灰度图片256级灰度的像素个数
void drawHist(vector<int> nums)
{
Mat hist = Mat::zeros(, , CV_8UC3);
auto Max = max_element(nums.begin(), nums.end());//max迭代器类型,最大数目
putText(hist, "Histogram", Point(, ), FONT_HERSHEY_DUPLEX, , Scalar(, , ));
//*********绘制坐标系************//
Point o = Point(, );
Point x = Point(, );
Point y = Point(, );
//x轴
line(hist, o, x, Scalar(, , ), , , );
//y轴
line(hist, o, y, Scalar(, , ), , , ); //********绘制灰度曲线***********//
Point pts[];
//生成坐标点
for (int i = ; i < ; i++)
{
pts[i].x = i * + ;
pts[i].y = - int(nums[i]*(300.0/(*Max)));//归一化到[0, 300]
//显示横坐标
if ((i + ) % == )
{
string num = format("%d", i + );
putText(hist, num, Point(pts[i].x, ), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(, , ));
}
}
//绘制线
for (int i = ; i < ; i++)
{
line(hist, pts[i - ], pts[i], Scalar(, , ), );
}
//显示图像
imshow("直方图" ,hist);
}
//计算直方图,统计各灰度级像素个数
void calHist(const string img)
{
Mat src, grey;
//读取图象
src = imread(img);
if (!src.data)
{
cout << "Image: " + img + " 读取失败" << endl;
return;
}
//先转为灰度图
cvtColor(src, grey, COLOR_BGR2GRAY);
imshow("灰度图", grey);
//计算各灰度级像素个数
vector<int> nums();
for (int i = ; i < grey.rows; i++)
{
uchar* p = grey.ptr<uchar>(i);
for (int j = ; j < grey.cols; j++)
{
nums[p[j]]++;
}
}
drawHist(nums);
} int main()
{
string img = "D:\\trashBox\\testIMG\\lena.bmp";
calHist(img); waitKey();
return ;
}
效果图
直方图hist
2. RGB彩色图象直方图
源码
#include <iostream>
#include <stdlib.h>
#include <string>
#include <algorithm>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/video.hpp>
using namespace cv;
using namespace std; //单通道图片直方图绘制
void drawHist(vector<int> nums)
{
Mat hist = Mat::zeros(, , CV_8UC3);
auto Max = max_element(nums.begin(), nums.end());//max迭代器类型,最大数目
putText(hist, "Histogram", Point(, ), FONT_HERSHEY_DUPLEX, , Scalar(, , ));
//*********绘制坐标系************//
Point o = Point(, );
Point x = Point(, );
Point y = Point(, );
//x轴
line(hist, o, x, Scalar(, , ), , , );
//y轴
line(hist, o, y, Scalar(, , ), , , ); //********绘制灰度曲线***********//
Point pts[];
//生成坐标点
for (int i = ; i < ; i++)
{
pts[i].x = i * + ;
pts[i].y = - int(nums[i]*(300.0/(*Max)));//归一化到[0, 300]
//显示横坐标
if ((i + ) % == )
{
string num = format("%d", i + );
putText(hist, num, Point(pts[i].x, ), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(, , ));
}
}
//绘制线
for (int i = ; i < ; i++)
{
line(hist, pts[i - ], pts[i], Scalar(, , ), );
}
//显示图像
imshow("直方图" ,hist);
} //三通道图片直方图绘制
void drawHist(vector<int> &r, vector<int> &g, vector<int> &b)
{
Mat hist = Mat::zeros(, , CV_8UC3);
putText(hist, "Histogram", Point(, ), FONT_HERSHEY_DUPLEX, , Scalar(, , ));
//*********绘制坐标系************//
Point o = Point(, );
Point x = Point(, );
Point y = Point(, );
//x轴
line(hist, o, x, Scalar(, , ), , , );
//y轴
line(hist, o, y, Scalar(, , ), , , ); //********绘制灰度曲线***********//
auto Max_r = max_element(r.begin(), r.end());
auto Max_g = max_element(g.begin(), g.end());
auto Max_b = max_element(b.begin(), b.end());
Point pts[][];
//生成坐标点
for (int i = ; i < ; i++)
{
pts[][i].x = i * + ;
pts[][i].y = - int(r[i] * (300.0 / (*Max_r)));//归一化到[0, 300]
pts[][i].x = i * + ;
pts[][i].y = - int(g[i] * (300.0 / (*Max_g)));//归一化到[0, 300]
pts[][i].x = i * + ;
pts[][i].y = - int(b[i] * (300.0 / (*Max_b)));//归一化到[0, 300]
//显示横坐标
if ((i + ) % == )
{
string num = format("%d", i + );
putText(hist, num, Point(pts[][i].x, ), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(, , ));
}
}
//绘制线
for (int i = ; i < ; i++)
{
line(hist, pts[][i - ], pts[][i], Scalar(, , ), );
line(hist, pts[][i - ], pts[][i], Scalar(, , ), );
line(hist, pts[][i - ], pts[][i], Scalar(, , ), );
}
//显示图像
imshow("直方图", hist);
} //灰度直方图计算
void calHist(const string img)
{
Mat src, grey;
//读取图象
src = imread(img);
if (!src.data)
{
cout << "Image: " + img + " 读取失败" << endl;
return;
}
//先转为灰度图
cvtColor(src, grey, COLOR_BGR2GRAY);
imshow("灰度图", grey);
//计算各灰度级像素个数
vector<int> nums();
for (int i = ; i < grey.rows; i++)
{
uchar* p = grey.ptr<uchar>(i);
for (int j = ; j < grey.cols; j++)
{
nums[p[j]]++;
}
}
drawHist(nums);
} //多通道直方图计算
void calHist(const string img, int pattern)
{
Mat src, grey;
//读取图象
src = imread(img);
if (!src.data)
{
cout << "Image: " + img + " 读取失败" << endl;
return;
}
imshow("原图像",src);
//计算各灰度级像素个数
vector<int> r(, );
vector<int> g(, );
vector<int> b(, );
for (int i = ; i < src.rows; i++)
{
uchar* p = src.ptr<uchar>(i);
for (int j = ; j < src.cols; j++)
{
r[p[j * + ]]++;
g[p[j * + ]]++;
b[p[j * + ]]++;
}
}
drawHist(r, g, b);
} int main()
{
string img = "D:\\trashBox\\testIMG\\tiger.jpg";
calHist(img);//计算灰度直方图
calHist(img, );//计算三色直方图 waitKey();
return ;
}
算法
1. 遍历Mat,统计RGB三通道各灰度级的像素个数;
2. 根据opencv画点线函数,绘制坐标轴及像素分布图
效果
三色(三通道)直方图
OpenCV手工实现灰度及RGB直方图的更多相关文章
- OpenCV Python教程(3、直方图的计算与显示)
转载请详细注明原作者及出处,谢谢! 本篇文章介绍如何用OpenCV Python来计算直方图,并简略介绍用NumPy和Matplotlib计算和绘制直方图 直方图的背景知识.用途什么的就直接略过去了. ...
- Python+OpenCV图像处理(八)—— 图像直方图
直方图简介:图像的直方图是用来表现图像中亮度分布的直方图,给出的是图像中某个亮度或者某个范围亮度下共有几个像素.还不明白?就是统计一幅图某个亮度像素数量.比如对于灰度值12,一幅图里面有2000 个像 ...
- opencv学习笔记(六)直方图比较图片相似度
opencv学习笔记(六)直方图比较图片相似度 opencv提供了API来比较图片的相似程度,使我们很简单的就能对2个图片进行比较,这就是直方图的比较,直方图英文是histogram, 原理就是就是将 ...
- OpenCV成长之路:图像直方图的应用
OpenCV成长之路:图像直方图的应用 2014-04-11 13:57:03 标签:opencv 图像 直方图 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否 ...
- opencv手工编译
opencv手工编译方法1.下载cmake gui2.在where is the source code路径下配置opencv根目录,在where to build the binaries路径下配置 ...
- OpenCV编程->RGB直方图统计
我们在处理彩色图像时.特别是在做局部图像的阈值切割时,须要一个直观的RGB统计图. 接下来開始实现. 代码: void CalcHistRGB() { IplImage* img_sou ...
- opencv——图像的灰度处理(线性变换/拉伸/直方图/均衡化)
实验内容及实验原理: 1.灰度的线性变换 灰度的线性变换就是将图像中所有的点的灰度按照线性灰度变换函数进行变换.该线性灰度变换函数是一个一维线性函数:f(x)=a*x+b 其中参数a为线性函数的斜率, ...
- java+opencv实现图像灰度化
灰度图像上每个像素的颜色值又称为灰度,指黑白图像中点的颜色深度,范围一般从0到255,白色为255,黑色为0.所谓灰度值是指色彩的浓淡程度,灰度直方图是指一幅数字图像中,对应每一个灰度值统计出具有该灰 ...
- OpenCV成长之路:图像直方图
http://ronny.blog.51cto.com/8801997/1394115 2014-04-11 13:47:27 标签:opencv 直方图 统计表 原创作品,允许转载,转载时请务必以超 ...
随机推荐
- 使用python3脚本部署mariadb主从架构
环境准备 一个脚本自动部署master服务 另一个部署slave服务 关闭主从节点的防火墙 以及事先设置好root远程登陆的权限. master import paramikossh=paramiko ...
- CentOS7下搭建zabbix监控(三)——Zabbix监控服务配置
CentOS7下搭建zabbix监控(一)——Zabbix监控端配置 CentOS7下搭建zabbix监控(二)——Zabbix被监控端配置 (1).配置Zabbix监控Apache服务 主机名:yo ...
- PAT 甲级 1038 Recover the Smallest Number (30 分)(思维题,贪心)
1038 Recover the Smallest Number (30 分) Given a collection of number segments, you are supposed to ...
- Delphi ADOQuery的速度优化
今天终于把纠缠了几天的问题改完了,说到底只是一个很小的问题,就是ADOQuery的一个小属性. 把控件DBGridEh的一列的checkbox设为true,将其绑定DataSource和ADOQuer ...
- 浅谈Delphi高效使用TreeView
本来我一直都是使用递归算法, 效率很低 下边这段代码是我原来写的 ------------------------------------------------------------------- ...
- css调用字体 没装微软雅黑,用css写@font-face让其能显示微软雅黑字体
在设计布局网页时 经常想要用一些比较好看的字体,比如微软雅黑,这个字体在近年来在网页设计中运用越来越平常, 然而所使用的字体也只有自己能看到 到别的机子上 又恢复了原来的宋体神马的. 经过一位高手的提 ...
- Linux - Linux命令行常用快捷键
Common Shortcut Key 用途 快捷键 说明 光标移动 Ctrl + a 把光标移到行首 Ctrl + e 把光标移到行尾 Ctrl + x 在 EOL 和当前位置移动光标 输入编辑 C ...
- 超详细的RNN代码实现(tensorflow)
一.学习单步的RNN:RNNCell 如果要学习TensorFlow中的RNN,第一站应该就是去了解“RNNCell”,它是TensorFlow中实现RNN的基本单元,每个RNNCell都有一个cal ...
- Django:reverse反转URL并传递参数
需求: 假设在文章详情页评论文章后需要重新刷新显示该页面(原始方法,提交评论表单为form方式,未采用ajax方式), 提交评论后代码会走comment的视图函数,等数据入库之后需要将页面重新定位到文 ...
- Docker 镜像的推送(六)
目录 一.为镜像命名 二.推送到官方 Docker Hub 1.首先得在 Docker Hub 上注册一个账号. 2.在 Docker Host 上登录 3.修改镜像命名 4.镜像上传 5.登录查看上 ...