一、直方图匹配(直方图规定化)算法:是以一个图像直方图作为模板,使待处理图像直方图与模板直方图近似。
算法流程:
- 分别计算模板影像和待处理影像累积直方图(统计像素值在0~255上分布比例);
- 一次计算待图像直方图上每个值到模板图像直方图每个值之间差值,生成256个差值表;
- 计算每个差值表中最小值,将最小值索引作为该差值表对应待处理图像值变换后值,生成查找表;
- 通过查找表对待处理图像进行处理。
实现步骤:
- 计算累积直方图:
计算直方图
Map<Integer, Double> map = new HashMap<>();
int width = image.getWidth();
int height = image.getHeight();
double totalPixel = width * height;
double rate = 1 / (3 * totalPixel);
for (int i = 0; i < 256; i++) {
map.put(i, 0.0);// 通过循环,往集合里面填充0~255个位置,初始值都为0
}
//分别统计图像上0~255上分布总数
for (int i = 0; i < image.getWidth(); i++) {
for (int j = 0; j < image.getHeight(); j++) {
int rgb = image.getRGB(i, j);
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
map.put(r, map.get(r) + rate);
map.put(g, map.get(g) + rate);
map.put(b, map.get(b) + rate);
}
}
计算累积直方图
for(int i = 0; i < 256;i++) {
tempSum += tempMap.get(i);
imageSum += imageMap.get(i);
tempList[i] = tempSum;
imageList[i] = imageSum;
}
2.计算差值表
List<Double[]> differenceList = new ArrayList<>();
for(int i = 0; i < 256;i++) {
Double[] differenceTable = new Double[256];
for(int j = 0; j< 256;j++) {
differenceTable[j] = Math.abs(imageList[i] - tempList[j]);
}
differenceList.add(differenceTable);
}
3.计算差值表最小值,生成查找表
for(int i = 0; i < 256;i++) {
Double[] differenceTable = differenceList.get(i);
Double[] sortTable = new Double[256];
for(int j = 0; j < 256;j++) {
sortTable[j] = differenceTable[j];
}
Arrays.sort(sortTable);
double mini = sortTable[0];
Double[] table = differenceList.get(i);
for(int j = 0; j < 256; j++) {
if (mini == table[j]) {
resultTable[i] = j;
}
}
}
4.通过查找表处理图像
for(int i = 0; i < width; i++) {
for(int j = 0 ;j < height;j++) {
int rgb = image.getRGB(i, j);
int r = (rgb >> 16) & 0xff;
int g = (rgb >> 8) & 0xff;
int b = rgb & 0xff;
r = rTable[r];
g = gTable[g];
b = bTable[b];
rgb = (r & 0xff) << 16 | (g & 0xff) << 8 | b & 0xff;
resultImage.setRGB(i, j, rgb);
}
}
return resultImage;
二、使用直方图匹配算法对图像进行匀光匀色。选取两幅不同色调的图像使用直方图匹配算法进行处理。
模板图像:
待处理图像:
处理后:
结论:处理前模板图像与待处理图像色调差异较大,处理后图像整体色调与模板图像非常接近。