一开始是看《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. Java集合:HashMap底层实现和原理(源码解析)

    Note:文章的内容基于JDK1.7进行分析.1.8做的改动文章末尾进行讲解. 一.先来熟悉一下我们常用的HashMap: 1.概述 HashMap基于Map接口实现,元素以键值对的方式存储,并且允许 ...

  2. MT【281】最大值函数

    已知正系数二次函数$ax^2+bx+c=0$有实数根,证明:$\max\{a,b,c\}\ge\dfrac{4}{9}(a+b+c)$ 证明:$\max\{a,b,c\}=\dfrac{a+c+|a- ...

  3. 洛谷P1258 小车问题(题解)

    https://www.luogu.org/problemnew/show/P1258(题目传送) 看题的第一眼就把题归为二分题,一直向着二分的方向走,却忽略了数学的推理.推理一番后(看了题解),发现 ...

  4. pytest 9 pytest-datadir读取文件信息

    安装:pip install pytest-datadir 介绍:用于操作测试数据目录和文件的插件.pytest-datadir他会寻找包含测试模块名字的文件夹或者全局的一个文件夹名字为data下的数 ...

  5. 【最强大的屏幕截图和标注工具】Snagit 2019.1 for Mac

    [简介] 今天和大家分享最新的 Snagit for Mac 2019.1 版本,这是Mac上最好用最强大的屏幕截图工具,Snagit功能非常强大,支持各种方式的屏幕截图,如全屏.滚动.部分.窗口.菜 ...

  6. Pandas系列(十)-转换连接详解

    目录 1. 拼接 1.1 append 1.2 concat 2. 关联 2.1 merge 2.2 join 数据准备 # 导入相关库 import numpy as np import panda ...

  7. apache中 sed 指定文件中某字符串增加行

    #!/bin/bash #在 servername 域名 字符串后面添加指定字符串 servername=`grep ServerName httpd-vhosts.conf |awk '{print ...

  8. stm32F10x复习-1

    地点:家 1.库文件说明 _htmresc: LOGO的设计图 Libraries: 源代码及启动文件 -- CoreSupport 核内设备函数层的CM3核通用的源文件.作用是为采用Cortex-M ...

  9. 第七节,Python的可视化包——matplotlib

    1.2D图表 import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt # 通过rcParams设置全局横 ...

  10. laravel5.4 导出 Excel 表格

    1.执行 composer require maatwebsite/excel 2. composer.json 文件出现(或者手动添加) 3.在config目录下 app.php 添加参数 4.导出 ...