opencv学习日记——直方图匹配
一、图像处理结果
二、代码部分
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
void show_hist(Mat hist, string name);
Mat hist(Mat a);
int main()
{
Mat img1 = imread("cat.jpg");
Mat img, gray;
cvtColor(img1, img, COLOR_BGR2GRAY);
Mat gray1 = imread("nazha.jpg");
resize(gray1, gray, Size(670, 471));
if (img.empty())
{
cout << "输入为空";
return -1;
}
Mat hist1, hist2;
hist1 = hist(img);
hist2 = hist(gray);
float hist1_cdf[256] = {hist1.at<float>(0)};
float hist2_cdf[256] = {hist2.at<float>(0)};
//计算概率累积
for (int i = 1; i < 256; i++)
{
hist1_cdf[i] = hist1_cdf[i - 1] + hist1.at<float>(i);
hist2_cdf[i] = hist2_cdf[i - 1] + hist2.at<float>(i);
}
//计算概率累计误差矩阵
float diff_cdf[256][256];
for (int i = 0; i < 256; i++)
{
for (int j = 0; j < 256; j++)
{
diff_cdf[i][j] = fabs(hist1_cdf[i] - hist2_cdf[j]);
}
}
//生出LUT
Mat lut(1, 256, CV_8U);
for (int i = 0; i < 256; i++)
{
float min = diff_cdf[i][0];
int index = 0;
for (int j = 0; j < 256; j++)
{
if (min > diff_cdf[i][j])
{
min = diff_cdf[i][j];
index = j;
}
}
lut.at<uchar>(i) = (uchar)index;
}
Mat result, hist3;
LUT(img, lut, result);
hist3 = hist(result);
imshow("待匹配图像", img);
imshow("匹配的模板图像", gray);
imshow("直方图匹配结果", result);
show_hist(hist1, "img");
show_hist(hist2, "gray");
show_hist(hist3, "result");
waitKey(0);
return 0;
}
//可视化直方图
void show_hist(Mat hist, string name)
{
int hist_w = 512;
int hist_h = 360;
int width = 2;
Mat img3 = Mat::zeros(hist_h, hist_w, CV_8UC1);
normalize(hist, hist, 1, 0, NORM_INF, -1, Mat());
for (int i = 1; i < hist.rows ; i++ )
{
rectangle(img3, Point(width * (i - 1), hist_h - 1), Point(width * i - 1, hist_h - cvRound(hist_h * hist.at<float>(i - 1)) - 1), Scalar(255, 255, 255), -1);
}
imshow(name, img3);
}
//计算直方图矩阵
Mat hist(Mat a)
{
int channels[1] = {0};
Mat hist;
int bins[1] = {256};
float range[2] = {0, 255};
const float * ranges[1] = {range};
calcHist(&a, 1, channels, Mat(), hist, 1, bins, ranges);
return hist;
}