本文根据博客《互信息图像配准》https://blog.csdn.net/wuxingyu_cs/article/details/50397280,使用opencv对算法进行实现。
环境:VS2013+OpenCV3.0
网上流传较多的计算图像熵及互信息代码均是通过计算每一个像素点灰度值概率实现的,个人认为这种算法与图像熵或互信息原理不符(也可能是因为新手,理解有误),因此编写了一个使用灰度直方图计算图像熵与互信息的方法,如有错误,敬请指正。
废话少说,直接上代码。
计算图像熵,输入为灰度图像及灰度等级
double Entorpy(Mat& inputImg,int size)
{
MatND dstHist;
int dims = 1;
float hranges[] = { 0, 255 };
const float *ranges[] = { hranges };
int channels = 0;
calcHist(&inputImg, 1, 0, Mat(), dstHist, dims, &size, ranges);
double Ent = 0;
for (int i = 0; i < 16; i++)
{
double value = (double)dstHist.at<float>(i);
double pr = value / (inputImg.rows*inputImg.cols);
if (pr > 0)
{
Ent -= pr * (log(pr) / log(2.0));//熵
}
}
return Ent;
}
计算图像互信息,输入两幅待匹配灰度图像。
double CoEntorpy(Mat& inputImg1, Mat& inputImg2)
{
double CoEnt = 0;
MatND inpuImg1_dstHist, inpuImg2_dstHist;
int dims = 1;
float hranges[] = { 0, 255 };
const float *ranges[] = { hranges };
int size = 64; //灰度等级
int channels = 0;
calcHist(&inputImg1, 1, 0, Mat(), inpuImg1_dstHist, dims, &size, ranges);
calcHist(&inputImg2, 1, 0, Mat(), inpuImg2_dstHist, dims, &size, ranges);
for (int i = 0; i < size; i++)
{
double inpuImg1_value = (double)inpuImg1_dstHist.at<float>(i);
double inpuImg1_pr = inpuImg1_value / (inputImg1.rows*inputImg1.cols);
double inpuImg2_value = (double)inpuImg2_dstHist.at<float>(i);
double inpuImg2_pr = inpuImg2_value / (inputImg2.rows*inputImg2.cols);
double pr = (inpuImg1_value + inpuImg2_value) / (inputImg1.rows*inputImg1.cols + inputImg2.rows*inputImg2.cols);
if (pr > 0 && inpuImg1_pr > 0 && inpuImg2_pr > 0)
{
CoEnt += pr * (log(pr / (inpuImg1_pr*inpuImg2_pr)) / log(2.0));//熵
}
}
return CoEnt;
}