1、灰度图像直方图的绘制
绘制结果如下:
源代码如下:
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
//0表示将图像转换为灰度再返回
Mat srcImage = imread("dog.bmp", 0);
imshow("原图",srcImage);
if(!srcImage.data) {cout << "fail to load image" << endl; return 0;}
//定义变量
Mat dstHist;
int dims = 1;
float hranges[] = {0, 256};
const float *ranges[] = {hranges}; // 这里需要为const类型
int size = 256;
int channels = 0;
//计算图像的直方图
calcHist(&srcImage, 1, &channels, Mat(), dstHist, dims, &size, ranges);
Mat dstImage(size, size, CV_8U, Scalar(0));
//获取最大值和最小值
double minValue = 0;
double maxValue = 0;
minMaxLoc(dstHist,&minValue, &maxValue, 0, 0); // 在cv中用的是cvGetMinMaxHistValue
//绘制出直方图
//saturate_cast函数的作用即是:当运算完之后,结果为负,则转为0,结果超出255,则为255。
int hpt = saturate_cast<int>(0.9 * size);
for(int i = 0; i < 256; i++)
{
float binValue = dstHist.at<float>(i); // 注意hist中是float类型
//拉伸到0-max
int realValue = saturate_cast<int>(binValue * hpt/maxValue);
line(dstImage,Point(i, size - 1),Point(i, size - realValue),Scalar(255));
}
imshow("一维直方图", dstImage);
waitKey(0);
return 0;
}
2、彩色图像直方图的绘制
绘制结果如下:
代码如下:
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
int main( )
{
Mat srcImage;
srcImage=imread("dog.bmp");
imshow( "素材图", srcImage );
int bins = 256;
int hist_size[] = {bins};
float range[] = { 0, 256 };
const float* ranges[] = { range};
MatND redHist,grayHist,blueHist;
int channels_r[] = {0};
//进行直方图的计算(红色分量部分)
calcHist( &srcImage, 1, channels_r, Mat(), //不使用掩膜
redHist, 1, hist_size, ranges,
true, false );
//进行直方图的计算(绿色分量部分)
int channels_g[] = {1};
calcHist( &srcImage, 1, channels_g, Mat(), // do not use mask
grayHist, 1, hist_size, ranges,
true, // the histogram is uniform
false );
//进行直方图的计算(蓝色分量部分)
int channels_b[] = {2};
calcHist( &srcImage, 1, channels_b, Mat(), // do not use mask
blueHist, 1, hist_size, ranges,
true, // the histogram is uniform
false );
//-----------------------绘制出三色直方图------------------------
//参数准备
double maxValue_red,maxValue_green,maxValue_blue;
minMaxLoc(redHist, 0, &maxValue_red, 0, 0);
minMaxLoc(grayHist, 0, &maxValue_green, 0, 0);
minMaxLoc(blueHist, 0, &maxValue_blue, 0, 0);
int scale = 1;
int histHeight=256;
Mat histImage = Mat::zeros(histHeight,bins*3, CV_8UC3);
//正式开始绘制
for(int i=0;i<bins;i++)
{
//参数准备
float binValue_red = redHist.at<float>(i);
float binValue_green = grayHist.at<float>(i);
float binValue_blue = blueHist.at<float>(i);
int intensity_red = cvRound(binValue_red*histHeight/maxValue_red); //要绘制的高度
int intensity_green = cvRound(binValue_green*histHeight/maxValue_green); //要绘制的高度
int intensity_blue = cvRound(binValue_blue*histHeight/maxValue_blue); //要绘制的高度
//绘制红色分量的直方图
line(histImage,Point(i,histHeight-1),Point(i, histHeight - intensity_red),CV_RGB(255,0,0));
//绘制绿色分量的直方图
line(histImage,Point(i+bins,histHeight-1),Point(i+bins, histHeight - intensity_green),CV_RGB(0,255,0));
//绘制蓝色分量的直方图
line(histImage,Point(i+bins*2,histHeight-1),Point(i+bins*2, histHeight - intensity_blue),CV_RGB(0,0,255));
}
imshow( "图像的RGB直方图", histImage );
waitKey(0);
return 0;
}
3、直方图均衡
opencv中使用的函数为equalize(),描述如下:
C++: void equalizeHist(InputArray src, OutputArray dst)
src: 输入图像,Mat类即可,需要为8位单通道的图像。
dst: 运算后的结果,和原图有一样的尺寸和大小。
代码执行结果如下:
源代码如下:
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
int main( )
{
Mat srcImage, dstImage;
Mat srcHist, dstHist;
srcImage = imread( "lena.bmp", 0 );
if(!srcImage.data ) { printf("读取图片错误"); return false; }
imshow( "原始图", srcImage );
//进行直方图均衡化
equalizeHist( srcImage, dstImage );
//显示结果
imshow( "直方图均衡化", dstImage );
//计算图像的直方图
//定义变量
int dims = 1;
float hranges[] = {0, 255};
const float *ranges[] = {hranges}; // 这里需要为const类型
int size = 256;
int channels = 0;
calcHist(&srcImage, 1, &channels, Mat(), srcHist, dims, &size, ranges);
calcHist(&dstImage, 1, &channels, Mat(), dstHist, dims, &size, ranges);
Mat srcHistImage(size, size, CV_8U, Scalar(0));
Mat dstHistImage(size, size, CV_8U, Scalar(0));
//获取最大值和最小值
double minValue = 0;
double srcMaxValue = 0;
double dstMaxValue = 0;
minMaxLoc(srcHist,&minValue, &srcMaxValue, 0, 0);
minMaxLoc(dstHist,&minValue, &dstMaxValue, 0, 0);
//绘制出直方图
//saturate_cast函数的作用即是:当运算完之后,结果为负,则转为0,结果超出255,则为255。
int hpt = saturate_cast<int>(0.9 * size);
for(int i = 0; i < 256; i++)
{
float srcValue = srcHist.at<float>(i); // 注意hist中是float类型
float dstValue = dstHist.at<float>(i);
//拉伸到0-max
int srcRealValue = saturate_cast<int>(srcValue * hpt/srcMaxValue);
int dstRealValue = saturate_cast<int>(dstValue * hpt/dstMaxValue);
line(srcHistImage,Point(i, size - 1),Point(i, size - srcRealValue),Scalar(255));
line(dstHistImage,Point(i, size - 1),Point(i, size - dstRealValue),Scalar(255));
}
imshow("原图直方图", srcHistImage);
imshow("均衡后直方图", dstHistImage);
waitKey(0);
return 0;
}