手工实现灰度及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. 0.9.0.RELEASE版本的spring cloud alibaba nacos实例

    简而言之,nacos与eureka的不同之处有三:后台老板.部署方式.功能.nacos是阿里的,eureka是奈飞的:nacos有自己的安装包,需要独立部署,eureka仅作为一个服务组件,引入jar ...

  2. confluent kafka connect remote debugging

    1. Deep inside of kafka-connect start up To begin with, let's take a look at how kafka connect start ...

  3. 查看php 某个服务的进程数

    查看进程就是使用ps命令而已,只不顾ps的参数太多了. 使用php查询的话,必须要开启几个函数(可以执行外部程序的函数),参考官网:http://php.net/manual/zh/book.exec ...

  4. MySQL学习笔记——MySQL5.7的启动过程(一)

    MySQL的启动函数在 sql/main.cc 文件中. main.cc: extern int mysqld_main(int argc, char **argv); int main(int ar ...

  5. 转载【oracle切换表空间】

    http://blog.itpub.net/28939273/viewspace-1061476/ [root@yoon ~]# more /etc/oracle-releaseOracle Linu ...

  6. 最新 好未来java校招面经 (含整理过的面试题大全)

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

  7. 怎么让桌面存到d盘

    1.找到桌面文件夹. (C:\Users\Administrator) [C盘],[用户].[“”系统账号“(如Administrator)文件夹],[桌面] 2.打开桌面文件夹的属性. 查看位置,修 ...

  8. 编写python高质量python代码的59个有效方法

    第1条:确认自己的python版本 第2条:遵循PEP8的风格 1.空格 对于 占据多行的长表达式来说, 除了首行之外的其余各行都应该在通常的缩进级别上再加4个空格. 每行字符数不应该超过79. 2. ...

  9. js — 数组Array

    目录 1. isArray 2. 转换方法 3. 分割字符串 join 4. 栈方法 5. 队列方法 6. 重排序方法 7. 操作方法 8. 位置方法 - 索引 9. 迭代方法 数组 array 解释 ...

  10. java-TheadPoolExecutor

    Executor的两极调度模型 第一级:java多线程程序把应用分解为若干个任务,然后使用用户级的调度器(Executor框架)将这些任务映射为固定数量的线程: 第二级:操作系统内核将这些线程映射到处 ...