注:本系列来自于图像处理课程实验,用Matlab实现最基本的图像处理算法
图像点处理是图像处理系列的基础,主要用于让我们熟悉Matlab图像处理的编程环境。灰度线性变换和灰度拉伸是对像素灰度值的变换操作,直方图是对像素灰度值的统计,直方图均衡是对灰度值分布的变换。
原图向灰度值为g,通过线性函数f(x)=kx+b
转换为f(g)得到灰度的线性变换。
Matlab中支持矩阵作为函数参数传入,定义一个线性转换函数,利用Matlab矩阵操作,用一行代码即可对整个二维图像矩阵中所有点的灰度进行线性变换:
function [ new ] = LinearTransformFunc( original, k, d )
new = original * k + d;
end
其中k和d是线性函数的斜率和截距,由用户输入指定,用户输入为空时赋予默认值:
input
函数获取用户输入isempty
判断用户输入是否为空:k = input(‘please input the slope(k) of grayscale linear transformation function:\n‘);
b = input(‘please input the intercept(b) of grayscale linear transformation function:\n‘);
if isempty(k)
k = 1;
end
if isempty(b)
b = 0;
end
变换图像名也可以由用户input
指定,默认为lena图:
imread
读出图片,返回值第一个是我们需要的灰度图(二维矩阵)imshow
在figure
中显示图像name = input(‘please input the name of image:\n‘);
if isempty(name)
name = ‘lena‘;
end
original = imread(strcat(‘../exp/‘, name, ‘.bmp‘));
transformed = LinearTransformFunc(original, k, b);
figure
imshow(transformed)
在这个实验的操作中说明如何读入、显示,后面实验不在赘述
利用subplot作图,把原图和线性变换后的图像对比,线性变换函数是f(x)=2x+10
:
左图是原图像,右图是线性变换后图像。
灰度拉伸变换和线性变换相似,只是是将灰度值做分段线性变换。分段函数控制点(x1,y1)
和(x2,y2)
:
整个程序用户接口和流程和线性变换相同,只是需要用户输入两个控制点,并传入以下的分段线性变换函数:
function [ new ] = StretchFunc(original, x1, y1, x2, y2 )
new = original;
w = size(new, 1);
h = size(new, 2);
k1 = y1 / x1;
dk1 = (y2 - y1) / (x2 - x1);
dk2 = (255 - y2) / (255 - x2);
for i = 1 : w
for j = 1 : h
x = new(i, j);
if x < x1
new(i, j) = k1 * x;
elseif x < x2
new(i, j) = dk1 * (x - x1) + y1;
else
new(i, j) = dk2 * (x - x2) + y2;
end
end
end
end
这里不可避免要使用到for循环。
同样对比原图,默认控制点选取(-100,20)和(100,180)
灰度直方图就是对图像中每个像素点的灰度值出现的频数或频率(归一化)的统计,那么我们直接遍历整个图像统计出每个灰度值出现次数再做相应处理即可。
首先需要遍历统计灰度,我在GrayScaleStatistic函数里完成统计,区间[low, high]是目标灰度统计区间,默认是[0,255]:
function [ result ] = GrayScaleStatistic( original, low, high )
w = size(original, 1);
h = size(original, 2);
result = zeros(1, high - low + 1);
for i = 1 : w
for j = 1 : h
g = original(i, j);
if g >= low && g <= high
g = g - low + 1;
result(g) = result(g) + 1;
end
end
end
end
然后就使用Matlab条形图作图函数bar
完成灰度图作图:
y = GrayScaleStatistic(original, low, high);
x = low : 1 : high;
bar(x, y)
对于题目要求的可输入灰度区间显示,我们要么不统计区间[low, high]以外的灰度值,要么直接全部统计但在作图时用xlim
函数限制x轴取值范围:
xlim([low, high])
对比Matlab标准直方图作图函数histogram
,结果如下:
也可以通过input输入限定区间,这里是[20,150]区间的灰度直方图:
左右对比,效果一致。
直方图均衡主要用于增强动态范围偏小的图像的反差,其基本思想是把原始图像的直方图变换为均匀分布,从而增强灰度值的动态范围,以达到增强对比度的效果。
直方图均衡化算法如下
sk
sk
计算频率累计直方图tk
,tk
做取整扩展:tk = int[(L - 1) * tk + 0.5]
,将直方图灰度映射尽量满整个灰度取值空间L
k->tk
在脚本中调用Normalize函数直接得到均衡化后的图像,再统计直方图并显示。
Normalize函数如下:
function [ new ] = Normalize( original, v )
s = sum(v);
tv = v / s;
l = length(v);
for i = 2 : l
tv(i) = tv(i) + tv(i - 1);
end
tk = uint8(255 * tv + 0.5);
w = size(original, 1);
h = size(original, 2);
new = original;
for i = 1 : w
for j = 1 : h
new(i, j) = tk(original(i, j) + 1);
end
end
end
说明:
其中有一下几点需要注意,也是Matlab图操作的注意点:
pout.bmp是一副灰度分布较为集中的图像,因此图像对比度不高,显示较为模糊。使用直方图均值化,分散灰度分布从而增强对比度:
通过对比均衡先后直方图分布,可以发现:
原文地址:http://blog.csdn.net/u014030117/article/details/46367021