手工实现灰度及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直方图的更多相关文章

  1. OpenCV Python教程(3、直方图的计算与显示)

    转载请详细注明原作者及出处,谢谢! 本篇文章介绍如何用OpenCV Python来计算直方图,并简略介绍用NumPy和Matplotlib计算和绘制直方图 直方图的背景知识.用途什么的就直接略过去了. ...

  2. Python+OpenCV图像处理(八)—— 图像直方图

    直方图简介:图像的直方图是用来表现图像中亮度分布的直方图,给出的是图像中某个亮度或者某个范围亮度下共有几个像素.还不明白?就是统计一幅图某个亮度像素数量.比如对于灰度值12,一幅图里面有2000 个像 ...

  3. opencv学习笔记(六)直方图比较图片相似度

    opencv学习笔记(六)直方图比较图片相似度 opencv提供了API来比较图片的相似程度,使我们很简单的就能对2个图片进行比较,这就是直方图的比较,直方图英文是histogram, 原理就是就是将 ...

  4. OpenCV成长之路:图像直方图的应用

    OpenCV成长之路:图像直方图的应用 2014-04-11 13:57:03 标签:opencv 图像 直方图 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否 ...

  5. opencv手工编译

    opencv手工编译方法1.下载cmake gui2.在where is the source code路径下配置opencv根目录,在where to build the binaries路径下配置 ...

  6. OpenCV编程->RGB直方图统计

      我们在处理彩色图像时.特别是在做局部图像的阈值切割时,须要一个直观的RGB统计图.   接下来開始实现.    代码: void CalcHistRGB() { IplImage* img_sou ...

  7. opencv——图像的灰度处理(线性变换/拉伸/直方图/均衡化)

    实验内容及实验原理: 1.灰度的线性变换 灰度的线性变换就是将图像中所有的点的灰度按照线性灰度变换函数进行变换.该线性灰度变换函数是一个一维线性函数:f(x)=a*x+b 其中参数a为线性函数的斜率, ...

  8. java+opencv实现图像灰度化

    灰度图像上每个像素的颜色值又称为灰度,指黑白图像中点的颜色深度,范围一般从0到255,白色为255,黑色为0.所谓灰度值是指色彩的浓淡程度,灰度直方图是指一幅数字图像中,对应每一个灰度值统计出具有该灰 ...

  9. OpenCV成长之路:图像直方图

    http://ronny.blog.51cto.com/8801997/1394115 2014-04-11 13:47:27 标签:opencv 直方图 统计表 原创作品,允许转载,转载时请务必以超 ...

随机推荐

  1. LeetCode_70. Climbing Stairs

    70. Climbing Stairs Easy You are climbing a stair case. It takes n steps to reach to the top. Each t ...

  2. ElasticSearch——冷热(hot&warm)架构部署

    背景 最近在做订单数据存储到ElasticSearch,考虑到数据量比较大,采用冷热架构来存储,每月建立一个新索引,数据先写入到热索引,通过工具将3个月后的索引自动迁移到冷节点上. ElasticSe ...

  3. pycurl模块

    pycurl的使用 pycurl是curl的一个python版本. pycurl的使用说明: pycurl的使用主要是一些参数的设定. 1,c.setopt(pycurl.URL,myurl) 设定链 ...

  4. ELK之在CentOS7.5上使用rpm包安装配置ELK7版本

    一,安装环境查看 二,软件版本选用 jdk 1.8.0_171 elasticsearch 7.1.1 kibana 7.1.1 logstash 7.1.1 三,安装配置 1,安装JDK 过程不详述 ...

  5. 最新 网易java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易.京东.去哪儿等10家互联网公司的校招Offer,因为某些自身原因最终选择了网易.6.7月主要是做系统复习.项目复盘.LeetCode与牛客刷题 ...

  6. input文本框禁用历史选择

    这里常用的场景是日期控件使用时,下面这个就很难看了 在input中添加autocomplete="off"就可以了 <input type="text" ...

  7. 如何查看USB是不是3.0版本

    打开设备管理器 找到>便携设备 对应U盘,打开属性>查看详细信息>如果设备描述为Data Traveler 3.0 那么这就是3.0的U盘

  8. 登陆Linux服务器时触发邮件提醒

    目前,客户只能在发现数据或者虚拟机被恶意侵入或者用户的误操作导致了数据的丢失之后,采取善后的手段,但是并没法做到提前的预警.那么通过 PAM 模块,就可以实现用户登录及获取root 权限时,通过邮件的 ...

  9. 5年经验Java程序员面试20天

      写在前面 今天分享的是一位5年工作经验的Java工程师在帝都的面试经验总结,看看这些互联网公司都爱问些什么题,希望对大家的面试有指导意义. 从事Java开发也有5年经验了,4月初自己的开启面试经历 ...

  10. 精选实用 Chrome 扩展(20)

    ● Reading List 简介:收藏网页,稍后阅读 ● OneTab 简介:收起当前已打开的标签页,需要的时候恢复 ● IE Tab 简介:网页用IE打开 ● uBlock Origin ● Pe ...