下面是的几个用MATLAB进行高光抑制的处理例子。
1. 基于最大值滤波的亮光抑制方法
原理是用某像素周围一定大小的邻域中的最大值减去该像素值,可达到亮光抑制的效果。在MATLAB中,可以使用mat2gray函数将图像归一化后,再使用imextendedmax函数进行最大值滤波,函数调用方式为:
ori = imread('ImageProcess/input/local.png');
sigma = 0.4;
alpha = 0.2;
beta = 0.5;
% imshow(ori)
fig = figure; % 返回句柄来进行图像保存
title('Traffic Light Diff');
% 同时显示出多中滤波对交通灯的处理方法,并在同一个数据面板上显示
subplot(3, 1, 1);
aug = locallapfilt(ori, sigma, alpha, beta);
imshowpair(ori, aug, 'montage');
subplot(3, 1, 2);
thresh = 0.4;
aug_I = imextendedmax(mat2gray(ori), thresh);
imshowpair(ori, aug_I, 'montage');
subplot(3, 1, 3);
% aug_I2 = imcomplement(imextendedmax(mat2gray(aug), 0.5)); % 取反操作
aug_I = imextendedmax(mat2gray(ori), thresh); % 获取高光部分区域
J = aug;
avg_val = mean(J(~aug_I)); % 将高光部分区域外的像素求平均值
J(aug_I) = avg_val;
imshowpair(ori, J, 'montage');
% 文件保存
save_path = strcat('ImageProcess/output/', 'figure', '.jpg');
saveas(fig, save_path);
其中,I为输入图像,thresh为一个介于0和1之间的阈值。
- 测试效果
2. 高亮区域gamma滤波
- 利用多个局部掩码辅助gamma滤波实现级层处理
ori = imread("input\local.png");
sigma = 0.4;
alpha = 0.2;
beta = 0.5;
Nsub = 5;
% imshow(ori)
fig = figure; % 返回句柄来进行图像保存
title('Traffic Light Diff');
% 1) 获取全局local laplacian filter处理图像
subplot(Nsub, 1, 1);
aug = locallapfilt(ori, sigma, alpha, beta);
imshowpair(ori, aug, 'montage');
% 2) 检测出高光区域
subplot(Nsub, 1, 2);
thresh = 0.70; % 数值越大区域越大
augI = imextendedmax(mat2gray(ori), thresh); % 高光区域
threshM = 0.6;
augM = imextendedmax(mat2gray(ori), threshM);
threshS = 0.4;
augS = imextendedmax(mat2gray(ori), threshS);
imshowpair(augI, augM, 'montage');
% 取反
% subplot(4, 1, 3);
% augI_inverse = imcomplement(augI);
% imshowpair(ori, augI_inverse, 'montage');
% 在拉普拉斯图像中获取高光区域部分
local = aug(augI);
localM = aug(augM);
localS = aug(augS);
% 对高光区域进行处理
local = imgaussfilt(local); % 2d高斯滤波
% 设置亮度降低的参数
% gamma = 1.6;
% low_in = 0; % 输入图像中的最低亮度值
% high_in = 80; % 输入图像中的最高亮度值
% low_out = 0; % 输出图像中的最低亮度值
% high_out = 10; % 输出图像中的最高亮度值
% local_gamma = imadjust( ...
% local_gaussf, ...
% [low_in/high_in, high_in/high_in], ...
% [low_out/high_out, high_out/high_out], ...
% gamma ...
% ); % gamma值越大越暗
gamma = 1.6;
local_gamma = imadjust(local, [], [], gamma);
gammaM = 2.4;
localM_gamma = imadjust(localM, [], [], gammaM);
gammaS = 3.2;
localS_gamma = imadjust(localS, [], [], gammaS);
subplot(Nsub, 1, 3);
J = aug;
J(augI) = local_gamma; % 对高光区域进行填充
J(augM) = localM_gamma;
J(augS) = localS_gamma;
imshowpair(augS, J, 'montage');
% 最后的效果对比
subplot(Nsub, 1, 4);
w = 0.8;
out = (1-w)*aug + w*J;
imshowpair(ori, out, 'montage');
subplot(Nsub, 1, 5);
imshowpair(aug, out, 'montage');
- 局部效果展示
将上面的主体函数构造成一个函数的形式,并保存到本地,这里涉及到了matlab字符串的使用。
img_path = 'input\car01.jpeg';
img_aug = local_highlight_restrain(img_path);
img = imread(img_path);
figure;
subplot(1,1,1);
imshowpair(img, img_aug, 'montage');
out_path = strrep(img_path, 'input', 'output');
imwrite(img_aug, out_path);
3. 进行取反后拉普拉斯处理
clear
clc
close all
ori = imread("input\local.png");
Nsub = 4;
% imshow(ori)
fig = figure; % 返回句柄来进行图像保存
% 1) 获取全局local laplacian filter处理图像
subplot(Nsub, 1, 1);
sigma = 0.4;
alpha = 0.2;
beta = 0.5;
aug_org = locallapfilt(ori, sigma, alpha, beta);
imshowpair(ori, aug_org, 'montage');
% 2) 检测出高光区域
thresh = 0.6; % 数值越大区域越大
augI = imextendedmax(mat2gray(ori), thresh); % 高光区域
% local = ori(augI);
% local = imgaussfilt(augI);
% local = medfilt2(uint8(augI*1));
H = fspecial('average',15);
local = imfilter(single(augI),H,'replicate');
subplot(Nsub, 1, 2);
ori_inverse = imcomplement(ori); % 取反
imshowpair(ori, ori_inverse, 'montage');
%
subplot(Nsub, 1, 3);
sigma = 0.2;
alpha = 0.25;
beta = 1;
aug = locallapfilt(ori_inverse, sigma, alpha, beta);
aug_inverse = imcomplement(aug);
imshowpair(aug, aug_inverse, 'montage');
subplot(Nsub, 1, 4);
out = double(local) .* double(aug_inverse) + (1 - double(local)) .* double(aug_org);
imshowpair(uint8(ori), uint8(out), 'montage');
4. 对高亮区域进行切分单独对子图处理后再拼接
clear;
clc;
Nsub = 5;
fig = figure; % 返回句柄来进行图像保存
ori = imread("input\local.png");
% 对滤波后的图像转为灰度图
sigma = 0.4;
alpha = 0.2;
beta = 0.5;
aug = locallapfilt(ori, sigma, alpha, beta);
grayImage = rgb2gray(aug); % 转换为灰度图像
subplot(Nsub, 1, 1);
imshowpair(aug, grayImage, 'montage');
% 对灰度图二值化处理
binaryImage = imbinarize(grayImage);
% 提取连通域
labeledImage = bwlabel(binaryImage);
% 计算每个连通域的边界框,格式为:[x, y, width, height]
stats = regionprops(labeledImage, 'BoundingBox');
% 过滤长度太小的边界框
minWidth = 9;
minHeight = 9;
boundingBoxes = zeros(0, 4);
for i = 1:numel(stats)
w = stats(i).BoundingBox(3);
h = stats(i).BoundingBox(4);
if w > minWidth && h > minHeight
boundingBoxes(end+1, :) = stats(i).BoundingBox;
end
end
% 绘制所有高亮部分的边界框
result = insertShape(aug, 'Rectangle', boundingBoxes, 'LineWidth', 2, 'Color', 'red');
subplot(Nsub, 1, 2);
imshowpair(aug, result, 'montage');
% 单独对高亮区域进行直方图均衡
% 对每个区域进行处理
gamma = 2.2;
J = aug;
for i = 1:size(boundingBoxes, 1)
boundingBox = boundingBoxes(i, :);
x = boundingBox(1);
y = boundingBox(2);
w = boundingBox(3);
h = boundingBox(4);
% 避免出现非整数
% subImage = J(y:y+h-1, x:x+w-1, :);
% subImage = imadjust(subImage, [], [], gamma);
% J(y:y+h-1, x:x+w-1, :) = subImage;
subImage = J(round(y):round(y+h-1), round(x):round(x+w-1), :);
% 对区域图进行图像处理
r = subImage(:, :, 1);
g = subImage(:, :, 2);
b = subImage(:, :, 3);
r_aug = adapthisteq(r,'clipLimit',0.1,'Distribution','rayleigh');
g_aug = adapthisteq(r,'clipLimit',0.1,'Distribution','rayleigh');
b_aug = adapthisteq(r,'clipLimit',0.1,'Distribution','rayleigh');
rgb = cat(3, r_aug, g_aug, b_aug);
% subImage = imadjust(subImage, [], [], gamma);
% 贴回去原图中
J(round(y):round(y+h-1), round(x):round(x+w-1), :) = rgb;
end
subplot(Nsub, 1, 3);
imshowpair(aug, J, 'montage');
% 用一个权重与原图进行叠加
w = 0.5;
out = w*J + (1-w)*ori;
subplot(Nsub, 1, 4);
imshowpair(ori, out, 'montage');
-
局部calth直方图处理
-
局部使用gamma
参考资料:https://ww2.mathworks.cn/help/index.html