您的位置:首页 > 运维架构

opencv3 绘制BGR三色直方图

2015-11-05 22:44 330 查看
#include<opencv2/opencv.hpp>
#include<iostream>
#include<vector>

using namespace cv;
using namespace std;

int main()
{
Mat srcImage = imread("1.jpg");
imshow("【原图】", srcImage);

//为计算直方图配置变量
//首先是需要计算的图像的通道,就是需要计算图像的哪个通道(bgr空间需要确定计算 b或g货r空间)
int channels = 0;
//然后是配置输出的结果存储的 空间 ,用MatND类型来存储结果
MatND dstHist;
//接下来是直方图的每一个维度的 柱条的数目(就是将数值分组,共有多少组)
int histSize[] = { 256 };		//如果这里写成int histSize = 256;   那么下面调用计算直方图的函数的时候,该变量需要写 &histSize
//最后是确定每个维度的取值范围,就是横坐标的总数
//首先得定义一个变量用来存储 单个维度的 数值的取值范围
float midRanges[] = { 0, 256 };
const float *ranges[] = { midRanges };

calcHist(&srcImage, 1, &channels, Mat(), dstHist, 1, histSize, ranges, true, false);

//calcHist  函数调用结束后,dstHist变量中将储存了 直方图的信息  用dstHist的模版函数 at<Type>(i)得到第i个柱条的值
//at<Type>(i, j)得到第i个并且第j个柱条的值

//开始直观的显示直方图——绘制直方图
//首先先创建一个黑底的图像,为了可以显示彩色,所以该绘制图像是一个8位的3通道图像
Mat b_drawImage = Mat::zeros(Size(256, 256), CV_8UC3);
//因为任何一个图像的某个像素的总个数,都有可能会有很多,会超出所定义的图像的尺寸,针对这种情况,先对个数进行范围的限制
//先用 minMaxLoc函数来得到计算直方图后的像素的最大个数
double g_dHistMaxValue = 0;
minMaxLoc(dstHist, 0, &g_dHistMaxValue, 0, 0);
//将像素的个数整合到 图像的最大范围内
//遍历直方图得到的数据
for (int i = 0; i < 256; i++)
{
int value = cvRound(dstHist.at<float>(i) * 256 * 0.9 / g_dHistMaxValue);

line(b_drawImage, Point(i, b_drawImage.rows - 1), Point(i, b_drawImage.rows - 1 - value), Scalar(255, 0, 0));
}

imshow("【蓝色通道的直方图】", b_drawImage);

//绘制绿色通道
channels = 1;
calcHist(&srcImage, 1, &channels, Mat(), dstHist, 1, histSize, ranges, true, false);
Mat g_drawImage = Mat::zeros(Size(256, 256), CV_8UC3);
minMaxLoc(dstHist, 0, &g_dHistMaxValue, 0, 0);
for (int i = 0; i < 256; i++)
{
int value = cvRound(dstHist.at<float>(i) * 256 * 0.9 / g_dHistMaxValue);

line(g_drawImage, Point(i, g_drawImage.rows - 1), Point(i, g_drawImage.rows - 1 - value), Scalar(0, 255, 0));
}
imshow("【绿色通道的直方图】", g_drawImage);

//绘制红色通道
channels = 2;
calcHist(&srcImage, 1, &channels, Mat(), dstHist, 1, histSize, ranges, true, false);
Mat r_drawImage = Mat::zeros(Size(256, 256), CV_8UC3);
minMaxLoc(dstHist, 0, &g_dHistMaxValue, 0, 0);
for (int i = 0; i < 256; i++)
{
int value = cvRound(dstHist.at<float>(i) * 256 * 0.9 / g_dHistMaxValue);

line(r_drawImage, Point(i, r_drawImage.rows - 1), Point(i, r_drawImage.rows - 1 - value), Scalar(0, 0, 255));
}
imshow("【红色通道的直方图】", r_drawImage);

waitKey(0);

return 0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: