MATLAB 中的 Gamma 校正实现
Gamma correction implementation in MATLAB
我正在尝试在 MATLAB 中执行伽玛校正功能,至少可以说,我得到了一些混合结果。使用低于 1 的伽玛常数(例如 0.5)会得到更亮的图像,而使用高于 1 的常数会得到更暗的图像,这是错误的,因为它应该给我相反的结果(常数低于 1 应该更暗且恒定高于 1 应该更亮)。
这是我一直在研究的代码,基于我在查看图像处理书籍时发现的以下公式:
f(v):= 255·(v/255) 1/GAMMA
其中(如果我理解正确的话)v 是输入图像,GAMMA 是常数。
这是 MATLAB 中的代码:
%%Fucnion de gamma
%%Entradas
%% I = imagen original
%% gamma = constante de gamma
%%Salidas
%% G = imagen transformada
function [G] = FuncionGamma(I,gamma)
G=zeros(size(I));
for i=1: size(I, 1)
for j=1: size(I, 2)
G(i,j) = double(255 * (I(i,j)/255)).^(1/gamma);
end
end
G=uint8(G);
end
这是调用它的脚本:
clc;
clear;
close all;
gamma = 0.5;
gamma2 = 1.5;
I = imread("mantis.jpg");
[IMG1] = FuncionGamma(I,gamma);
[IMG2] = FuncionGamma(I,gamma2);
figure;
imshow(IMG1);
figure;
imshow(IMG2);
结果如下:
原图:
伽玛 = 0.5
伽玛 = 1.5
我做错了什么?
注意你的括号:
G(i,j) = double(255 * (I(i,j)/255)).^(1/gamma);
G(i,j) = double( 255 * (I(i,j)/255) ) .^ (1/gamma);
^^^^^^^^^^^^^^^^^^
突出显示的部分已提升为 1/gamma
。您需要以不同的方式放置括号,以便首先计算幂,然后计算乘法。请注意,那里不需要 double
,但您可能希望在除法之前将 I
强制转换为 double(在 MATLAB 中将 uint8
除以 double 会产生 uint8
)。
此外,您根本不需要循环。 MATLAB 擅长一次性处理整个矩阵。您可以将函数简化为:
function G = FuncionGamma(I,gamma)
G = uint8( 255 * (double(I)/255).^(1/gamma) );
end
正如我在我参加的课程中学到的那样,你应该在你做映射之前缩放图像,至少对于灰度图像。我不确定彩色图片是否需要它。
function imgGamma = GammaMap(img,gamma)
imgTemp = double(img) % Create temporary image of type double
imgTemp = 1./255 % Before mapping, scale the image: g = f*(1/255)
img_temp = img_temp.^gamma; % Use the stretching formula
imgGamma = img_temp.*255; % After mapping, scale the image back, f = g*255
imgGamma = uint8(imgGamma); % Before returning the image, transform it to uint8
end
我正在尝试在 MATLAB 中执行伽玛校正功能,至少可以说,我得到了一些混合结果。使用低于 1 的伽玛常数(例如 0.5)会得到更亮的图像,而使用高于 1 的常数会得到更暗的图像,这是错误的,因为它应该给我相反的结果(常数低于 1 应该更暗且恒定高于 1 应该更亮)。
这是我一直在研究的代码,基于我在查看图像处理书籍时发现的以下公式:
f(v):= 255·(v/255) 1/GAMMA
其中(如果我理解正确的话)v 是输入图像,GAMMA 是常数。
这是 MATLAB 中的代码:
%%Fucnion de gamma
%%Entradas
%% I = imagen original
%% gamma = constante de gamma
%%Salidas
%% G = imagen transformada
function [G] = FuncionGamma(I,gamma)
G=zeros(size(I));
for i=1: size(I, 1)
for j=1: size(I, 2)
G(i,j) = double(255 * (I(i,j)/255)).^(1/gamma);
end
end
G=uint8(G);
end
这是调用它的脚本:
clc;
clear;
close all;
gamma = 0.5;
gamma2 = 1.5;
I = imread("mantis.jpg");
[IMG1] = FuncionGamma(I,gamma);
[IMG2] = FuncionGamma(I,gamma2);
figure;
imshow(IMG1);
figure;
imshow(IMG2);
结果如下:
原图:
伽玛 = 0.5
伽玛 = 1.5
我做错了什么?
注意你的括号:
G(i,j) = double(255 * (I(i,j)/255)).^(1/gamma);
G(i,j) = double( 255 * (I(i,j)/255) ) .^ (1/gamma);
^^^^^^^^^^^^^^^^^^
突出显示的部分已提升为 1/gamma
。您需要以不同的方式放置括号,以便首先计算幂,然后计算乘法。请注意,那里不需要 double
,但您可能希望在除法之前将 I
强制转换为 double(在 MATLAB 中将 uint8
除以 double 会产生 uint8
)。
此外,您根本不需要循环。 MATLAB 擅长一次性处理整个矩阵。您可以将函数简化为:
function G = FuncionGamma(I,gamma)
G = uint8( 255 * (double(I)/255).^(1/gamma) );
end
正如我在我参加的课程中学到的那样,你应该在你做映射之前缩放图像,至少对于灰度图像。我不确定彩色图片是否需要它。
function imgGamma = GammaMap(img,gamma)
imgTemp = double(img) % Create temporary image of type double
imgTemp = 1./255 % Before mapping, scale the image: g = f*(1/255)
img_temp = img_temp.^gamma; % Use the stretching formula
imgGamma = img_temp.*255; % After mapping, scale the image back, f = g*255
imgGamma = uint8(imgGamma); % Before returning the image, transform it to uint8
end