班级: 电信0805
姓名:
学号:
Huffman编码
一. 实验内容
1、了解BMP图像的格式,实现BMP图片格式的数据域及文件头的分离
2、熟悉Huffman编码原理
3、用C语言使用Huffman编码算法对给定图像文件进行编解码
二. 实验原理
Huffman编码:
Huffman编码是一种基于图像统计特征的变长编码方法:概率小的符号用较长的码字表示,概率大的符号用较短的码字表示。
Huffman编码的步骤:
位图BMP文件格式
文件头:
Typedef struct tagBITMAPFILEHEADER
{
WORD bfType; // 必须是0x424D,”BM”
DWORD bfSize; // 文件大小,包括结构本身
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits; // 实际图像数据便宜量
}BITMAPFILEHEADER;
信息头:
typedef struct tagBITMAPINFOHEADER
{
DWORD biSize; //结构本身的大小-40
LONG biWidth; //图像宽度
LONG biHeight; //图像高度
WORD biPlanes; //显示设备的平面数目-1
WORD biBitCount //描述每个象素颜色需要的位数
DWORD biCompression;//是否压缩
DWORD biSizeImage;//实际的位图数据占用的字节数
LONG biXPelsPerMeter;//显示设备的分辨率
LONG biYPelsPerMeter;
DWORD biClrUsed;//指定本图象实际用到的颜色数,如果该值为零,则用到的颜色数为2的biBitCount次方。
DWORD biClrImportant;//重要颜色数目,如果为零,则都是重要的。
}BITMAPINFOHEADER;
调色板:
typedef struct tagRGBQUAD
{
BYTE rgbBlue; //蓝色分量
BYTE rgbGreen; //绿色分量
BYTE rgbRed; //红色分量
BYTE rgbReserved; //保留值
} RGBQUAD;
三. 实现过程
(1)huffman树数据结构
由于huffman树为二叉树,定义数据结构为:
struct SNode {
long int freq; // 频率
int depth; // 深度,编码长度
char gray;
struct SNode * pPar; // 父结点
struct SNode * pLeft; // 左结点
struct SNode * pRight; // 右结点
char * code; // 字节编码
} ;
(2)灰度概率统计与排序
读取文件流时,跳过文件头的54个字节,直接读取数据域,从头到尾遍历统计,将统计结果存入freq中,通过链表的插入排序算法形成有序链表:
void addtolist(struct SNode* pNode)
{
if (head ==NULL) // 队列为空,
{
head = pNode;// 直接加入头部
}
else
{
if (pNode->freq < head->freq)//当新加入的结点的频数小于head结点的频数时,将新结点放到队首
{
pNode->pPar=head;
head=pNode;
}
else
{
struct SNode* p = head;
while ( (p->pPar!= 0) && (p->pPar->freq < pNode->freq))
{
p = p->pPar;
}
pNode->pPar = p->pPar;
p->pPar = pNode;
}
}
}
(3)Huffman树生成与编码
同页1图示中编码算法,有已知的有序单链表生成huffman树:
void createcodetree(struct SNode *ptree,int len)
{
int offset ,i=0;
while ( head!= NULL&& head->pPar != NULL)
{
// 取出前两个频数最小结点
struct SNode *p1 = head;
struct SNode *p2 = head->pPar;
head = p2->pPar;
offset=len+i;
ptree[offset].freq = p1->freq + p2->freq; // 频率为两者之和
ptree[offset].pLeft = p1;
ptree[offset].pRight = p2;
p1->pPar =&ptree[offset];
p2->pPar = &ptree[offset];
AddChildLen(&ptree[offset]);//调整树中每个结点的深度
addtolist(&ptree[offset]);//将新产生的结点,放到临时队列中
i++;
}
// 构建树完成,生成编码
for ( i = 0; i < 256; i++)
{
if (nodes[i].freq > 0)
{
createcode(&nodes[i]);
}
}
}
(4)解码
解码过程为编码的逆过程。编码是从叶子节点自下而上编码(即先生成最末位向前编码),而解码是从根节点自上而下,直到节点为叶子节点截止:
void decode(){
FILE * hufin,*hufout,*imgin;
struct SNode *p;
int i=0,n=0,num=0;
char b;
char debuf[507132];//507132是当前目录huffma.txt文件中所有字符的个数,也就是'0'和'1'的个数。
if((imgin=fopen("lena.bmp","rb"))==NULL){
printf("file open error\n");
exit(1);
}
if((hufout=fopen("decode.bmp","wb+"))==NULL){//打开存储解码结果的文件
printf("file open error");
exit(1);
}
if((hufin=fopen("huffman.txt","rt+"))==NULL){//打开存储编码结果的文件
printf("huffman.txt open error\n");
exit(1);
}
fread(debuf,sizeof(char),54,imgin);//读出原始图像的文件头,图像信息放到b中,因为文件头没有进行编码所以无需解码直接拷贝
fwrite(debuf,sizeof(char),54,hufout);//将文件头,图像信息放到解码后的文件中
//n=len+1;
fgets(debuf,507132,hufin); //从文件中读出所有的编码序列,只读n-1个第,并自动使b【n】为‘\0’
p=head; //每次解码都要从树的根节点开始
for(i=0;debuf[i]!='\0';i++){//开始解码
switch(debuf[i]){
case '0':{
if(p->pLeft!=NULL) {//如果编码为0并且左孩子不为空,那么p指向p的左孩子。
p=p->pLeft;
break;
}
else{ //如果左孩子为空,则此结点为叶子结点,取出其灰度值作为解码结果
b=p->gray;
fwrite(&b,sizeof(char),1,hufout);
p=head;
i=i-1;//此时i指向下一个码元的开始位置,但是for循环还有一个i++所以此时需要将i减一
break;
}
}
case '1':{
if(p->pRight!=NULL){//如果编码为1并且右孩子孩子不为空,那么p指向p的右孩子。
p=p->pRight;
break;
}
else{//如果右孩子孩子为空,则此结点为叶子结点,取出其灰度值作为解码结果
b=p->gray;
fwrite(&b,sizeof(char),1,hufout);
p=head;
i=i-1;
break;
}
}
default: break;
}
}
b=p->gray;//上面的switch语句未能统计左后一个解码结果,所以在此统计一下
fwrite(&b,sizeof(char),1,hufout);
}
基于深度的图像修
一. 实验内容
1、单幅图像的修补
2、结合彩色图像和深度图像的图像修补
二. 实验原理
图像修复技术:
应用图像修复技术可以保证图像信息的完整性,是利用图像的空间相关性对图像上信息缺损区域进行填充的过程
图像修复技术的用途:
艺术品修复、文物保护、影视特技制作、多余目标物体剔除、图像缩放、图像的有损压缩、视频通信的错误隐匿。
图像中常有缺失或者损坏的部分,即空白区域或者有误的区域。图像修补就是根据这些区域周围的信息完成对空白区域的填充,以实现图像的恢复。
基本方法
利用深度图的图像修补
1图像的前景与背景
实际场景中存在前景与背景的区别,前景会遮挡背景,而且前景与背景往往差距比较大。
2深度图
用于表示3D空间中的点与成像平面距离的灰度图。0~255表示,灰度值越大,表示场景距离成像平面越近,反之,灰度值越小,表示场景距离成像平面越远。
前景的灰度值大,背景的灰度值小。
如下左彩色图,右深度图
3普通的图像修补区分不了图像的前景和背景,简单的加权求和填补空白点的方法会导致前景和背景的混杂。引入深度图之后,可以利用深度图区分图像的前景和背景,在对背景进行修补的时候,可以利用深度图滤除那些前景参考点的影响,从而使背景的空白点只由背景点加权求和得到,前景亦然。
三. 实现过程
基本思想:
1. 读入一个像素点,判断其是否为空白点;
2. 若不是空白点,则跳过该点,判断下一个点;
3. 若该点是空白点,则选取以该店为中心的41*41大小的区域为参考窗口,由上述的基于深度图的修补公式进行修补;
4. 重复上述步骤,对图像中的每一个点都进行如此处理,直至全图处理完毕,则图像修补完成;
具体实现代码(matlab):
clear all;
close all;
I=imread('color-blend-f034.bmp');
B=imread('depth-cam4-f034.bmp');
figure,subplot(1,2,1);
imshow(I);
title('原始图像');
[m,n,hh]=size(I);
A=rgb2gray(I);
I1=I;
[rowind,columnind]=find(A<5);
pointnum=length(rowind);
rowstart=rowind-20;rowend=rowind+20;
rowstart(rowstart<1)=1;rowend(rowend>m)=m;
columnstart=columnind-20;columnend=columnind+20;
columnstart(columnstart<1)=1;columnend(columnend>n)=n;
for num=1:pointnum
x=rowind(num);
y=columnind(num);
basedepth=B(x,y);
xstart=rowstart(num);
xend=rowend(num);
x1=x-xstart+1;
ystart=columnstart(num);
yend=columnend(num);
y1=y-ystart+1;
depthpos=A(xstart:xend,ystart:yend)>4&(B(xstart:xend,ystart:yend)-basedepth)<4;
[locind1,locind2]=find(depthpos);
W=(locind1-x1).*(locind1-x1)+(locind2-y1).*(locind2-y1)+1;
TT=1./W;T=sum(TT);
Aloc=I(xstart:xend,ystart:yend,1);
Aloc=double(Aloc(depthpos));
R=Aloc.*TT;R=sum(R);
I1(x,y,1)=R/(T+0.1);
Aloc=I(xstart:xend,ystart:yend,2);
Aloc=double(Aloc(depthpos));
R=Aloc.*TT;R=sum(R);
I1(x,y,2)=R/(T+0.1);
Aloc=I(xstart:xend,ystart:yend,3);
Aloc=double(Aloc(depthpos));
R=Aloc.*TT;R=sum(R);
I1(x,y,3)=R/(T+0.1);
end
subplot(1,2,2);
imshow(I1);
title('修复图像');
figure,imshow(I,[]);
figure,imshow(I1,[]);
多媒体实验报告一姓名方子乙学号20xx00300336班级20xx级软件6班一实验目的1熟悉和掌握使用WindowsMCI进行编程…
多媒体技术及应用实验报告班级:电信0805姓名:学号:Huffman编码一.实验内容1、了解BMP图像的格式,实现BMP图片格式的…
多媒体技术班级网络姓名李耿卓学号12023120xx0050多媒体中的多媒体通信技术1交互性交互性是多媒体通信系统区别于其他通信系…
多媒体实验报告实验一数字音频实验一实验时间20xx年3月29日一实验目的1了解不同数字音频指标对所生成声音文件音质的影响2掌握音频…
北京邮电大学多媒体通信专业综合实验多媒体通信专业综合实验报告题目窄带话音调频发送与接收系统班级组员学号北京邮电大学多媒体通信专业综…
多媒体技术设计实验报告专业计算机科学与技术年级09级姓名张海建学号090601150提交日期1实验目的学会使用该flash软件进行…
多媒体课程设计报告设计题目:物联网学院:计算机科学与信息学院专业:计科班级:计科101学号:XX学生姓名:XXX指导教师:XX20…
1q实验粒子系统讲授时数05学时一实验类型研究创新型实验二实验目的通过本实验让学生熟练掌握三维图形程序编写掌握粒子系统的设计与实现…
多媒体技术实验报告书姓名专业年级学号指导老师目录实验一图像采集与编辑实验实验二音频信号的获取与处理实验三波形音频播放器实验四数字视…
中学教学多媒体软件开发的研究阶段实验报告省前中中学教学多媒体软件开发的研究课题组中学教学多媒体软件开发的研究这一课题已深入开展了两…