直方图匹配又称为直方图规定化(规范化),其作用是增强某一特定区间的图像信息,直方图匹配综合了直方图变换和均衡化的原理思想,通过建立映射变换关系,使期望图像的直方图达到一种特定形态,对源图像直方图均衡化y=f(x),目标图像直方图均衡化z=g(k),使得y=z,即满足。
直方图匹配的步骤如下:(1)分别计算源图像和目标图像的累计概率分布(2)分别对源图像与目标图像进行直方图均衡化操作
(3)利用组映射关系使源图像直方图按照规定进行变换
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(void)
{
Mat srcImage = imread(1.png);
Mat dstImage = imread(2.png);
resize(dstImage,dstImage,Size(srcImage.rows,srcImage.cols),0,0,CV_INTER_LINEAR);
//初始化累计分布参数
float srcCdArr[256];
float dstCdArr[256];
int srcAddTemp[256];
int dstAddTemp[256];
int histMatchMap[256];
for(int i = 0;i<256;i++)
{
srcAddTemp[i] = 0;
dstAddTemp[i] = 0;
srcCdArr[i] = 0;
dstCdArr[i] = 0;
histMatchMap[i] = 0;
}
float sumSrcTemp = 0;
float sumDstTemp = 0;
int nSrcPix = srcImage.cols + srcImage.rows;
int nDstPix = srcImage.cols + srcImage.rows;
int matchFlag = 0;
for(size_t nrow=0;nrow<srcImage.rows;nrow++)
{
for(size_t ncol=0;ncol<srcImage.cols;ncol++)
{
srcAddTemp[(int)srcImage.at<uchar>(nrow,ncol)]++;
dstAddTemp[(int)srcImage.at<uchar>(nrow,ncol)]++;
}
}
//求解源图像与目标图像的累计概率分布
for(int i=0;i<256;i++)
{
sumSrcTemp += srcAddTemp[i];
srcCdAdd[i] = sumSrcTemp / nSrcPix;
sumDstTemp += srcAddTemp[i];
dstCdAdd[i] = sumDstTemp / nDstPix;
}
//直方图匹配
for(int i = 0;i<256;i++)
{
float minMatchPara = 20;
for(int j = 0;j<256;j++)
{
if(minMatchPara>abs(srcCdAdd[i]-dstCdAdd[i]))
{
minMatchPara = abs(srcCdAdd[i]-dstCdAdd[i]);
matchFlag = j;
}
}
}
histMatchMap[i] = matchFlag;
}
Mat HistMatchImage = Mat::zeros(srcImage.rows,srcImage.cols,CV_8UC3);
cvtColor(srcImage,HistMatchImage,CV_BGR2GTAY);
for(int i=0;i<HistMatchImage.rows,i++)
{
for(int j=0;j<HistMatchImage.cols;j++)
{
HistMatchImage.at<uchar>(i,j) = histMatchMap[HistMatchImage.at<uchar>(i,j)];
}
}