一开始是看《OpenCV计算机视觉编程攻略(第2版)》这本书学做直方图,但是书本里说直方图的部分只详细说了黑白图像(单通道)的直方图绘制方法,RGB图像的直方图只说了如何计算,没有说计算完之后如何绘制,自己想了很久也没想到正确的绘制方法。

去查OpenCV的官方文档,里面的例子只说了如何绘制H和S两通道的直方图,很多函数的用法也没搞清楚。

后来在网上看别人的程序,找到有绘制HSV三通道直方图的程序,花了一点时间一行一行地看,并且结合自己已经学过的知识把程序改成绘制RGB三通道的直方图的程序。

histogram.h:

#ifndef HISTOGRAM_H
#define HISTOGRAM_H #include <opencv2\opencv.hpp> #include <iostream>
#include <string> class Histogram
{
private:
int histSize[]; //直方图中箱子的数量
float hranges[]; //值范围
const float * ranges[]; //值范围的指针
int channels[]; //要检查的通道数量 public:
Histogram();
cv::Mat getHistogram(const cv::Mat & image);
std::vector<cv::Mat> getHistogramImage(const cv::Mat & image, int zoom = );
static std::vector<cv::Mat> getImageOfHistogram(const cv::Mat & hist, int zoom);
}; #endif

histogram.cpp:

#include "histogram.h"

Histogram::Histogram()
{
histSize[] = ;
histSize[] = ;
histSize[] = ;
hranges[] = 0.0;
hranges[] = 256.0;
ranges[] = hranges;
ranges[] = hranges;
ranges[] = hranges;
channels[] = ;
channels[] = ;
channels[] = ;
} cv::Mat Histogram::getHistogram(const cv::Mat & image)
{
cv::Mat hist; hranges[] = 0.0;
hranges[] = 256.0;
channels[] = ;
channels[] = ;
channels[] = ; cv::calcHist(&image, , channels, cv::Mat(), hist, , histSize, ranges); return hist;
} std::vector<cv::Mat> Histogram::getHistogramImage(const cv::Mat & image, int zoom)
{
cv::Mat hist = getHistogram(image); return Histogram::getImageOfHistogram(hist, zoom);
} std::vector<cv::Mat> Histogram::getImageOfHistogram(const cv::Mat & hist, int zoom)
{
int scale = ; float hist_b[];
float hist_g[];
float hist_r[];
memset(hist_b, , * sizeof(float));
memset(hist_g, , * sizeof(float));
memset(hist_r, , * sizeof(float)); //计算三个通道的直方图
for(int b = ; b < ; b ++ )
{
for(int g = ; g < ; g ++)
{
for(int r = ; r < ; r ++)
{
float binVal = hist.at<float>(b, g, r);
hist_b[b] += binVal;
hist_g[g] += binVal;
hist_r[r] += binVal;
}
}
} //获得三个通道直方图中的最大值
double max_b = 0.0, max_g = 0.0,max_r = 0.0;
for(int i = ; i < ; i ++)
{
if(hist_b[i] > max_b)
{
max_b = hist_b[i];
}
}
for(int i = ; i < ; i ++)
{
if(hist_g[i] > max_g)
{
max_g = hist_g[i];
}
}
for(int i = ; i < ; i ++)
{
if(hist_r[i] > max_r)
{
max_r = hist_r[i];
}
} //初始化空的图
cv::Mat b_img = cv::Mat::zeros(, * scale, CV_8UC3);
cv::Mat g_img = cv::Mat::zeros(, * scale, CV_8UC3);
cv::Mat r_img = cv::Mat::zeros(, * scale, CV_8UC3); //绘制三个通道的直方图
for(int i = ; i < ; i ++)
{
int intensity = cvRound(hist_b[i] * b_img.rows / max_b);
cv::rectangle(b_img, cv::Point(i * scale, b_img.rows - intensity), cv::Point((i + ) * scale - , b_img.rows - ), cv::Scalar(, ,), );
}
for(int i = ; i < ; i ++)
{
int intensity = cvRound(hist_g[i] * g_img.rows / max_g);
cv::rectangle(g_img, cv::Point(i * scale, g_img.rows - intensity), cv::Point((i + ) * scale - , g_img.rows - ), cv::Scalar(, , ), );
}
for(int i = ; i < ; i ++)
{
int intensity = cvRound(hist_r[i] * r_img.rows / max_r);
cv::rectangle(r_img, cv::Point(i * scale, r_img.rows - intensity), cv::Point((i + ) * scale - , r_img.rows - ), cv::Scalar(, , ), );
} std::vector<cv::Mat> imgs;
imgs.push_back(b_img);
imgs.push_back(g_img);
imgs.push_back(r_img); return imgs;
}

main.cpp:

#include <opencv2\opencv.hpp>

#include <iostream>
#include <string> #include "histogram.h" using namespace std; int main()
{
cv::Mat image = cv::imread("animal.jpg");
cv::imshow("image", image); Histogram h;
std::vector<cv::Mat> imgs = h.getHistogramImage(image); cv::namedWindow("B");
cv::imshow("B", imgs[]);
cv::namedWindow("G");
cv::imshow("G", imgs[]);
cv::namedWindow("R");
cv::imshow("R", imgs[]); cv::waitKey(); return ;
}

运行结果:

参考资料:

http://blog.csdn.net/ljbkiss/article/details/7420429

OpenCV绘制图像中RGB三个通道的直方图的更多相关文章

  1. Java基于opencv实现图像数字识别(三)—灰度化和二值化

    Java基于opencv实现图像数字识别(三)-灰度化和二值化 一.灰度化 灰度化:在RGB模型中,如果R=G=B时,则彩色表示灰度颜色,其中R=G=B的值叫灰度值:因此,灰度图像每个像素点只需一个字 ...

  2. C#使用OpenCV剪切图像中的圆形和矩形

    前言 本文主要介绍如何使用OpenCV剪切图像中的圆形和矩形. 准备工作 首先创建一个Wpf项目--WpfOpenCV,这里版本使用Framework4.7.2. 然后使用Nuget搜索[Emgu.C ...

  3. opencv 访问图像像素的三种方式

    访问图像中的像素 访问图像像素有三种可行的方法方法一:指针访问指针访问访问的速度最快,Mat类可以通过ptr函数得到图像任意一行的首地址,同时,Mat类的一些属性也可以用到公有属性 rows和cols ...

  4. (转)使用Python和OpenCV检测图像中的物体并将物体裁剪下来

    原文链接:https://blog.csdn.net/liqiancao/article/details/55670749 介绍 硕士阶段的毕设是关于昆虫图像分类的,代码写到一半,上周五导师又给我新的 ...

  5. opencv 替换图像中的一部分

    首先选取图像中的Roi区域,然后对Roi区域进行赋值,那么原图像相应的区域也跟着变化了: dst = src.clone(); cv::Mat Roi(dst, cv::Rect(x, y, cut_ ...

  6. opencv 5 图像转换(3 重映射 仿射变换 直方图均衡化)

    重映射 实现重映射(remap函数) 基础示例程序:基本重映射 //---------------------------------[头文件.命名空间包含部分]------------------- ...

  7. 利用OpenCV检测图像中的长方形画布或纸张并提取图像内容

    基于知乎上的一个答案.问题如下: 也就是在一张照片里,已知有个长方形的物体,但是经过了透视投影,已经不再是规则的长方形,那么如何提取这个图形里的内容呢?这是个很常见的场景,比如在博物馆里看到一幅很喜欢 ...

  8. OpenCV 绘制图像直方图

    OpenCV绘制图像直方图,版本2.4.11 直方图可展示图像中的像素分布,是用以表示数字图像中亮度分布的直方图,标绘了图像中每个亮度值的像素数.可以借助观察该直方图了解需要如何调整亮度分布.这种直方 ...

  9. 多通道(比方RGB三通道)卷积过程

    今天一个同学问 卷积过程好像是对 一个通道的图像进行卷积, 比方10个卷积核,得到10个feature map, 那么输入图像为RGB三个通道呢,输出就为 30个feature map 吗, 答案肯定 ...

随机推荐

  1. 【XSY3042】石像 拓扑排序 状压DP 洲阁筛

    题目大意 有 \(n\) 个整数 \(a_1,a_2,\ldots,a_n\),每个数的范围是 \([1,m]\).还有 \(k\) 个限制,每个限制 \(x_i,y_i\) 表示 \(a_{x_i} ...

  2. 【系统】libevent库学习

    Libevent库 是一个用C语言开发的.轻量级的开源高性能事件通知库,主要功能特点如下: 事件驱动(event-driven),高性能; 注册事件分优先级: 支持 I/O,定时器和信号等事件信息: ...

  3. css流式布局

    elem{ width:1160px;/*流式布局的总宽度*/ column-width:375px; -moz-column-width: 375px; /*每列宽度*/ -webkit-colum ...

  4. GDB使用记录

    ref:http://sunyongfeng.com/201506/programmer/tools/gdb.html 简介 GDB,GNU Debugger,特性如下: GDB具备各种调试功效,可对 ...

  5. Visual Studio图形调试器详细使用教程(基于DirectX11)

    前言 对于DirectX程序开发者来说,学会使用Visual Studio Graphics Debugger(图形调试器)可以帮助你全面了解渲染管线绑定的资源和运行状态,从而确认问题所在.现在就以我 ...

  6. [物理学与PDEs]第2章第1节 理想流体力学方程组 1.2 理想流体力学方程组

    1.  质量守恒定律: 连续性方程 $$\bee\label{2_1_2_zl} \cfrac{\p\rho}{\p t}+\Div(\rho{\bf u})=0.  \eee$$ 2.  动量守恒定 ...

  7. windows下 cmd 界面的替代者 cmder 推荐!

    介绍 http://cmder.net/ Portable console emulator for Windows Cmder is a software package created out o ...

  8. UE4材质特别属生记录

    tangent space normal 切线空间法线 材质默认使用的切线空间法线,可切换为对象空间法线(彩色贴图) Separate Translucency 单独半透明 允许半透明被渲染到一个单独 ...

  9. Python中__get__, __getattr__, __getattribute__的区别及延迟初始化

    本节知识点 1.__get__, __getattr__, __getattribute__的区别 2.__getattr__巧妙应用 3.延迟初始化(lazy property) 1.__get__ ...

  10. 《尚学堂_史上最易懂的设计模式视频》--章节3 Iterator迭代 模拟列表

    广州尚学堂官网-|广州Java培训|Java培训机构|人工智能+Python培训|PHP培训|全栈工程师培训|UI设计培训|前端移动开发培训http://www.gzsxt.cn/ ==Iterato ...