【数字图像处理】实验三 图像增强2

1 实验目的

  1. 理解并掌握直方图均衡化实现图像增强。
  2. 掌握傅里叶变换和离散余弦变换。

2 实验环境

matlab

3 实验内容

1、对一幅低对比度分辨率的图像采用直方图均衡化方法实现图像增强,分别采用系统函数和自己编写函数实现相应用功能。

  • 使用系统函数
% lab311.m
close all;
clear;
clc;

I=imread('lab3.jpeg');%读取图像
I=rgb2gray(I);
J=histeq(I);%将灰度拉伸,使图像不会显得那么黑,有了更好的对比度

figure('NumberTitle','off','name','直方图均衡化(系统函数)');
%显示各图像
subplot(2,2,1);     imshow(I);     title('原始图像','FontName','宋体');
subplot(2,2,2);     imhist(I);     title('灰度直方图','FontName','宋体');   ylim('auto');
subplot(2,2,3);     imshow(J);     title('直方图均衡化(系统函数)','FontName','宋体');
subplot(2,2,4);     imhist(J);     title('灰度直方图','FontName','宋体');   ylim('auto');
  • 使用自定义函数
%1)lab312.m
close all;
clear;
clc;

I=imread('lab3.jpeg');%读取图像
I=rgb2gray(I);
J=histSYX(I);
figure('NumberTitle','off','name','直方图均衡化(自定义函数)');
%显示各图像
subplot(2,2,1);     imshow(I);     title('原始图像','FontName','宋体');
subplot(2,2,2);     imhist(I);     title('灰度直方图','FontName','宋体');   ylim('auto');
subplot(2,2,3);     imshow(J);     title('直方图均衡化(自定义函数)','FontName','宋体');
subplot(2,2,4);     imhist(J);     title('灰度直方图','FontName','宋体');   ylim('auto');
2)自定义直方图均衡化histSYX.m
function J=histSYX(I)

[width,height]=size(I);
count=width*height;			%像素总数

% J=zeros(width,height);
J=I;

n=256;%灰度级

H=zeros(1,n);
for row=1:width
    for col=1:height
        k=I(row,col);			%该像素灰度值rk
        H(k+1)=H(k+1)+1;		%统计各灰度级pixel总数nk
    end
end
pr=H./count;					%计算原始直方图的概率分布pr(rk)=nk/n

sk=zeros(1,n);
Sk=zeros(1,n);
for loc1=1:n
    for loc2=1:loc1
        sk(loc1)=sk(loc1)+pr(loc2);		%计算累计直方图的概率分布sk=Σnj/n(j=0~k)
    end
    Sk(loc1)=round(((n-1)-0)*sk(loc1));	%取整扩展
end

for row=1:width
    for col=1:height
        k=I(row,col);
        J(row,col)=Sk(k+1);				%映射
    end
end

直方图均衡化——系统函数
直方图均衡化——系统函数
直方图均衡化——自定义函数
直方图均衡化——自定义函数

2、对一幅图像分别进行傅里叶变换和离散余弦变换,并把傅里叶变换直流分量移到频谱中心。

  • 傅里叶变换
%1)主函数lab321.m
close all;
clear;
clc;
I=imread('lab32.jpeg');
I=rgb2gray(I);
I=im2double(I);
F= DFT(I);

figure('NumberTitle','off','name','傅里叶变换');
%显示各图像
subplot(1,2,1);     imshow(I);     title('原始图像','FontName','宋体');
subplot(1,2,2);     imshow(F,[]);     title('傅里叶正变换','FontName','宋体');

%系统函数实现
% J=rgb2gray(I);      %对于RGB图像必须做的一步,也可以用im2double函数
% F=fft2(J);          %傅里叶变换
% F1=log(abs(F)+1);   %取模并进行缩放
% 
% Fs=fftshift(F);      %将频谱图中零频率成分移动至频谱图中心
% S=log(abs(Fs)+1);    %取模并进行缩放
% fr=real(ifft2(ifftshift(Fs)));  %频率域反变换到空间域,并取实部
% ret=im2uint8(mat2gray(fr));     %更改图像类型
% 将逆转换得到的矩阵先转换为灰度图像(mat2gray),再将图像类型转换为uint8
% 若在开头已经rgb2gray,则此步骤可省去,直接显示经逆转换的图像。
% 若在开头调用im2double,此步省略后可显示出彩色图像。
% subplot(2,2,1);imshow(I);title('原始图像','FontName','宋体');
% subplot(2,2,2);imshow(F1,[]);title('傅里叶正变换','FontName','宋体');
% subplot(2,2,3);imshow(S,[]);title('频移后的频谱图','FontName','宋体');
% subplot(2,2,4);imshow(ret),title('傅里叶逆变换','FontName','宋体');
%2)自定义傅里叶变换函数(含频移)DFT.m
function F= DFT(image)

[M,N] = size(image);
F=zeros(M,N);
temp=zeros(M,N);
j= 0+1i;

%分离
for x=1:M
    for v=1:N
        point=0;
        for y=1:N
            point=point+image(x,y)*exp(-j*2*pi*(v-1)*(y-1)/N);
        end
        temp(x,v)=point;
    end
end

for u=1:M
    for v=1:N
        point=0;
        for x=1:M
            point=point+temp(x,v)*exp(-j*2*pi*(u-1)*(x-1)/M);
        end
        F(u,v)=point;
    end
end

%不分离
% for u =1:M
%     for v= 1:N
%         point=0;
%         for x=1:M
%             for y=1:N
%                 point=point+image(x,y)*exp(-j*2*pi*((u-1)*(x-1)/M+(v-1)*(y-1)/N));
%             end
%         end
%         F(u,v)=point;
%     end
% end
F=fftshift(F);
F=log(abs(F)+1);
  • 离散余弦变换
%1)主函数lab322.m
close all;
clear;
clc;
I=imread('lab32.jpeg');
I=rgb2gray(I);
J=double(I);
F= DCT(J);

figure('NumberTitle','off','name','离散余弦变换');
%显示各图像
subplot(1,2,1);     imshow(I);     title('原始图像','FontName','宋体');
subplot(1,2,2);     imshow(F,[]);     title('离散余弦变换','FontName','宋体');
%2)自定义离散余弦变换函数DCT.m
function F= DCT(image)

[M,N] = size(image);
F=zeros(M,N);
temp=zeros(M,N);

Wu=pi/(2*M);
Wv=pi/(2*N);
Wn=sqrt(2/N);
Wm=sqrt(2/M);

%分离
for x=1:M
    for v=1:N
        if v==1
            Cv=1/sqrt(2);
        else
            Cv=1;
        end
        
        point=0;
        for y=1:N
            point=point+image(x,y)*cos((2*(y-1)+1)*(v-1)*Wv);
        end
        temp(x,v)=Cv*Wn*point;
    end
end

for u=1:M
    if u==1
        Cu=1/sqrt(2);
    else
        Cu=1;
    end
    for v=1:N
        point=0;
        for x=1:M
            point=point+temp(x,v)*cos((2*(x-1)+1)*(u-1)*Wu);
        end
        F(u,v)=Cu*Wm*point;
    end
end

%不分离
% for u =1:M
%     if u==1
%         Cu=1/sqrt(2);
%     else
%         Cu=1;
%     end
%     
%     for v= 1:N
%         if v==1
%             Cv=1/sqrt(2);
%         else
%             Cv=1;
%         end
%         
%         C=Cu*Cv;
%         point=0;
%         for x=1:M
%             for y=1:N
%                 point=point+image(x,y)*C*cos((2*(x-1)+1)*(u-1)*Wu)*cos((2*(y-1)+1)*(v-1)*Wv);
%             end
%         end
%         
%         F(u,v)=W*point;
%     end
% end
F=log(abs(F)+1);

傅里叶变换
傅里叶变换
离散余弦变换
离散余弦变换

4 实验心得

进一步理解了直方图均衡化以及利用傅里叶变换和离散余弦变换进行频域变换。

对于频域变换,需要注意几个问题:
【参考博客👉传送门

  1. imshow函数的使用。当图像是double类型时,要使用imshow(I,[])来根据数据矩阵的数值范围自动设置灰度图像显示范围。

  2. 警告: 显示复数输入项的实部。
    警告: 显示复数输入项的实部
    若图像经过傅里叶变换直接用imshow函数显示,会提示如上错误。这是由于经此时变换后的图像矩阵大多是复数矩阵,包含实部和虚部,在对图像进行显示前必须先用abs函数取复数矩阵的模,再进行显示。

  3. 对频谱取对数进行缩放log(abs(F)+1)。因为取模后图像矩阵的数值一般会很大,直接用imshow函数是无法显示的。对于(0,1)之间的值经过取对数后会变成负值,而log(F+1)则将所有的值映射到正数范围内。

  4. 使用不同的函数其变换效果也是不一样的。如使用im2double,进行傅里叶变换后其频谱图呈白色基调,使用rgb2gray其频谱图呈灰色基调。【未验证】

  • 18
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

社恐患者

赚钱不易呜呜呜

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值