这篇博客主要来学习图像直方图比较。
图像直方图比较,就是计算两幅图像的直方图数据,比较两组数据的相似性,从而得到两幅图像之间的相似程度。
void cv::calcHist (const Mat * images,
int nimages,
const int * channels,
InputArray mask,
OutputArray hist,
int dims,
const int * histSize,
const float ** ranges,
bool uniform = true,
bool accumulate = false
)
参数:
images: 源图像,注意这里的格式是const Mat*,也就是说,你要传入一个地址,输入的数组(图片)或者数组集(一堆图片)需要为相同的深度和相同的尺寸。每个都能够用任意数量的通道。
Nimages:输入图像个数
Channels:List of the dims channels used to compute the histogram. The first array channels are numerated from 0 to images[0].channels()-1 , the second array channels are counted from images[0].channels() to images[0].channels() + images[1].channels()-1, and so on.
mask:可选的掩码,如果不为空的话,那么它必须是8位且和image[i]尺寸相同。
hist:输出的直方图,二维数组。
dims:需要统计的直方图维度(特征数目),必须是正数,且不大于CV_MAX_DIMS(这个版本opencv3.1里面是32)
histSize:存放每个维度的直方图尺寸的数组。
ranges:每一维数值的取值范围。Array of the dims arrays of the histogram bin boundaries in each dimension. When the histogram is uniform ( uniform =true), then for each dimension i it is enough to specify the lower (inclusive) boundary L0 of the 0-th histogram bin and the upper (exclusive) boundary UhistSize[i]−1 for the last histogram bin histSize[i]-1 . That is, in case of a uniform histogram each of ranges[i] is an array of 2 elements. When the histogram is not uniform ( uniform=false ), then each of ranges[i] contains histSize[i]+1 elements: L0,U0=L1,U1=L2,...,UhistSize[i]−2=LhistSize[i]−1,UhistSize[i]−1 . The array elements, that are not between L0 and UhistSize[i]−1 , are not counted in the histogram.
uniform:表示直方图是否均匀
accumulate:累计标识符,若为ture,直方图再配置阶段不会被清零。
#include
#include
using namespace cv;
using namespace std;
int main(int artc, char** argv) {
Mat src1 = imread("C:/Users/Dell/Desktop/picture/basketball1.png");
Mat src2 = imread("C:/Users/Dell/Desktop/picture/basketball2.png");
Mat src3 = imread("C:/Users/Dell/Desktop/picture/helloworld.png");
Mat src4 = imread("C:/Users/Dell/Desktop/picture/7.jpg");
imshow("input1", src1);
imshow("input2", src2);
imshow("input3", src3);
imshow("input4", src4);
Mat hsv1, hsv2, hsv3, hsv4;
cvtColor(src1, hsv1, COLOR_BGR2HSV);
cvtColor(src2, hsv2, COLOR_BGR2HSV);
cvtColor(src3, hsv3, COLOR_BGR2HSV);
cvtColor(src4, hsv4, COLOR_BGR2HSV);
int h_bins = 60; int s_bins = 64;
int histSize[] = { h_bins, s_bins };
float h_ranges[] = { 0, 180 };
float s_ranges[] = { 0, 256 };
const float* ranges[] = { h_ranges, s_ranges };
int channels[] = { 0, 1 };
//参数1 指针引用
//参数2 数组中有几个图片
//参数3 通道(0-1)
//参数4 输出
//参数5 计算的两个通道直方图
//参数6 存放每个维度的直方图尺寸的数组。
//参数7 通道像素的取值范围
Mat hist1, hist2, hist3, hist4;
calcHist(&hsv1, 1, channels, Mat(), hist1, 2, histSize, ranges, true, false);
calcHist(&hsv2, 1, channels, Mat(), hist2, 2, histSize, ranges, true, false);
calcHist(&hsv3, 1, channels, Mat(), hist3, 2, histSize, ranges, true, false);
calcHist(&hsv4, 1, channels, Mat(), hist4, 2, histSize, ranges, true, false);
//归一化
normalize(hist1, hist1, 0, 1, NORM_MINMAX, -1, Mat());
normalize(hist2, hist2, 0, 1, NORM_MINMAX, -1, Mat());
normalize(hist3, hist3, 0, 1, NORM_MINMAX, -1, Mat());
normalize(hist4, hist4, 0, 1, NORM_MINMAX, -1, Mat());
for (int i = 0; i < 4; i++)
{
int compare_method = i;
double src1_src2 = compareHist(hist1, hist2, compare_method);
double src3_src4 = compareHist(hist3, hist4, compare_method);
printf(" Method [%d] : src1_src2 : %f, src3_src4: %f, \n", i, src1_src2, src3_src4);
}
waitKey(0);
return 0;
}