本篇博文旨在向那些正在学习数字图像处理的同学们提供部分图像处理代码展示,本文所涉及的代码均使用matlab编译。
本文中的所有函数都不适用matlab自带的对应函数,均由自编函数实现。
function res=zhongshu(matrx)
%众数
s=matrx(:);%变更矩阵形式
[m,~]=size(s);%得到矩阵的行数
for i=1:m%得到每一个元素的在矩阵中的个数
s(i,2)=length(find(s(:,1)==s(i,1)));
end
msx_num=max(s(:,2));%得到众数在矩阵中存在的个数
num=find(s(:,2)==msx_num);%得到众数所在的行数
res=s(num,1);%得到众数,但是res中保存的是此矩阵中所有的此数字
res=unique(res);%去除多余的,每个众数只保留一个,唯一性。
end
function result=zhongzhi(DATA)
%中值
[N,t]=size(DATA);
s=[];%空矩阵
for k=1:t
A=DATA(:,k);%逐个波段进行
for i=1:N-1
for j=1:N-i
if A(j,1)>A(j+1,1)%冒泡法排序
w=A(j,1);
A(j,1)=A(j+1,1);
A(j+1,1)=w;
end
end
end
s(:,k)=A;%将排序之后的矩阵存放于s中
end
for k=1:t
if mod(N,2)~=0%对于奇偶分情况讨论
result(:,k)=s((N+1)/2,k);
else
result(:,k)=(s(N/2,k)+s(N/2+1,k))/2;
end
end
end
function result=paixu(DATA)
%将data矩阵进行列向由大到小排序
[N,t]=size(DATA);%得到data矩阵的行列数
for k=1:t%从第一列开始依次往后
A=DATA(:,k);
%A存储的是第k列排序之后的顺序
for i=1:N-1%使用冒泡法进行排序
for j=1:N-i
if A(j,1)>A(j+1,1)
w=A(j,1);
A(j,1)=A(j+1,1);
A(j+1,1)=w;
end
end
end
result(:,k)=A;%result是本函数的输出变量,将A赋予result
end
end
function [ans]=cov(matrx)
%按照波段数,依次得到两两波段之间的方差协方差构成矩阵
ans=[];
[~,~,k]=size(matrx);%得到波段数k
for i=1:k%两两波段之间相互组合,求取两者组合的协方差
for j=1:k
ans(i,j)=fangcha(matrx(:,:,i),matrx(:,:,j));
end
end
end
function [res]=fangcha (matrx_1,matrx_2)%求得两个矩阵的方差协方差
matrx_1=matrx_1(:);
matrx_2=matrx_2(:);%统一矩阵的行列数
[m,~]=size(matrx_1);
matrx_1_mean=mean(matrx_1(:));
matrx_2_mean=mean(matrx_2(:));%得到两矩阵的均值
sum=0;%sum为协方差公式的分子部分
for i=1:m
sum=sum+(matrx_1(i,1)-matrx_1_mean)*(matrx_2(i,1)-matrx_2_mean);
end
res=sum/(m-1);
end
function Xxgxs=corrcoef(data)
%求取不同波段之间的相关系数
XFC=cov(data);%先得到不同波段之间的协方差阵
[~,~,k]=size(data);
%得到波段数
for i=1:k
for j=1:i
if i==j
Xxgxs(i,j)=1;%自身与自身的相关系数为1,不用计算即可得到
else
Xxgxs(i,j)=XFC(j,i)/(XFC(i,i)*XFC(j,j));
Xxgxs(j,i)=XFC(j,i)/(XFC(i,i)*XFC(j,j));%按照相关系数的计算公式进行计算
end
end
end
end
function zhifangtu(s)
f=double(s);
g=zeros(1,256);
for i=1:256
g(i)=length(find(f==i));%find函数可以得到其位置,但是此处不需要位置,仅需个数,故用length函数取其个数
end
figure,bar(0:255,g);
function [s1,Y]=xianxinglashen(data)
%将图像灰度值进行线性拉伸
[p,q,m]=size(data);%得到矩阵得行列数以及波段数
N=p*q;
data=double(data);%uint8型数据类型不适于计算,需要将其转换为double型
for i=1:m%一个波段一个波段的进行
X=data(:,:,i);
m1=max(X(:));
m2=min(X(:));%得到第i个波段的最大数值以及最小数值
for j=1:p
for n=1:q
X(j,n,1)=255*(X(j,1)-m1)/(m2-m1);%对每一个数都进行线性拉伸
end
end
Y(:,:,i)=X;%一个波段处理完成后将其保存于Y矩阵内
end
s1=uint8(Y);%将最终的Y、矩阵再次转换为适于图形展开的uint8数据类型
end
function B=histoequal(A)
%直方图均衡化
[p,q]=size(A);%矩阵A的行列数
C=A(:);%改变矩阵A的形式
N=p*q;%矩阵A的值的总数
B=zeros(N,1); %零矩阵
[d1,m1]=histogram3(A);%使用函数histogram3
m2=size(d1,2);
d2=LJhistogram(d1);
d3=d2/N;
d3=round(d3*m1);%四舍五入约等
for i=1:N
B(i,1)=d3(1,C(i,1)+1);
end
[d4,~]=histogram3(B);
B=reshape(B,[p,q]);%重新构建矩阵
end
matrx=imread('hb.jpg');
matrx=rgb2gray(matrx);
figure,imshow(matrx);title('原图像')
figure,imhist(matrx);title('原图像直方图')
matrx=double(matrx);
[a,b,~]=size(matrx);
N=a*b;
x=matrx(:);
x_sorted=sort(x);
L_1=max(x_sorted);
value_count=zeros(256,3);
sun=0;
for i=0:255
value_count(i+1,1)=i;
temp=length(find(x_sorted==i));
value_count(i+1,2)=temp;
sun=sun+temp;
value_count(i+1,3)=sun;
end
new_value=round(L_1/N*value_count(:,3));
for i=1:256
if new_value(i,1)~=value_count(i,1)
for d=1:a
for j=1:b
if matrx(d,j)==value_count(i,1)
matrx(d,j)=new_value(i,1);
end
end
end
end
end
matrx=uint8(matrx);
figure,imshow(matrx);
title('均衡化之后')
figure,imhist(matrx);
title('均衡化后直方图');
function [B,M]=histogramatch(A,C)
[p,q]=size(A);%原图像的大小
[m,n]=size(C);%参考图像的大小
N1=p*q;%原图像总像素的个数
N2=m*n;%参考图像总像素的个数
a=A(:);
c=C(:);
[D1,m1]=histogram3(A);
Q1=LJhistogram(D1);
Q1=Q1/N1;
[D2,m2]=histogram3(C);
Q2=LJhistogram(D2);
Q2=Q2/N2;
J=zeros(1,size(D1,2));%零矩阵
m3=min(c);%求最小值
m3=uint16(m3);
m2=uint16(m2);%转换数据类型为uint8
for i=1:size(D1,2)
mi=1000;
for j=m3+1:m2+1
if abs(abs(Q1(1,i))-abs(Q2(1,j)))<mi
mi=abs(abs(Q1(1,i))-abs(Q2(1,j)));
k=j-1;
end
end
J(1,i)=k;
end
B=zeros(N1,1);
for i=1:N1
k=a(i,1);
k=uint16(k);%转换数据类型为uint8
B(i,1)=J(1,k+1);
End
[D3,~]=histogram3(B);
B=reshape(B,[p,q]);%重构矩阵
M=uint8(B);%转换数据类型为uint8
end
function img=junzhilvbo(A,muban)
%中值滤波
[p,q]=size(A);%矩阵A的行列数
X=double(A);%uint8类型不适于计算,故转换为double型
x=X;
half=floor(muban/2);
n=ones(muban);
smuban=muban^2;
for i=1:p-muban+1
for j=1:q-muban+1
xx=X(i:i+muban-1,j:j+muban-1).*n;%依次取muban阶矩阵进行操作
y=(sum(sum(xx)))/smuban;%取均值
x(i+half,j+half)=y;%用均值取代中间位置的数字
end
end
img=uint8(x);%重新转换为uint8数据类型
end
function img=zhongzhilvbo(A,muban)
[p,q]=size(A);
X=double(A);%uint8型不适于计算,需要将其转换为double型
x=X;
half=floor(muban/2);
half2=ceil(muban^2/2);
for i=1:p-muban+1
for j=1:q-muban+1
xx=X(i:i+muban-1,j:j+muban-1);%依次取muban阶矩阵进行操作
xx=xx(:);%将矩阵变为列矩阵
xx=sort(xx);%排序方便取中值
y=xx(half2,1);
x(i+half,j+half)=y;%用中值取代原先的值
end
end
img=uint8(x);%将其转换为uint8型,适于展图
end
function img=sobel(A,n)
%sobel算子锐化
[p,q]=size(A);
X=double(A);%转换为double型
x=X;
half=floor(n/2);
m1=[-1,0,1;-2,0,2;-1,0,1];
m2=[-1,-2,-1;0,0,0;1,2,1];
for i=1:p-n+1
for j=1:q-n+1
n1=X(i:i+n-1,j:j+n-1).*m1;%与sobel算子点乘
n1=sum(sum(n1));
n2=X(i:i+n-1,j:j+n-1).*m2;%与sobel算子点乘
n2=sum(sum(n2));
n3=abs(n1)+abs(n2);%绝对值相加
x(i+half,j+half)=n3;%用sobel算子计算结果取代原先的数值
end
end
img=uint8(x);%转换为uint8型数据
end
function img=prewitt(A,n)
[p,q]=size(A);
X=double(A);%转换为double型
x=X;
half=floor(n/2);
m1=[-1,-1,-1;0,0,0;1,1,1];
m2=[-1,-0,1;-1,0,1;-1,0,1];
for i=1:p-n+1
for j=1:q-n+1
n1=X(i:i+n-1,j:j+n-1).*m1;%与prewitt算子点乘
n1=sum(sum(n1));
n2=X(i:i+n-1,j:j+n-1).*m2;%与prewitt算子点乘
n2=sum(sum(n2));
n3=abs(n1)+abs(n2);%绝对值相加
x(i+half,j+half)=n3;%用prewitt算子计算结果取代原先的数值
end
end
img=uint8(x);%转换为uint8型数据
end
function [s1,s22]=rgb2hsi(R,G,B)
%将rgb转换为hsi
[p,q]=size(R);%得到r、g、b的行列数
r=double(R);
g=double(G);
b=double(B);%uint8型数据不适于计算,将其转换为double型
m=((r-g)+(r-b))/2;
n=sqrt((r-g).*(r-g)+(r-b).*(g-b));
th=acos(m./(n+eps));%得到角度sita的值
I=(r+g+b)/3;
c=max(max(I));%i中的最大值
I=I/c;%得到i的值
S=1-3*min(min(r,g),b)./(r+g+b);
H=th;
H(g<b)=2*pi-H(g<b);%当g<b时,进行此操作,覆盖上一步操作的结果
H=H/(2*pi);%有可能出现大于360度的情况
s1=cat(3,H,S,I);
s2=cat(3,r,g,b);
subplot(2,1,1)
s2=uint8(s2);
imshow(s2);
title('原RGB图像')
hold on
subplot(2,1,2)
s22=s1;%s1为0~1的小数形式
s1=im2uint8(s1);%转化为0~255的范围
imshow(s22);
title('HSI图像')
end
function rgb=hsi2rgb(HSI)
%将hsi空间中的图像转换到rgb空间中去
hsi=im2double(HSI);%转换为double型数据方便计算
p=size(HSI,1);
q=size(HSI,2);%得到矩阵的大小
h=hsi(:,:,1)*2*pi;
s=hsi(:,:,2);
i=hsi(:,:,3);
r=zeros(p,q);
g=zeros(p,q);
b=zeros(p,q);%生成零矩阵
m=find(h>=0&h<2*pi/3);%确定H的位置
b(m)=i(m).*(1-s(m));
r(m)=i(m).*(1+s(m).*cos(h(m))./cos((pi/3)-h(m)));
g(m)=3*i(m)-(r(m)+b(m));
m=find(h>=2*pi/3&h<4*pi/3);%以下进行分情况讨论,按照h角度的不同大小进行分类
h(m)=h(m)-2*pi/3;
r(m)=i(m).*(1-s(m));
g(m)=i(m).*(1+s(m).*cos(h(m)./cos(pi/3-h(m))));
b(m)=3*i(m)-(r(m)+g(m));
m=find(h>=4*pi/3&h<=2*pi);
h(m)=h(m)-4*pi/3;
g(m)=i(m).*(1-s(m));
b(m)=i(m).*(1+s(m).*cos(h(m)./cos(pi/3-h(m))));
r(m)=3*i(m)-(b(m)+g(m));
rgb=cat(3,r,g,b);
rgb=max(min(rgb,1),0);
rgb=im2uint8(rgb);
subplot(2,1,1)
imshow(HSI);
title('HSI图像')
hold on
subplot(2,1,2)
imshow(rgb);
title('RGB图像')
end
function [res]=k_l(image)
%主成分分析
[row,~]=size(image);%得到行列数
image_mean=mean(image);%得到每一列的均值
image_temp_mean=repmat(image_mean,row,1);%将矩阵向下复制延伸
image_cov=cov(image);%求得协方差阵
[a,b]=eigs(image_cov);%按照特征值的排序依次获得对应的特征向量
res=(image-image_temp_mean)*a;
end
function [res]=mix_brovey(image_1,image_2)
figure,imshow(image_1);
figure,imshow(image_2);%展示原始的两个图像
x=double(image_1);y=double(image_2);%image_2 为全色影像 image_1 为高光谱灰度影像
[a,b,~]=size(y);
[m,n,~]=size(x);
for k=1:3
x(:,:,k)=imsize(x(:,:,k),[a,b],nearest);%以全色影像为标准,将高光谱影像与之拟合
end
res=zero(a,b,3);%生成零矩阵
for k=1:3
res(:,:,k)=y.*x(:,:,k)./(x(:,:,1)+x(:,:,2)+x(:,:,3)); %进行brovey运算
end
res=uing8(res);%转换为uint8型数据
figure,imshow(res);%展图
function [res]=multiply(image_high,image_lot)
[m,n,~]=size(image_lot);
[a,b,~]=size(image_high);%得到两矩阵的行列数
image_lot=double(image_lot);
image_high=double(image_high);%变为double型,适于计算
for k=1:3
image_high(:,:,k)=imsize(image_high(:,:,k),[m,n],nearest);%以全色影像为标准,将高光谱影像与之拟合
end
res=zero(a,b,3);%得到零矩阵
for k=1:3
res(:,:,k)=image_high.*image_lot(:,:,k);%两矩阵对应位置相乘,进行融合
end
res=uing8(res);%转换为uint8型
figure,imshow(res);%展图
end
function output=pca(pan,mul)
%pca图像融合算法
[p,q]=size(pan);%行列数
M=BilineInter(mul,p,q);
[V,D,pcM]=PCA(M);%使用函数pca
[pa,~]=histogramatch(pan,pcM(:,:,1));
pcM(:,:,1)=pa;
PC=reshape(pcM,[p*q,size(mul,3)]);
PC=double(PC);%转变数据类型为double型
output=PC*V';
k=size(mul,3);%行列数
out=reshape(output,[p,q,k]);%重构矩阵
out=uint8(out);%由double型转为uint8型
end
function output=hsi(mul,pan)
%hsi图像融合
[p,q]=size(pan);%矩阵的大小
RGB=BilineInter(mul,p,q);
%将rgb空间中的图像转换到hsi空间中去
hsi=rgb2hsi(RGB(:,:,1),RGB(:,:,2),RGB(:,:,3));
H=hsi(:,:,1);
S=hsi(:,:,2);
I=hsi(:,:,3);%分别取得hsi三个波段的矩阵
c=histogramatch(pan,I);
hsi2=cat(3,H,S,c);%组合成新的hsi空间中的图像
output=hsi2rgb(hsi2);%将hsi中的图像转换到rgb空间中去
output=uint8(output);%转换为uint8型数据便于图像展示
end
function [d2,k,t1]=yuzhifenge(data)
%迭代阈值分割
[m,n]=size(data);
a=data(:);
ave=mean(a);%均值
t1=ave;%t的初始值用均值
t2=10000;
d2=zeros(m*n,1);%零矩阵
k=0;
while(abs(t1-t2)>0.05)%循环结束的条件:当两个次求取的t的差值绝对值小于一个给定数字时,迭代结束
c1=double(0);c2=double(0);i1=double(0);i2=double(0);
for p=1:size(a)
if a(p,1)<t1
c1=c1+double(a(p,1));
i1=i1+1;
else
c2=c2+double(a(p,1));
i2=i2+1;
end
end
t2=t1;
t1=(double(c1)/double(i1)+double(c2)/double(i2))/2;
k=k+1;
end
for p=1:size(a)%依次进行选择
if a(p,1)<t1
d2(p,1)=255;
else
d2(p,1)=0;
end
end
d2=reshape(d2,m,n);%重新构建矩阵
d2=uint8(d2);%转变数据类型
end
function flag=k_means(data,ave)
[m,n,p]=size(data);%行列数以及波段数
[k,t]=size(ave);
a=reshape(data,m*n,p);
ave2=zeros(k,t);
while abs(max(ave2-ave))>1%循环结束的条件
[flag,ave2]=Shortdis(a,ave);
temp=ave;
ave=ave2;
ave2=temp;
end
flag=reshape(flag,m,n) ; %重构矩阵
end
function [flag,ave]=Shortdis(a,mc)
%此函数实现按平均值对图像进行重分类并计算平均值
%mc为样本的平均值
[N,~]=size(a);
[k,q]=size(mc);
flag=zeros(N,1);
ave=zeros(k,q);%零矩阵
for i=1:N
a1=a(i,:);
d1=sqrt(sum((a1-mc(1,:)).^2));
p=1;
for j=2:k
d2=sqrt(sum((a1-mc(j,:)).^2));
if d2<d1
d1=d2;
p=j;
end
end
flag(i,1)=p;
end
for i=1:k
ave(i,:)=mean(a(flag==i,:));
end
end
function flag= zuidasiran(data,mc)
%最大似然分类方法,data为待分类影响
%mc为已经选取好的分类样本,为n*1的元胞数组
[m,n,p]=size(data);%得到矩阵的大小
[k,~]=size(mc);%得到矩阵的大小
a=reshape(data,m*n,p);%重新构造矩阵
flag=zeros(m*n,1);%生成零矩阵
ave=zeros(k,1);%生成零矩阵
thi=zeros(k,1);%生成零矩阵
for i=1:k
ave(i,1)=mean(mc{i,1});%均值
thi(i,1)=cov(mc{i,1});%方差协方差阵
end
for i=1:m*n
a1=a(i,:);
f1=exp(-(a1-ave(1,1))^2/(2*thi(1,1)))/sqrt(2*pi*thi(1,1));
p=1;
for j=2:k
f2=exp(-(a1-ave(j,1))^2/(2*thi(j,1)))/sqrt(2*pi*thi(j,1));
if f1<f2
p=j;
f1=f2;
end
end
if f1<0.3
flag(i,1)=k+1;
else
flag(i,1)=p;
end
end
flag=reshape(flag,m,n);%重新构造矩阵
imagesc(flag);
end
function flag= zuiduanjulifenlei(data,mc)
%马氏距离的监督分类
%data为待分类影响
%mc为已经选取好的分类样本,每个类构成一个矩阵,矩阵的每一行是一个样本
%矩阵的列数必须与data的波段数相同
[m,n,p]=size(data);%得到矩阵的大小
[k,~]=size(mc);%得到矩阵的大小
a=reshape(data,m*n,p);%重新构造矩阵
flag=zeros(m*n,1);%生成零矩阵
for i=1:m*n
a1=a(i,:);
c1=inv((cov(mc{1,:})));
ave=mean(mc{1,:});%均值
d1=sqrt((a1-ave)*c1*(a1-ave)');
p=1;
for j=2:k
c1=inv((cov(mc{k,:})));
ave=mean(mc{k,:});%均值
d=sqrt((a1-ave)*c1*(a1-ave)');
if d1>d
p=j;
d1=d;
end
end
flag(i,1)=p;
end
flag=reshape(flag,m,n);%均值
end