直方图计算
API:
void 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:输入的图片指针
- nimages:计算的图片数量
- channels:要计算图片哪个通道的直方图
- mask:要计算的区域,直接Mat()就代表整张图片
- hist:计算得到的直方图数组
- dims:直方图通道的个数
- histSize:把直方图分成多少个区间
- ranges:统计像素的范围
- uniform:是否归一化处理
- accumulate:多个图像时是否对直方图进行累加计算
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat src = imread("E:/opencv_source/opencv_tutorial_data-master/images/flower.png");
imshow("src", src);
vector<Mat> mv;
split(src, mv);
Mat b_hist,g_hist,r_hist;
int histSize = 256;
float range[] = {0,256};
const float* ranges = { range };
calcHist(&mv[0], 1, 0, Mat(), b_hist, 1, &histSize, &ranges, true, false);
calcHist(&mv[1], 1, 0, Mat(), g_hist, 1, &histSize, &ranges, true, false);
calcHist(&mv[2], 1, 0, Mat(), r_hist, 1, &histSize, &ranges, true, false);
Mat result = Mat::zeros(Size(600, 400), CV_8UC3);
int margin = 50;
int nm = result.rows - 2 * margin;
normalize(b_hist, b_hist, 0, nm, NORM_MINMAX, -1, Mat());
normalize(g_hist, g_hist, 0, nm, NORM_MINMAX, -1, Mat());
normalize(r_hist, r_hist, 0, nm, NORM_MINMAX, -1, Mat());
float step = (result.cols - 2 * margin) / 256.0;
for (int i = 0; i < 255; i++)
{
line(result, Point(step * i + 50, 50 + nm - b_hist.at<float>(i, 0)), Point(step * (i + 1) + 50, 50 + nm - b_hist.at<float>(i + 1, 0)), Scalar(255, 0, 0), 2, 8, 0);
line(result, Point(step * i + 50, 50 + nm - g_hist.at<float>(i, 0)), Point(step * (i + 1) + 50, 50 + nm - g_hist.at<float>(i + 1, 0)), Scalar(0, 255, 0), 2, 8, 0);
line(result, Point(step * i + 50, 50 + nm - r_hist.at<float>(i, 0)), Point(step * (i + 1) + 50, 50 + nm - r_hist.at<float>(i + 1, 0)), Scalar(0, 0, 255), 2, 8, 0);
}
line(result, Point(0, nm + 50), Point(result.cols, nm + 50), Scalar(255, 255, 255), 1, 8, 0);
line(result, Point(50, result.rows), Point(50, 0), Scalar(255, 255, 255), 1, 8, 0);
imshow("result", result);
waitKey(0);
destroyAllWindows();
return 0;
}
直方图均衡化(增强灰度图的图像对比度)
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat src = imread("E:/opencv_source/opencv_tutorial_data-master/images/flower.png");
imshow("src", src);
Mat dst, gray;
cvtColor(src, gray, COLOR_BGR2GRAY);
imshow("gray", gray);
equalizeHist(gray, dst);
imshow("dst", dst);
waitKey(0);
destroyAllWindows();
return 0;
}
利用直方图计算图像相似度
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat src1 = imread("E:/opencv_source/opencv_tutorial_data-master/images/malware.png");
Mat src2 = imread("E:/opencv_source/opencv_tutorial_data-master/images/malware1.png");
Mat src3 = imread("E:/opencv_source/opencv_tutorial_data-master/images/malware2.png");
imshow("src1", src1);
imshow("src2", src2);
imshow("src3", src3);
//直方图计算
Mat hist1, hist2, hist3;
int histSize[] = { 256,256,256 };
int channels[] = { 0,1,2 };
float c1[] = { 0,255 };
float c2[] = { 0,255 };
float c3[] = { 0,255 };
const float* histRanges[] = { c1,c2,c3 };
calcHist(&src1, 1, channels, Mat(), hist1, 3, histSize, histRanges, true, false);
calcHist(&src2, 1, channels, Mat(), hist2, 3, histSize, histRanges, true, false);
calcHist(&src3, 1, channels, Mat(), hist3, 3, histSize, histRanges, true, false);
//归一化
normalize(hist1, hist1, 0, 1.0, NORM_MINMAX, -1, Mat());
normalize(hist2, hist2, 0, 1.0, NORM_MINMAX, -1, Mat());
normalize(hist3, hist3, 0, 1.0, NORM_MINMAX, -1, Mat());
//比较巴式距离
double bh12 = compareHist(hist1, hist2, HISTCMP_BHATTACHARYYA);
double bh13 = compareHist(hist1, hist3, HISTCMP_BHATTACHARYYA);
double bh23 = compareHist(hist2, hist3, HISTCMP_BHATTACHARYYA);
printf("bh12:%.2f,bh13:%.2f,bh23:%.2f\n", bh12, bh13, bh23);
//相关性比较
double ch12 = compareHist(hist1, hist2, HISTCMP_CORREL);
double ch13 = compareHist(hist1, hist3, HISTCMP_CORREL);
double ch23 = compareHist(hist2, hist3, HISTCMP_CORREL);
printf("ch12:%.2f,ch13:%.2f,ch23:%.2f\n", ch12, ch12, ch23);
waitKey(0);
destroyAllWindows();
return 0;
}