计算直方图

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

图片集:



猜你喜欢

转载自blog.csdn.net/gg101001/article/details/79653889