对灰度图像进行霍夫曼编码,用Matlab怎么实现啊?

对灰度图像进行霍夫曼编码,用Matlab怎么实现啊?,第1张

给你一段程序,自己研究下吧!\x0d\x0a\x0d\x0aclc\x0d\x0aclear\x0d\x0acloseall\x0d\x0a%定义HufData/颤裂埋Len为全局变量的结构体\x0d\x0aglobalHufData\源悔x0d\x0aglobalLen\x0d\x0adisp('计算机正在准备输出哈夫曼编码结果,请耐心等待??')\x0d\x0a%原始码字的灰度\x0d\x0aa=imread('kids.tif')\x0d\x0a\x0d\x0a%分区画出原始图像和灰度直方图\x0d\x0afigure\x0d\x0asubplot(1,2,1)\x0d\x0aimshow(a)\x0d\x0a%取消坐标轴和边框\x0d\x0aaxisoff\x0d\x0aboxoff\x0d\x0atitle('MATLAB自带图像','fontsize',13)\x0d\x0asubplot(1,2,2)\x0d\x0aaxisoff\x0d\x0aboxoff\x0d\x0aimhist(a)\x0d\x0atitle('图像灰度直方图','fontsize',13)\x0d\x0a%图像的灰度统计\x0d\x0aGrayStatistics=imhist(a)\x0d\x0aGrayStatistics=GrayStatistics'\x0d\x0aGrayRatioo=GrayStatistics/sum(GrayStatistics)\x0d\x0aGrayRatioNO=find(GrayRatioo~=0)\x0d\x0aLen=length(GrayRatioNO)\x0d\x0a%初始化灰度集,防止系统随即赋予其垃茄蚂圾值\x0d\x0aGrayRatio=ones(1,Len)\x0d\x0a\x0d\x0afori=1:Len\x0d\x0aGrayRatio(i)=GrayRatioo(i)\x0d\x0aend\x0d\x0a\x0d\x0aGrayRatio=abs(sort(-GrayRatio))\x0d\x0a%将图像灰度概率赋予结构体\x0d\x0afori=1:Len\x0d\x0aHufData(i).value=GrayRatio(i)\x0d\x0aend\x0d\x0a\x0d\x0a%哈夫曼编码/霍夫曼编码\x0d\x0aHuffmanCode(Len)\x0d\x0a%输出码字\x0d\x0a\x0d\x0azippedHuffman=1\x0d\x0afori=1:Len\x0d\x0atmpData=HufData(i).code\x0d\x0astr=''\x0d\x0aforj=1:length(tmpData)\x0d\x0astr=strcat(str,num2str(tmpData(j)))\x0d\x0azippedHuffman=zippedHuffman+1\x0d\x0aend\x0d\x0adisp(strcat('a',num2str(i),'=',str))\x0d\x0aend\x0d\x0ai\x0d\x0a%计算计算机一共输出多少个哈夫曼编码/霍夫曼编码\x0d\x0azippedHuffman\x0d\x0a%计算在删去0灰度级压缩之前的原始图像字节容量\x0d\x0aunzipped_delete=i*8\x0d\x0a\x0d\x0a%计算压缩比率\x0d\x0aratio_delete=zippedHuffman/unzipped_delete\x0d\x0a\x0d\x0a%计算图像的压缩比率\x0d\x0aad=num2str(ratio_delete*100)\x0d\x0astr2=strcat(ad,'%')\x0d\x0adisp(strcat('哈夫曼编码压缩比率','=',str2))\x0d\x0a\x0d\x0a%子程序:哈夫曼编码/霍夫曼编码函数HuffmanCode.m\x0d\x0afunctionHuffmanCode(OriginSize)\x0d\x0aglobalHufData\x0d\x0aglobalLen\x0d\x0afori=1:Len\x0d\x0a%%霍夫曼编码树左边纪录为1\x0d\x0aHufData(i).left=1\x0d\x0a%%霍夫曼编码树右边纪录为0\x0d\x0aHufData(i).right=0\x0d\x0a%%输出码初始化为0\x0d\x0aHufData(i).code=[]\x0d\x0a%%排序列表初始化\x0d\x0aSortList(i).symbol=i\x0d\x0aSortList(i).value=HufData(i).value\x0d\x0aend\x0d\x0a%初始化原始消息数目\x0d\x0anewsymbol=OriginSize\x0d\x0aforn=OriginSize:-1:2\x0d\x0a%将N个消息进行排序\x0d\x0aSortList=sortdata(SortList,n)\x0d\x0a%将最后两个出现概率最小的消息合成一个消息\x0d\x0anewsymbol=newsymbol+1\x0d\x0aHufData(newsymbol).value=SortList(n-1).value+SortList(n).value\x0d\x0aHufData(newsymbol).left=SortList(n-1).symbol\x0d\x0aHufData(newsymbol).right=SortList(n).symbol\x0d\x0a%将消息添加到列队的最后,为N-1个消息重新排序作好准备\x0d\x0aSortList(n-1).symbol=newsymbol\x0d\x0aSortList(n-1).value=HufData(newsymbol).value\x0d\x0aend\x0d\x0a%遍历霍夫曼树,获得霍夫曼编码/哈夫曼编码\x0d\x0avisit(newsymbol,Len,[])\x0d\x0aend\x0d\x0a\x0d\x0a%子程序:冒泡排序法函数sortdata.m\x0d\x0afunctionreData=sortdata(SortList,n)\x0d\x0a%根据消息概率进行排序\x0d\x0afork=n:-1:2\x0d\x0aforj=1:k-1\x0d\x0amin=SortList(j).value\x0d\x0asbl=SortList(j).symbol\x0d\x0aif(min<SortList(j+1).value)\x0d\x0aSortList(j).value=SortList(j+1).value\x0d\x0aSortList(j+1).value=min\x0d\x0aSortList(j).symbol=SortList(j+1).symbol\x0d\x0aSortList(j+1).symbol=sbl\x0d\x0aend\x0d\x0aend\x0d\x0aend\x0d\x0areData=SortList\x0d\x0aend\x0d\x0a\x0d\x0a%子程序:遍历哈夫曼编码/霍夫曼编码树搜索函数visit.m\x0d\x0afunctionvisit(node,n,ocode)\x0d\x0aglobalHufData\x0d\x0aifnode0)\x0d\x0a%遍历左分支接点输出1,这里采用子函数嵌套调用\x0d\x0aocode1=[ocode1]\x0d\x0avisit(HufData(node).left,n,ocode1)\x0d\x0aend\x0d\x0aif(HufData(node).right>0)\x0d\x0a%遍历右分支接点输出0,这里采用子函数嵌套调用\x0d\x0aocode2=[ocode0]\x0d\x0avisit(HufData(node).right,n,ocode2)\x0d\x0aend\x0d\x0aend\x0d\x0aend

霍夫曼编码计算过程:无损数据压缩的熵编码。

在计算机数据处理中,霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现机率的方法得到的,出现机率高的字母使用较短的编码,反之出现机率低的则使用较长的编码,这便使编码之后的字符串的平均长度、期望值降低,从而改凯腊达到无损压缩数据的目的。

例如,在英文中,e的出现机率最高,而z的出现概率则最低。当利用霍夫曼编码对一篇英文进行压缩时,e极有可能用一个比特来表示,而z则可能花去25个比特(不是26)。用普通的表示方法时,每个英文字母均占用一个字节,即8个比核滑特。

二者相比,e使用了一般编码的1/8的长度,z则使用了3倍多。倘若我们能实现对于英文中各个字母出现概率的较准确的估算,就可以大幅度提高无损压缩的比例。

霍夫曼编码历史:

1951年,霍夫曼在麻省理工学院(MIT)攻读博士学位,他和修读信息论课程的同学得选择是完成学期报告还是期末考试。导师罗伯特·法诺(Robert Fano)出的学期报孙敏告题目是:查找最有效的二进制编码。

由于无法证明哪个已有编码是最有效的,霍夫曼放弃对已有编码的研究,转向新的探索,最终发现了基于有序频率二叉树编码的想法,并很快证明了这个方法是最有效的。霍夫曼使用自底向上的方法构建二叉树,避免了次优算法香农-范诺编码(Shannon–Fano coding)的最大弊端──自顶向下构建树。

1952年,于论文《一种构建极小多余编码的方法》(A Method for the Construction of Minimum-Redundancy Codes)中发表了这个编码方法。

以前写的,证明最优子结构,随便一本算法书上就有.

#include<stdio.h>

#include<stdlib.h>

#define

NIL

-2

#define

Size_Max_bm

30

#define

left(i)

(2*(i)+1)

#define

right(i)

(2*(i)+2)

#define

swap(a,b)

{cjys

tt=(a)(a)=(b)(b)=t}

#define

parent(i)

((i)%2?((i)-1)/2:((i)-2)/2)typedef

struct

cjys

{

char

sj

int

pl

struct

cjys

*left

struct

cjys

*right

}cjystypedef

struct

cjdl

{

int

size

int

leapsize

cjys

*p

}cjdl

cjys

*fpnn(void)

void

input(cjdl

*p)

cjys

*fpnn(void)

void

zxdwh(cjys

*p,

int

i,

int

leapsize)

void

rd(cjdl

*p,

cjys

tp)

cjys

cd(cjdl

*p)

void

hbs(cjdl

*p)

cjys

*cjs(cjdl

*p)

void

bls(cjys

*p,int

*jl,

int

i)

void

disp(char

*tp,

cjys

*p)int

main()

{

cjdl

p

char

x[255]

cjys

*re=NULL

int

jl[Size_Max_bm]

input(&p)

re=cjs(&p)

printf("对照编码图为:\n")

bls(re,jl,0)

freopen("CON","r",stdin)

printf("输入Huffman码(VLC):")

scanf("%s",x)

disp(x,re)

system("pause")

}

void

input(cjdl

*p)

{

int

i

cjys

*tp

tp=fpnn()

printf("输入字母个数:")

scanf("%d",

&p->size)

p->p=malloc(sizeof(cjys)*p->size)

p->leapsize=0

for(i

=

0

i

<

p->sizei++)

{

printf("输入第%d字母:",i+1),scanf("

%c",&tp->sj)

printf("输入出现次数(频率整数):"),scanf("%d",&tp->pl)

rd(p,*tp)

}

free(tp)

}

cjys

*fpnn(void)

{

cjys

*p=NULL

p=malloc(sizeof(cjys))

p->left=NULL

p->right=NULL

return

p

}

void

zxdwh(cjys

*p,

int

i,

int

leapsize)

{

int

l=left(i),

r=right(i),

mini=i

if(l<leapsize

&&

p[l].pl<p[mini].pl)

mini=l

if(r<leapsize

&&

p[r].pl<p[mini].pl)

mini=r

if(mini

!=

i)

{

swap(p[i],p[mini])

zxdwh(p,mini,leapsize)

}

}

void

rd(cjdl

*p,

cjys

tp)

{

if(p->leapsize

==

p->size)

{

printf("队列已满!")

exit(0)

}

p->p[p->基枣leapsize]=tp

int

j=p->leapsize,k=parent(j)

while(k>=0

&&

p->p[j].pl

<

p->p[k].pl)

{

swap(p->p[j],p->p[k])

j=k

k=parent(j)

}

p->御裤leapsize++

}

cjys

cd(cjdl

*p)

{

if(p->leapsize

==

0)

{

printf("队列搏拆拆已空!")

exit(0)

}

cjys

tp=p->p[0]

p->leapsize--

p->p[0]=p->p[p->leapsize]

zxdwh(p->p,0,p->leapsize)

return

tp

}

void

hbs(cjdl

*p)

{

cjys

*p1=NULL,

*p2=NULL

cjys

tp

p1=fpnn()

p2=fpnn()

*p1=cd(p)

*p2=cd(p)

tp.left=p1

tp.right=p2

tp.pl=p1->pl+p2->pl

tp.sj=NIL

rd(p,tp)

}cjys

*cjs(cjdl

*p)

{

int

i,

n=p->leapsize

cjys

*tp=NULL

tp=fpnn()

for(i

=

0

i

<

n-1

i++)

hbs(p)

*tp=p->p[0]

return

tp

}

void

bls(cjys

*p,

int

*jl,

int

i)

{

if(p

==

NULL)

return

if(p->sj!=NIL)

{

int

i2

printf("%c:",p->sj)

for(i2

=

0

i2

<

i

i2++)

printf("%d",jl[i2])

printf("\n")

}

jl[i]=0

bls(p->left,jl,i+1)

jl[i]=1

bls(p->right,jl,i+1)

}

void

disp(char

*tp,

cjys

*p)

{

cjys

*ttp=NULL

int

pd=0

while(1)

{

ttp=p

while(1)

{

if(ttp->sj

!=

NIL)

{

printf("%c",ttp->sj)

break

}

if(*tp

==

'\0')

{

pd=1

break

}

if(*tp++

==

'0'

)

ttp=ttp->left

else

ttp=ttp->right

}

if(pd)

break

}

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12405536.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-25
下一篇 2023-05-25

发表评论

登录后才能评论

评论列表(0条)

保存