#if !defined HISTOGRAM1D
#define HISTOGRAM1D
#pragma once
//在文件头加入“#pragma once”,能够保证头文件被编译一次,它用来防止某个头文件被多次“include”
//#if !defined, #define, #endif 用来防止某个宏被多次定义
#include "iostream"
#include "math.h"
#include "stdio.h"
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/core/core.hpp"
using namespace cv;
using namespace std;
//创建灰度图像直方图
class Histogram1D
{
public:
//构造函数
Histogram1D(){
//默认参数
histSize[0]=255;//255个箱子数
hranges[0]=0.0;//从0开始
hranges[1]=256.0;//不包括256,到255
ranges[0]=hranges;
channels[0]=0; //先关注通道0
}
//计算一维直方图
Mat getHistogram(const Mat &image){
Mat hist;
calcHist(&image, //输入图像
1, //仅仅为一个图像的直方图
channels, //使用的通道
Mat(), //不使用掩码
hist, //结果直方图
1, //直方图维数,一维
histSize, //箱子数目
ranges); //像素范围
return hist;
}
//计算一维直方图,并返回对应的图像
Mat getHistogramImage(const Mat &image,int zoom=1){
//首先计算直方图
Mat hist=getHistogram(image);
//创建图像
return getImageOfHistogram(hist,zoom);
}
//创建一个静态的直方图图像(静态方式)
static Mat getImageOfHistogram(const Mat &hist,int zoom){
//获取最大值与最小值
double maxValue=0;
double minValue=0;
minMaxLoc(hist,&minValue,&maxValue,0,0);//局部最大最小获取方式
//直方图大小
int histSize=hist.rows;
//显示直方图的方形图像
Mat histImg(histSize*zoom,histSize*zoom,CV_8UC1,Scalar(255));//初始化直方图背景区域
//设置最高的为90%(图像高度)的箱子个数
int hpt=static_cast<int>(0.9*histSize);
//为每个箱子画垂线
for (int h=0;h<histSize;h++)
{
float binValue=hist.at<float>(h);//获取一维数组hist中的数值
if (binValue>0)
{
int intensity=static_cast<int>(binValue*hpt/maxValue);//把所有数值归化到hpt一下范围
line(histImg, // 画图背景图像
Point(h*zoom,histSize*zoom), //前一个点
Point(h*zoom,(histSize-intensity)*zoom), //后一个点
Scalar(0), //颜色
zoom); //线粗
}
}
return histImg;
}
protected:
private:
int histSize[1];//直方图箱子数量
float hranges[2]; //值的范围
const float *ranges[1]; //值范围指针
int channels[1]; //要检查的通道数
};
#endif;
///
#include "ColorDetector.h"
#include "Histogram1D.h"
//鼠标点击获取图像的像素值(包括彩色与黑白图像)//
void onMouse(int event,int x, int y,int flags,void *param){
Mat *image=reinterpret_cast<Mat*>(param);
switch(event){
case CV_EVENT_FLAG_LBUTTON:
if (image->type()==CV_8UC1){ //gray image
cout<<"at("<<y<<","<<x<<") value is: "<<static_cast<int>(image->at<uchar>((Point(x,y))))<<endl;
}
else if(image->type()==CV_8UC3)//rgb(color) image
{
//cout<<"at("<<y<<","<<x<<") value is: "<<"( "<<(image->at<Vec3b>(y,x)[0])<<", "<<(image->at<Vec3b>(y,x)[1])<<", "<<(image->at<Vec3b>(y,x)[2])<<")"<<endl;
cout<<"at("<<y<<","<<x<<") value is: "<<"( "<<static_cast<int>(image->at<Vec3b>(y,x)[0])<<", "<<static_cast<int>(image->at<Vec3b>(y,x)[1])<<", "<<static_cast<int>(image->at<Vec3b>(y,x)[2])<<")"<<endl;
}
break;
}
}
void main(){
ColorDetector cdetect;
Histogram1D h;
Mat image=imread("C:\\Users\\Administrator\\Desktop\\experiment\\d120.jpg",CV_LOAD_IMAGE_GRAYSCALE);
imshow("result",h.getHistogramImage(image));
//setMouseCallback("result",onMouse,reinterpret_cast<void*>(&detector));
waitKey(0);
}