数字图像处理之点运算---分段线性变换

一.理论概要
1.对比度拉伸
利用分段线性函数来增强图像对比度的方法实际上增强原图各部分的反差,即增加图像中感兴趣的灰度区域,相对抑制那些不感兴趣的灰度区域。
分段的灰度拉伸可以更加灵活的控制输出灰度直方图的分布,可以有选择性的拉伸某段灰度区间,以改善输出图像。如果一副图像集中在较暗的区域而导致图像偏暗,可以用灰度拉伸功能来扩展(斜率>1)物体的灰度区间以改善图像;同样,如果图像的灰度集中在较亮的区域而导致图像偏亮,也可以用灰度拉伸功能来压缩(斜率小于1)物体灰度区间以改善图像质量。
2.灰度级分层
这个主要是实现其实就是让一定范围的灰度值保持不变,需要突出的部分进行变换,也可以实现阈值变换,以及实现最常用的二值化图像。
3.比特平面分层
这个原理更加简单,高比特平面包含了更多的信息,而低比特平面贡献了更精细的灰度细节。简单说就是通过阈值变换函数处理输入图像得到二值图像,比如第八个比特平面就是将0-127之间的灰度值映射为0,128-255之间的灰度映射为1。
二.matlab实现:
(一).对比度拉伸
(1)首先我们想实现 下面分段函数的对比度拉伸
在这里插入图片描述
下面代码绘制这个曲线图,代码写的比较繁琐,但是好理解。

figure;
x1=0:0.001:X1;
y1=Y1/X1*x1;
plot(x1,y1)
hold on
x2=X1:0.001:X2;
y2=(Y2-Y1)/(X2-X1)*(x2-X1)+Y1;
plot(x2,y2);
hold on
x3=X2:0.001:1;
y3=(Y2-1)/(X2-1)*(x3-X2)+Y2;
plot(x3,y3);
hold on
x4=0:0.001:1;   
y4=x4;
plot(x4,y4);
hold on

下面代码实现了图像灰度值的分段函数变换

I=imread('coins.png');  %读入原图像
subplot(2,2,1);
imshow(I,[]);%显示原图像
title('原图像');
%分段线性变换
[M,N]=size(I);
I=im2double(I);
out=zeros(M,N);
X1=0.3;Y1=0.15;
X2=0.7;Y2=0.85;
for i=1:M
    for j=1:N
        if I(i,j)<X1
            out(i,j)=Y1*I(i,j)/X1;
        elseif I(i,j)>X2
            out(i,j)=(I(i,j)-X2)*(1-Y2)/(1-X2)+Y2;
        else
            out(i,j)=(I(i,j)-X1)*(Y2-Y1)/(X2-X1)+Y1;
        end
    end
end
subplot(2,2,2);
imshow(out,[]);
title('变换后图像')
%绘制直方图
subplot(2,2,3);
imhist(I);
title('原图像');
subplot(2,2,4);
imhist(out);
title('变换后图像')

其中主要的分段函数实现部分如下,利用了两个循环嵌套对图像的数组进行遍历。

for i=1:M
    for j=1:N
        if I(i,j)<X1
            out(i,j)=Y1*I(i,j)/X1;
        elseif I(i,j)>X2
            out(i,j)=(I(i,j)-X2)*(1-Y2)/(1-X2)+Y2;
        else
            out(i,j)=(I(i,j)-X1)*(Y2-Y1)/(X2-X1)+Y1;
        end
    end
end

执行结果如下图所示:
在这里插入图片描述结合变换函数我们可知x<x1时斜率小于1,x1<x<x2时斜率大于1,x>x2时斜率小于1,根据灰度值的变换规律。

  1. 斜率影响图像的对比度,那么低灰度值的部分肯定被压缩,效果就是暗的部分更加暗,而且对比度更低,结果图像我们明显看出暗色的背景更加暗,而且结合直方图我们可以看出低灰度值部分向更低灰度值压缩,也就是低灰度值部分向x轴左侧偏移导致图像暗色部分更暗,而且低灰度部分灰度值分布范围变窄,导致此部分对比度降低。
  2. 与之对应的是高灰度值部分,我们可以由变换曲线可知此部分值增大,说明整体高灰度值部分向x轴右侧偏移,结果就是导致亮色的部分更加亮,这也从图像中可以明显观察出来,而此部分变换曲线斜率小于1,也就是说此部分灰度值范围得到了压缩,那么对比度降低,由直方图看出高灰度部分的范围确实缩小了,
  3. 而0.3-0.7这部分斜率大于1,对比度增强,但是由于选图的原因图像中并不明显,但是从直方图中很明显看到中间部分灰度值分布范围变宽,而且值分布变得均匀。

(二).阈值变换
实现的二值化图像的代码:

%灰度级分层/阈值变换
I=imread('coins.png');
thresh=graythresh(I);   %自适应确定阈值
bw1=im2bw(I,thresh);    %二值化
bw2=im2bw(I,130/255);   %手动实现二值化
figure;
subplot(1,3,1);
imshow(I);
title('原图像');
subplot(1,3,2);
imshow(bw1);
title('自动阈值');
subplot(1,3,3);
imshow(bw2);
title('手动阈值');

实现效果如下:
在这里插入图片描述
(三)比特平面分层
代码实现:

%比特面分层:第八比特面
I=imread('coins.png');
L=127;
[M,N]=size(I);
out8(M,N)=zeros();
for i=1:M
    for j=1:N
        if I(i,j)<127
            out8(i,j)=0;
        else
            out8(i,j)=1;
        end
    end
end
%比特面分层:第1比特面
L=1;
out1(M,N)=zeros();
for i=1:M
    for j=1:N
        if I(i,j)<L
            out1(i,j)=1;
        else
            out1(i,j)=0;
        end
    end
end
figure;
subplot(1,3,1);
imshow(I);
title('原图像');
subplot(1,3,2);
imshow(out8);
title('第8比特面');
subplot(1,3,3);
imshow(out1);
title('第1比特面');

运行结果:
在这里插入图片描述
四.代码
由于代码繁多,可在我的资源里边下载《分段线性变换》
五.总结
总之,要根据图像构造自己需要的分段线性函数是关键,先确定需要突出的部分或者要二值化的阈值是关键。

猜你喜欢

转载自blog.csdn.net/jxqbuct/article/details/89278444