1.视频教程:
B站、网易云课堂、腾讯课堂
2.代码地址:
Gitee
Github
3.存储地址:
Google云
百度云:
提取码:

1.直方图统计

灰度图像:0-255
如果每个bin的范围是0-15
则bin的个数是16

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char** argv) {

	Mat src = imread("E:/cats.jpg", IMREAD_UNCHANGED);

	if (src.empty()) {
		printf("image is empty!!!");
		return -1;
	}
	namedWindow("image", WINDOW_FREERATIO);
	imshow("image", src);
	vector<Mat> mv;
	split(src, mv);
	// 计算直方图
	int histSize = 256;
	Mat b_hist, g_hist, r_hist;
	float range[] = { 0,255 };
	const float * histRanges = { range };
	calcHist(&mv[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRanges, true, false);
	calcHist(&mv[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRanges, true, false);
	calcHist(&mv[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRanges, 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 = 500.0 / 256.0;
	for (int i = 0; i < 255; i++) {

		line(result, Point(step*i, 50 + nm - b_hist.at<float>(i, 0)), Point(step*(i + 1), 50 + (nm - b_hist.at<float>(i + 1, 0))), Scalar(255, 0, 0), 2, 8, 0);
		line(result, Point(step*i, 50 + nm - g_hist.at<float>(i, 0)), Point(step*(i + 1), 50 + (nm - b_hist.at<float>(i + 1, 0))), Scalar(0, 255, 0), 2, 8, 0);
		line(result, Point(step*i, 50 + nm - r_hist.at<float>(i, 0)), Point(step*(i + 1), 50 + (nm - b_hist.at<float>(i + 1, 0))), Scalar(0, 0, 255), 2, 8, 0);

	}
	imshow("histgorm", result);
	waitKey(0);
	destroyAllWindows();
	return 0;
}

OpenCV获取图像直方图_scala

2.直方图均衡化

OpenCV获取图像直方图_ios_02

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char** argv) {

	Mat src = imread("E:/cats.jpg", IMREAD_UNCHANGED);

	if (src.empty()) {
		printf("image is empty!!!");
		return -1;
	}
	namedWindow("image", WINDOW_FREERATIO);
	imshow("image", src);

	Mat gray, dst;
	cvtColor(src, gray, COLOR_BGR2GRAY);
	imshow("gray", gray);
	// 均衡化
	equalizeHist(gray, dst);
	imshow("dst", dst);

	waitKey(0);
	destroyAllWindows();
	return 0;
}





OpenCV获取图像直方图_直方图均衡化_03

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char** argv) {

	Mat src = imread("E:/cats.jpg", IMREAD_UNCHANGED);

	if (src.empty()) {
		printf("image is empty!!!");
		return -1;
	}
	namedWindow("image", WINDOW_FREERATIO);
	imshow("image", src);

	Mat gray, dst;
	cvtColor(src, gray, COLOR_BGR2GRAY);
	imshow("gray", gray);
	equalizeHist(gray, dst);
	imshow("dst", dst);

	// 计算直方图
	int histSize = 256;
	Mat b_hist, g_hist, r_hist;
	float range[] = { 0,255 };
	const float * histRanges = { range };
	calcHist(&gray, 1, 0, Mat(), b_hist, 1, &histSize, &histRanges, true, false);
	calcHist(&dst, 1, 0, Mat(), g_hist, 1, &histSize, &histRanges, 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());
	float step = 500.0 / 256.0;
	for (int i = 0; i < 255; i++) {
		line(result, Point(step*i, 50 + nm - b_hist.at<float>(i, 0)), Point(step*(i + 1), 50 + (nm - b_hist.at<float>(i + 1, 0))), Scalar(255, 0, 0), 2, 8, 0);
		line(result, Point(step*i, 50 + nm - g_hist.at<float>(i, 0)), Point(step*(i + 1), 50 + (nm - b_hist.at<float>(i + 1, 0))), Scalar(0, 255, 0), 2, 8, 0);
	}
	imshow("histgorm", result);
	waitKey(0);
	destroyAllWindows();
	return 0;
}

OpenCV获取图像直方图_#include_04

3.直方图比较

1.直方图数据归一化之后进行
2.比较得到相似度

四种常用比较方式

1.相关性
2.卡方
3.交叉
4.巴氏距离

OpenCV获取图像直方图_直方图_05

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char** argv) {

	Mat src1 = imread("E:/cats.jpg", IMREAD_COLOR);
	Mat src2 = imread("E:/cat.png", IMREAD_COLOR);

	if (src1.empty() || src2.empty()) {
		printf("image is empty!!!");
		return -1;
	}

	imshow("src1", src1);
	imshow("src2", src2);

	int histSize[] = { 256,256,256 };
	int channels[] = { 0,1,2 };
	Mat hist1, hist2;
	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);

	// 归一化
	normalize(hist1, hist1, 0, 1.0, NORM_MINMAX, -1, Mat());
	normalize(hist2, hist2, 0, 1.0, NORM_MINMAX, -1, Mat());

	// 1.巴氏距离比较
	double h12 = compareHist(hist1, hist2, HISTCMP_BHATTACHARYYA);
	double h11 = compareHist(hist1, hist1, HISTCMP_BHATTACHARYYA);
	printf("h12:%.2f,h11:%.2f\n", h12, h11);
	// 2.相关性比较
	double c12 = compareHist(hist1, hist2, HISTCMP_CORREL);
	double c11 = compareHist(hist1, hist1, HISTCMP_CORREL);
	printf("c12:%.2f,c11:%.2f\n", c12, c11);
	waitKey(0);
	destroyAllWindows();
	return 0;
}





OpenCV获取图像直方图_ios_06