手工实现灰度及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. Django中验证码的登录

    需求概述 一般登录页面或者其他页面都需要验证码的功能,那在Django中如何实现呢? 这基本就需要用到第三方模块了:pillow 还需要两个文件,一个是字体文件:Monaco.ttf,另一个是一个模块 ...

  2. (一)深入java虚拟机之内存溢出与分析

    一.内存溢出程序 public class Test { public static void main(String[] args) { List<User> userList=new ...

  3. spark osx:WARN NativeCodeLoader:62 - Unable to load native-hadoop library for your platform

    spark-env.sh文件中增加,确保${HADOOP_HOME}/lib/native目录下有libhadoop.so文件 export JAVA_LIBRARY_PATH=${HADOOP_HO ...

  4. laravel门面DB返回数组配置

    在数据库配置文件中添加 'fetch' => PDO::FETCH_ASSOC, //但是这个配置好像是全局的,不能针对单个数据库连接进行配置 也可以在方法内使用php内置函数get_objec ...

  5. 【Leetcode_easy】594. Longest Harmonious Subsequence

    problem 594. Longest Harmonious Subsequence 最长和谐子序列 题意: 可以对数组进行排序,那么实际上只要找出来相差为1的两个数的总共出现个数就是一个和谐子序列 ...

  6. iOS-常见问题(错误和警告)

    1.storyboard连线问题    产生原因:将与storyboard关联的属性删除了,但是storyboard中还保持之前所关联的属性.    解决:取消关联就没事了.     2.XXXXX ...

  7. iOS-代理设计模式delegate和protocol

    充当代理的步骤: 首先要明确谁请别人代理,谁当别人的代理 1> 请代理三部曲: 1 写一个协议protoc,把自己不方便做的事列出来(@protocol  studentDelegate < ...

  8. 【Kail 学习笔记】自用KAIL更新源

    打开 /etc/apt/source.list 添加-保存即可 deb http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contr ...

  9. redis windows 扩展Redis igbinary 下载地址

    http://windows.php.net/downloads/pecl/releases/redis/3.1.2/ http://windows.php.net/downloads/pecl/re ...

  10. vue的依赖注入provide和inject

    一.解决的场景问题: 根父组件A有一个方法getMap,该组件A下的所有子组件B,子组件C,子组件D,或者子组件B下的子组件E等层层嵌套情况下,在某种情况下,都需要访问父组件的getMap方法,那么常 ...