目录
在数字图像处理领域,图像阴影是一个常见的问题。阴影的存在会导致图像对比度降低、细节模糊,严重影响图像的视觉效果和后续的图像分析任务,如目标检测、识别与跟踪等。因此,图像去阴影技术具有重要的研究意义和实际应用价值。传统的图像去阴影方法主要包括基于物理模型的方法和基于图像处理的方法。基于物理模型的方法试图通过建立光照模型来估计和补偿阴影区域,但这类方法通常需要复杂的计算和大量的先验知识,且对不同场景的适应性较差。基于图像处理的方法则侧重于从图像的像素特征出发,直接对图像进行操作以去除阴影。本文提出的基于模板匹配和图像形态学处理的方法属于后者,它具有简单高效、适应性强等优点。
1. 模板匹配原理
模板是模板匹配算法的核心元素。在图像去阴影应用中,模板应选择图像中不受阴影影响或阴影影响较小的区域。例如,可以选择图像中的高光区域、特定纹理区域或人工标记的无阴影区域作为模板。模板的大小和形状需要根据图像的特点和阴影的分布情况进行确定。一般来说,模板应具有一定的代表性和独特性,以便在图像中能够准确地找到与之匹配的区域。
常用的匹配准则有多种,如平方差匹配准则、归一化互相关匹配准则等。
在图像中进行模板匹配时,需要遍历图像的所有可能位置,计算每个位置的匹配值。为了提高匹配效率,可以采用一些优化策略,如多分辨率匹配、金字塔分层匹配等。以多分辨率匹配为例,首先将图像和模板进行降采样,得到不同分辨率的图像和模板层次结构。在低分辨率层次上进行快速的粗匹配,得到可能的匹配区域,然后在高分辨率层次上对这些区域进行精确匹配,从而减少不必要的计算量。
2.图像形态学处理
膨胀操作会使图像中的目标区域扩大,边界向外扩张。在去阴影中,膨胀操作可以填充阴影区域内部的一些小孔和凹陷,使阴影区域更加完整。
在去阴影中,开运算可以去除阴影区域中的一些孤立噪声点和小阴影斑块,使阴影区域更加规则。在去阴影中,闭运算可以填充阴影区域与非阴影区域之间的一些缝隙,使阴影区域与周围环境更好地融合。
3.基于模板匹配和图像形态学处理的图像去阴影方法
利用模板匹配算法在图像中找到无阴影的模板区域,并确定其在图像中的位置和特征。然后,以模板区域为参考,通过比较图像中其他区域与模板区域的特征差异,检测出可能的阴影区域。例如,可以计算图像中各区域与模板区域的亮度差异、颜色差异或纹理差异等特征指标,当这些差异超过一定阈值时,将该区域判定为阴影区域。
对于检测到的阴影区域,采用图像形态学处理进行去除。首先,根据阴影区域的形状和大小选择合适的结构元素B。然后,对阴影区域进行开运算,去除阴影区域中的噪声和小斑块,得到较为平滑的阴影轮廓:
4.MATLAB程序
.................................................................................
function ImgOut = remove(ImgIn, mask, x, y, t)
% remove函数用于实际去除图像ImgIn中由掩码mask标记区域所对应的阴影部分,
% 并根据smoothEdges参数处理阴影与光亮区域的边缘
ps = 8;
% 将输入图像ImgIn的数据类型转换为双精度浮点数类型,并将像素值归一化到[0, 1]区间,以便后续计算
Id = double(ImgIn)./ 255;
% 获取掩码mask的高度(行数)和宽度(列数)
[h, w] = size(mask);
% 获取边界点的数量
npt = length(x);
% 初始化一个长度为3的双精度浮点数向量aCh,用于存储某种颜色通道的累加值
aCh = double([0.0, 0.0, 0.0]);
% 初始化一个长度为3的双精度浮点数向量aChs,用于存储另一种颜色通道的累加值
aChs = double([0, 0, 0]);
% 遍历所有边界点,计算边界点两侧一定范围内像素点的颜色通道值相关信息
for n = 1:npt
x0 = x(n);
y0 = y(n);
t0 = t(n);
% 根据当前边界点的坐标和切线方向,计算其垂直方向上一定距离(1.5 * ps)处的两个点的坐标
x1 = round(x0 + 1.5 * ps * cos(t0 + pi / 2));
y1 = round(y0 + 1.5 * ps * sin(t0 + pi / 2));
x2 = round(x0 + 1.5 * ps * cos(t0 - pi / 2));
y2 = round(y0 + 1.5 * ps * sin(t0 - pi / 2));
% 确保计算出的坐标在图像范围内,若超出则跳过当前循环
if (x1 < 1 || x1 > h || x2 < 1 || x2 > h || y1 < 1 || y1 > w || y2 < 1 || y2 > w)
continue;
end
% 将坐标转换为无符号32位整数类型,以符合图像像素坐标的数据类型要求
x1 = uint32(x1);
y1 = uint32(y1);
x2 = uint32(x2);
y2 = uint32(y2);
% 遍历三个颜色通道,计算边界点两侧一定范围内像素点的最大颜色通道值和最小颜色通道值,
% 并累加到相应向量中
for i = 1:3
v1 = Id(x1, y1, i);
v2 = Id(x2, y2, i);
maxv = max([v1, v2]);
minv = min([v1, v2]);
aCh(i) = aCh(i) + maxv;
aChs(i) = aChs(i) + minv;
end
end
% 计算平均的最大颜色通道值,即将累加的最大颜色通道值除以边界点数量
aCh = aCh./ npt;
% 重置边界点数量为0,用于后续重新计数
npt = 0;
% 遍历图像的所有像素点,对于掩码mask中标记为1的像素点(即阴影区域内的像素点),
% 累加其颜色通道值到aChs向量中,并计数
for i = 1:h
for j = 1:w
if (mask(i, j) == 1)
for ch = 1:3
aChs(ch) = aChs(ch) + Id(i, j, ch);
end
npt = npt + 1;
end
end
end
% 计算平均的最小颜色通道值,即将累加的最小颜色通道值除以阴影区域内的像素点数量
aChs = aChs./ npt;
% 计算颜色通道比例因子,用于后续调整阴影区域内像素点的颜色值
sl = zeros(h, w, 3);
chs = aCh./ aChs;
% 遍历图像的所有像素点,根据掩码mask的值对像素点的颜色值进行调整
% 对于掩码中标记为1的像素点(阴影区域内),按照计算出的比例因子调整其颜色值
% 对于掩码中标记为0的像素点(非阴影区域),保持其原始颜色值不变
for i = 1:h
for j = 1:w
if (mask(i, j) == 1)
for ch = 1:3
sl(i, j, ch) = (chs(ch) + 1) * ImgIn(i, j, ch);
end
else
sl(i, j, :) = ImgIn(i, j, :);
end
end
end
% 将处理后的图像数据类型转换为无符号8位整数类型,符合图像像素值的常见数据类型要求
sl = uint8(sl);
% 将处理后的图像数据赋值给输出图像ImgOut,完成去除阴影及边缘处理的操作
ImgOut = sl;
end
22
5.仿真结果
6.完整程序下载
完整可运行代码,博主已上传至优快云,使用版本为matlab2022a:
https://download.youkuaiyun.com/download/ccsss22/90018505?spm=1001.2014.3001.5503