/*其主要思路为:
1、求取源图I的平均灰度,并记录rows和cols;
2、按照一定大小,分为N*M个方块,求出每块的平均值,得到子块的亮度矩阵D;
3、用矩阵D的每个元素减去源图的平均灰度,得到子块的亮度差值矩阵E;
4、用双立方差值法,将矩阵E差值成与源图一样大小的亮度分布矩阵R;---可以使用使用除法
5、得到矫正后的图像result = I - R;*/
void RemoveLightUnevenDistribution(cv::Mat &image, int blockSize)
{
if (!image.data)
{
return;
}
if (image.channels() == 3)
{
cvtColor(image, image, CV_RGB2GRAY);
//cvtColor(image, image, CV_BGR2GRAY);
}
double average = mean(image)[0];
int rows_block = ceil(double(image.rows) / double(blockSize));
int cols_block = ceil(double(image.cols) / double(blockSize));
cv::Mat blockImage;
blockImage = cv::Mat::zeros(rows_block, cols_block, CV_32FC1);
for (int i = 0; i < rows_block; i++)
{
for (int j = 0; j < cols_block; j++)
{
int rowmin = i*blockSize;
int rowmax = (i + 1)*blockSize;
if (rowmax > image.rows) rowmax = image.rows;
int colmin = j*blockSize;
int colmax = (j + 1)*blockSize;
if (colmax > image.cols) colmax = image.cols;
cv::Mat imageROI = image(cv::Range(rowmin, rowmax), cv::Range(colmin, colmax));
double temaver = mean(imageROI)[0];
blockImage.at<float>(i, j) = temaver;
}
}
//blockImage = blockImage - average;//subtract
cv::Mat blockImageTemp = blockImage.clone();
cv::convertScaleAbs(blockImage, blockImageTemp, 1 / average, 0);
//blockImage = blockImage - average
cv::Mat blockImageResize;
cv::resize(blockImage, blockImageResize, image.size(), (0, 0), (0, 0), cv::INTER_CUBIC);
cv::Mat imageFloat;
image.convertTo(imageFloat, CV_32FC1);
cv::Mat dst = imageFloat - blockImageResize;
dst.convertTo(image, CV_8UC1);
return;
}
转载网络,稍作修改