Image Processing 第一次作业
Image Processing
张和东
True color image 与 color-map image之间的转换
读取一张color-map image,并写程序(不能调用matlab自带的函数)将其转换成true color image,并保存为一张jpg图片
程序:
clear
clc
%% read a colormap image
[ind,map]=imread('colormap0.tif');
figure
image(ind);
colormap(map)
axis image
title('ColormapImage')
%% convert a colormapped image to true color
TruecolorImage=zeros([size(ind),3]);
[w,h]=size(ind);
for i=1:w
for j=1:h
for c=1:3
TruecolorImage(i,j,c)=map(ind(i,j)+1,c);
end
end
end
figure
image(TruecolorImage)
axis image
title('TruecolorImage')
%% save image
imwrite(TruecolorImage,'TruecolorImage.jpg')
分析:
由color-map image得到true color image,就是计算true color image 上每一个像素点对应的值。通过color map image 找到每个像素点对应的像素值即可。由于转换之后保留了之前图像的所有信息,所以与原图完全一样。
效果比较:
<img src="http://images.cnblogs.com/cnblogs_com/zhanghedong/1055457/o_ColormapImage.png" width="330px">
<img src="http://images.cnblogs.com/cnblogs_com/zhanghedong/1055457/o_TruecolorImage.png" width="324px">
设计算法将一张true color image转换成color-map image,并尽可能的保留其原始颜色信息。color-map image的colormap维度为256
算法:
用聚类的方法先将所有像素点颜色分成256类并编号,然后以每一类的重心点作为该类的代表颜色,同一类颜色对应map上一个值(重心颜色值)。
程序:
clear
clc
%% read a truecolor image
TruecolorImage=imread('0.jpg');
figure
image(TruecolorImage);
axis image
title('TruecolorImage')
%% convert a true color image to colormapped (clusting)
[h,m,k]=size(TruecolorImage);
n=m*h;
data=zeros(n,3);
for i=1:m
for j=1:h
data((i-1)*h+j,:)=TruecolorImage(j,i,:);
end
end
[idx,C] = kmeans(data,256);
%% transform into colormap
index = zeros(h,m); map=C/255;
for k=1:n
index(k)=idx(k);
end
figure
image(index);
colormap(map)
axis image
title('ColorMapImage')
%% save image
聚类程序:
%N是数据一共分多少类
%data是输入的不带分类标号的数据
%u是每一类的中心
%re是返回的带分类标号的数据
function [u re]=KMeans(data,N)
[m n]=size(data); %m是数据个数,n是数据维数
ma=zeros(n); %每一维最大的数
mi=zeros(n); %每一维最小的数
u=zeros(N,n); %随机初始化,最终迭代到每一类的中心位置
for i=1:n
ma(i)=max(data(:,i)); %每一维最大的数
mi(i)=min(data(:,i)); %每一维最小的数
for j=1:N
u(j,i)=ma(i)+(mi(i)-ma(i))*rand(); %随机初始化,不过还是在每一维[min max]中初始化好些
end
end
while 1
pre_u=u; %上一次求得的中心位置
for i=1:N
tmp{i}=[]; % 公式一中的x(i)-uj,为公式一实现做准备
for j=1:m
tmp{i}=[tmp{i};data(j,:)-u(i,:)];
end
end
quan=zeros(m,N);
for i=1:m %公式一的实现
c=[];
for j=1:N
c=[c norm(tmp{j}(i,:))];
end
[junk index]=min(c);
quan(i,index)=norm(tmp{index}(i,:));
end
for i=1:N %公式二的实现
for j=1:n
u(i,j)=sum(quan(:,i).*data(:,j))/sum(quan(:,i));
end
end
if norm(pre_u-u)<0.1 %不断迭代直到位置不再变化
break;
end
end
re=[];
for i=1:m
tmp=[];
for j=1:N
tmp=[tmp norm(data(i,:)-u(j,:))];
end
[junk index]=min(tmp);
re=[re;data(i,:) index];
end
end
效果比较:
<img src="http://images.cnblogs.com/cnblogs_com/zhanghedong/1055457/o_T2.png" width="324px">
<img src="http://images.cnblogs.com/cnblogs_com/zhanghedong/1055457/o_C2.png" width="330px">
结果分析:
细看ColorMap图片会有一点点粗糙,这是由于转换过程中通过聚类的方式,只保留了256类,之前的颜色变成每一类重心点的颜色会有一些差距。
图像直方图操作
解释图像直方图均衡化的原理,并用程序实现。
算法及原理:
图像直方图均衡化值通过把原始图像的灰度直方图比较集中的区域“抹平”,使直方图均匀分布,达到高对比度和色调多变的效果。
用累积分布函数的来计算对应的像素值:
其中h表示像素值的概率密度函数。
这样就可以计算出一个查找表,每个像素点的值对应一个新的像素值,从而实现直方图均衡化的目的。
程序:
function LUT =LookUpTable_HE(I)%计算出直方图均衡化的查找表
h= Histogram(I);
A=sum(h);
LUT=ones(256,3);
p=zeros(1,3);
for i=1:256
p=p+([h(i,1,1),h(i,1,2),h(i,1,3)]/A(1,1,1));
LUT(i,:)=p;
end
end
I=imread('1.jpg');%读取一个图片
LUT=LookUpTable_HE(I);%生成一个查找表
[h,m,rgb]=size(I);
T=double(I)/255;
for k=1:rgb
for i=1:h
for j=1:m
T(i,j,k)=LUT(I(i,j,k)+1,k);
end
end
end
figure
image(T)
axis image
title('Equalization')
效果比较(由于跟之前的图片一样,所以只展示出均衡化之后的图片):
<img src="http://images.cnblogs.com/cnblogs_com/zhanghedong/1055457/o_Eq.png" width="330px">
<img src="http://images.cnblogs.com/cnblogs_com/zhanghedong/1055457/o_Orh.png" width="330px">
<img src="http://images.cnblogs.com/cnblogs_com/zhanghedong/1055457/o_Eqh.png" width="330px">
结果分析:
由直方图的结果可以观察到变换之后的直方图比原先的均匀了很多。另外图像的对比度明显增强了。
输入图片A与参考图片R,对A做变换得到A’使其统计直方图尽可能与R的统计直方图接近
算法及原理:
跟上一题一样,为了方便计算,我们首先生成一查找表,这张查找表是根据A和R的像素分布对比情况得到的。同样用累计概率密度函数的方法。要求得到的图像A'到第k个像素点的累计概率密度pA(k)不小于pR(l),也不大于pR(l+1),这样使得他们的累计概率密度尽可能相似,然后再用累计概率密度函数值乘以255得到查找表。根据查找表变换图像A即可得到A'。
程序:
function LUT =LookUpTable_Match(I,J)%计算出直方图匹配的查找表
hI= Histogram(I);hJ=Histogram(J);
AI=sum(hI);AJ=sum(hJ);
LUT=ones(256,3);
pI=zeros(1,3);pJ=zeros(1,3);
for k=1:3
gJ=1;
pJ(k)=pJ(k)+hJ(gJ,1,k)/AJ(1,1,1);
for gI=1:256
pI(k)=pI(k)+hI(gI,1,k)/AI(1,1,1);
while((pI(k)>pJ(k)) && (gJ<256))
gJ=gJ+1;
pJ(k)=pJ(k)+hJ(gJ,1,k)/AJ(1,1,1);
end
LUT(gI,k)=double(gJ)/256;
end
end
end
I=imread('1.jpg');
J=imread('2.jpg');
LUT=LookUpTable_Match(I,J);
[h,m,rgb]=size(I);
T=double(I)/255;
for k=1:rgb
for i=1:h
for j=1:m
T(i,j,k)=LUT(I(i,j,k)+1,k);
end
end
end
figure
image(I)
axis image
figure
image(J)
axis image
figure
image(T)
axis image
计算统计直方图直方图程序:
function h= Histogram(I)
[R C B]=size(I);
h=zeros(256,1,B);
for g=0:255
h(g+1,1,:)=sum(sum(I==g));
end
% x=0:255;
% bar(x,h(:,1)); title('Red');
% bar(x,h(:,2)); title('Green');
% bar(x,h(:,3)); title('Bule');
return;
对比效果:
<img src="http://images.cnblogs.com/cnblogs_com/zhanghedong/1055457/o_A.png" width="330px">
<img src="http://images.cnblogs.com/cnblogs_com/zhanghedong/1055457/o_R.png" width="330px">
<img src="http://images.cnblogs.com/cnblogs_com/zhanghedong/1055457/o_A'.png" width="330px">
三张图片的直方图对比:
<img src="http://images.cnblogs.com/cnblogs_com/zhanghedong/1055457/o_Ah.png" width="330px">
<img src="http://images.cnblogs.com/cnblogs_com/zhanghedong/1055457/o_Rh.png" width="330px">
<img src="http://images.cnblogs.com/cnblogs_com/zhanghedong/1055457/o_A'h.png" width="330px">
结果分析:
有图片结果可以发现A图片的色彩分布上是与R相似的,统计直方图也反应出了这一点