概念
直方图:亮度直方图表示每个亮度级在图像中的占有率,图像对比度是通过亮度级范围来度量的,而直方图所示的是特定亮度级像素点的数目。
直方图拉伸和直方图均衡化是两种常见的间接对比度增强方法。直方图拉伸是通过对比度拉伸对直方图进行调整,从而扩大前景和背景灰度的差别,以达到增强对比度的目的,这种方法可以利用线性或非线性的方法来实现;直方图均衡化则通过使用累积函数对灰度值进行“调整”以实现对比度的增强。
直方图正规化
直方图正规化(histogram normalization)是常见的扩展亮度级的方法,将原直方图进行扩展和位移,使直方图涵盖所有256个亮度级。
matlab代码实现:
function normalization()
close all;
clear all;
clc;
I = imread('3.jpg');
set(gcf, 'outerposition', get(0, 'screensize'));
grayI = rgb2gray(I);
subplot(221);
imshow(grayI, []);
title('原始灰度图像');
%原始灰度图像直方图
subplot(222);
imhist(grayI, 255);
title('直方图');
%直方图正规化
grayI = double(grayI);
[rows, cols] = size(grayI);
minim = min(min(grayI));
range = max(max(grayI)) - minim;
range = double(range);
for x = 1 : rows
for y = 1 : cols
grayI(x,y) = floor(((grayI(x,y)-minim)*255)/range);
end
end
%直方图正规化后的图像
subplot(223);
imshow(grayI, []);
title('正规化灰度图像');
%正规化后的直方图
subplot(224);
imhist(uint8(grayI), 255);
title('正规化直方图');
效果图如下:
直方图均衡化
直方图均衡化是一个非线性处理过程,映射函数满足单调递增,且存在上下确界,增强局部对比。
matlab代码实现:
function equalization()
close all;
clear all;
clc;
I = imread('2.jpg');
set(gcf, 'outerposition', get(0, 'screensize'));
grayI = rgb2gray(I);
subplot(221);
imshow(grayI, []);
title('原始灰度图像');
%原始灰度图直方图
subplot(222);
imhist(grayI, 225);
title('原始灰度图直方图');
dict = zeros(256, 1);
[rows, cols] = size(grayI);
for i = 1 : rows
for j = 1 : cols
dict(grayI(i, j) + 1, 1) = dict(grayI(i, j) + 1, 1) + 1;
end
end
sum = 0;
for k = 0 : 255
sum = sum + dict(k + 1, 1);
dict(k + 1, 1) = floor((sum*255)/(rows*cols)+0.000001);
end
for m = 1 : rows
for n = 1 : cols
grayI(m, n) = dict(grayI(m, n) + 1, 1);
end
end
subplot(223);
imshow(grayI);
title('均衡化后的灰度图像');
%均衡化后的直方图
subplot(224);
imhist(grayI, 255);
title('均衡化后的直方图');
end
效果图如下:
阈值处理
ostu阈值处理图像二值化问题,通过定义类间差来选择最优的阈值。类间差用来表征阈值左右两个区域间灰度值差别程度,差别程度越大,说明边界部分大致分到了一边,非边界被分到另一边。
matlab实现代码:
function Otsu()
close all
clear all
clc
I = imread('1.jpg');
set(gcf, 'outerposition', get(0, 'screensize'));
I = rgb2gray(I);
subplot(121);
imshow(I);
title('原始图像');
[rows, cols] = size(I);
dict = zeros(256, 1);
prob = zeros(256, 1);
mean = 0;
mean1 = zeros(256, 1);
mean2 = zeros(256, 1);
for i = 1 : rows
for j = 1 : cols
dict(I(i,j) + 1, 1) = dict(I(i,j) + 1, 1) + 1;
end
end
prob(1) = dict(1, 1)/rows/cols + 0.00000001;
for k = 2 : 256
prob(k, 1) = prob(k-1) + dict(k, 1)/rows/cols;
end
for m = 1 : 256
mean = mean + dict(m, 1) * (m - 1);
end
mean = mean/rows/cols + 0.0000001;
mean1(1, 1) = 0.00000001;
mean2(1, 1) = mean;
for n = 2 : 256
mean1(n, 1) = mean1(n-1, 1) * dict(n-1, 1) + dict(n, 1) * (n - 1);
dict(n, 1) = dict(n, 1) + dict(n-1, 1);
if(dict(n, 1) > 0)
mean1(n, 1) = mean1(n, 1)/dict(n, 1);
mean2(n, 1) = mean - mean1(n, 1);
else
mean1(n, 1) = 0.00000001;
mean2(n, 1) = mean;
end
end
sigma = 0;
threshold = 0;
for s = 1 : 256
if(prob(s, 1) * (1-prob(s, 1)) * (mean1(s, 1)-mean2(s, 1)) * (mean1(s, 1)-mean2(s, 1)) > sigma)
threshold = s - 1;
sigma = prob(s, 1) * (1-prob(s, 1)) * (mean1(s, 1)-mean2(s, 1)) * (mean1(s, 1)-mean2(s, 1));
end
end
for r = 1 : rows
for c = 1 : cols
if(I(r,c) >= threshold)
I(r,c) = 255;
else
I(r,c) = 0;
end
end
end
subplot(122);
imshow(I);
title('二值图像');
效果图如下: