图像局部方差计算公式:
其中,I(x+i, y+j)表示以(x, y)为中心的坐标点的像素;Ws表示窗口内像素的个数;M(x)表示局部窗口内的均值
具体实现代码:
float* getLocalVar(Mat& img, int r, float* localVarImg)
{
// 输入参数:img, r
// 输出参数:localVarImg
// 输入参数r表示窗口半径
// 对图像进行边界填充
Mat borderImg(Size(img.cols + 2*r, img.rows + 2*r), CV_8UC1, -1);
cv::copyMakeBorder(img, borderImg, r, r, r, r,BORDER_DEFAULT);
for(int i = r; i < img.rows + r; i++)
{
for(int j = r; j < img.cols + r; j++)
{
double localSum = 0;
float localAve = 0;
float localVar = 0;
//局部窗口内像素求和localSum
for( int m = i-r; m <= i+r; m++)
{
for(int n = j-r; n <= j+r; n++)
{
// cout<<"read value: "<<(int)borderImg.at<uchar>(m, n)<<endl;
localSum = localSum + borderImg.at<uchar>(m, n);
// cout<<"localSum: "<<localSum<<endl;
}
}
// 局部窗口内像素的均值计算localAve;
localAve = localSum / POW(2*r+1);
localSum = 0;
// 局部窗口内每个像素与均值差求和
for(int m = i-r; m <= i+r; m++)
{
for(int n = j-r; n <= j+r; n++)
{
// cout<<borderImg.at<uchar>(m, n) - localAve<<endl;
localSum = localSum + POW(borderImg.at<uchar>(m, n) - localAve);
}
}
// 局部方差
localVar = localSum*1.0 / (POW(2*r+1));
localVarImg[(i-r)*img.cols + (j-r)] = localVar;
}
}
return localVarImg;
}
函数调用实例:
int main(int argc, char* argv)
{
// 图像索引编号
int imgIndex = 9;
string imageIndex;
//int类型 转 string类型
stringstream ss;
ss<<imgIndex;
ss>>imageIndex;
string path = "..//data//";
string IRFile = "IR_";
string imgFormat = ".bmp";
string IRImgFile = path + IRFile + imageIndex + imgFormat;
Mat IRImg = imread(IRImgFile, 0);
if(IRImg.empty())
{
CV_Error(CV_StsBadArg, "read image wrong, pease check ");
}
if(IRImg.channels() == 3)
{
cv::cvtColor(IRImg, IRImg, CV_RGB2GRAY);
}
imshow("IRImg", IRImg);
float* IRWeight = 0;
int r = 3;
IRWeight = new float[IRImg.cols * IRImg.rows];
getLocalVar(IRImg, r, IRWeight);
return 0;
}