1、计算直方图函数
void calcHist(const Mat* image,int nimages,const int *channels,InputArray mask,OutputArray hist,int dims,const int *histsize,const float **ranges,bool uniform=true,bool accumurate=false)
参数一:输入数组或者数组集
参数二:输入数组的个数
参数三:需要统计的是第几个通道
参数四:可选的操作掩码,如果不为空则必须是8位且跟输入数组尺寸一样
参数五:一个二维数组,输出的目标直方图
参数六:需要计算的直方图维度,必须是正数
参数七:存放每个维度的直方图数组
参数八:每一维数值的取值范围
参数九:直方图是否均匀标识符
参数十:累计标识符,主要是允许从多个阵列中计算单个直方图,或者在特定的时间更新直方图
2、寻找最值函数
void minMaxLoc(InputArray src,double *minVal,double *maxVal=0,Point *minLoc,Point *maxLoc,InputArray mask = noarray())
参数一:输入单通道阵列
参数二:返回最小值指针,若无可填NULL
参数三:返回最大值指针
参数四:返回最小位置指针
参数五:返回最大位置指针
参数六:用于选择子阵列可选掩摸
绘制H-S直方图示例:
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
/* 绘制HS颜色空间的直方图 */
using namespace std;
using namespace cv;
int main(int argc,char *argv[])
{
Mat srcImage,hsvImage;
srcImage = imread(argv[1]);
cvtColor(srcImage,hsvImage,COLOR_BGR2HSV);
int hueBinNum = 30;
int saturationBinNum = 32;
int histSize[] = {hueBinNum,saturationBinNum};
float hueRanges[] = {0,180};
float saturationRanges[] = {0,256};
const float *ranges[] = {hueRanges,saturationRanges};
//MatND适用于存储直方图的一种数据结构
MatND dstHist;
int channels[] = {0,1};
calcHist(&hsvImage,1,channels,Mat(),dstHist,2,histSize,ranges,true,false);
double maxValue = 0;
//计算数组的全局最大值
minMaxLoc(dstHist,0,&maxValue,0,0);
int scale = 10;
Mat histImg = Mat::zeros(saturationBinNum*scale,hueBinNum*scale,CV_8UC3);
for(int hue=0;hue<hueBinNum;hue++)
for(int saturation=0;saturation<saturationBinNum;saturation++)
{
float binValue = dstHist.at<float>(hue,saturation);
int idensity = cvRound(binValue*255/maxValue);
rectangle(histImg,Point(hue*scale,saturation*scale),Point((hue+1)*scale -1,(saturation+1)*scale-1),Scalar::all(idensity),FILLED);
}
imshow("原始图",srcImage);
imshow("H-S直方图",histImg);
imwrite("H_S.jpg",histImg);
waitKey(0);
return 0;
}
原图 效果图
计算并绘制图像一维直方图
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc,char *argv[])
{
Mat srcImage = imread(argv[1],0);
imshow("原图",srcImage);
MatND dstHist;
int dims =1;
int size =256;
int channels =0;
float ranges[] = {0,255};
const float *hranges[]={ranges};
calcHist(&srcImage,1,&channels,Mat(),dstHist,dims,&size,hranges);
int scale =1;
Mat dstImage(size*scale,size,CV_8U,Scalar(0));
double maxValue = 0;
minMaxLoc(dstHist,0,&maxValue,0,0);
int hpt = saturate_cast<int>(0.9*size);
for(int i=0;i<256;i++)
{
float binValue = dstHist.at<float>(i);
int realValue = saturate_cast<int>(binValue*hpt/maxValue);
rectangle(dstImage,Point(i*scale,size-1),Point((i+1)*scale-1,size-realValue),Scalar(255));
}
imshow("直方图",dstImage);
waitKey(0);
return 0;
}
3、计算图像相似度
double compareHist(InputArray H1,InputArray H2,int method)
double compareHist(const SparseMat &H1,const SparsrMat &H2,int method)
参数一、二:输入的两个直方图数组
参数三:计算的距离算法,1:相关 2:卡方 3:直方图相交 4:bhattacharyya距离中
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc,char *argv[])
{
Mat srcImage_base,hsvImage_base;
Mat srcImage_test1,hsvImage_test1;
Mat srcImage_test2,hsvImage_test2;
srcImage_base = imread(argv[1]);
srcImage_test1 = imread(argv[2]);
srcImage_test2 = imread(argv[3]);
imshow("base",srcImage_base);
imshow("test1",srcImage_test1);
imshow("test2",srcImage_test2);
cvtColor(srcImage_base,hsvImage_base,COLOR_BGR2HSV);
cvtColor(srcImage_test1,hsvImage_test1,COLOR_BGR2HSV);
cvtColor(srcImage_test2,hsvImage_test2,COLOR_BGR2HSV);
int h_bin = 50,s_bin = 60;
int histSize[] = {h_bin,s_bin};
float h_ranges[]={0,256};
float s_ranges[]={0,180};
const float *ranges[]={h_ranges,s_ranges};
int channels[]={0,1};
MatND baseHist,test1Hist,test2Hist;
calcHist(&hsvImage_base,1,channels,Mat(),baseHist,2,histSize,ranges,true,false);
normalize(baseHist,baseHist,0,1,NORM_MINMAX,-1,Mat());
calcHist(&hsvImage_test1,1,channels,Mat(),test1Hist,2,histSize,ranges,true,false);
normalize(test1Hist,test1Hist,0,1,NORM_MINMAX,-1,Mat());
calcHist(&hsvImage_test2,1,channels,Mat(),test2Hist,2,histSize,ranges,true,false);
normalize(test2Hist,test2Hist,0,1,NORM_MINMAX,-1,Mat());
for(int i=0;i<4;i++)
{
int compare_method = i;
double base_base = compareHist(baseHist,baseHist,compare_method);
double base_test1 = compareHist(baseHist,test1Hist,compare_method);
double base_test2 = compareHist(baseHist,test2Hist,compare_method);
printf("方法【%d】匹配结果:【base-base】:%f,【base-test1】:%f,【base-test2】:%f\n",i,base_base,base_test1,base_test2);
}
return 0;
}
方法【0】匹配结果:【base-base】:1.000000,【base-test1】:0.023493,【base-test2】:0.032385
方法【1】匹配结果:【base-base】:0.000000,【base-test1】:374.822603,【base-test2】:488.727046
方法【2】匹配结果:【base-base】:50.936584,【base-test1】:0.388639,【base-test2】:4.061601
方法【3】匹配结果:【base-base】:0.000000,【base-test1】:0.785861,【base-test2】:0.796482
图片集: