数字图像处理实验报告 (图像编码)(4)

2019-03-29 09:40

int j;

graySum = width * height; // 计算图象象素总数 for (i = 0; i < graygrade; i ++) { // 赋零值

grayfreq[i] = 0.0; }

//计算各个灰度值的计数 for (i = 0; i < height; i ++)

{ }

//计算各个灰度值出现的概率

for (i = 0; i < graygrade; i ++) { }

grayfreq[i] = grayfreq[i] / (double)graySum; for (j = 0; j < width; j ++)

{ //指向图象指针 lpSrc = (unsigned char*)lpDIBBits + width * i + j; }

//相应的灰度计数加1

grayfreq[*(lpSrc)] = grayfreq[*(lpSrc)] + 1;

//构建霍夫曼编码的码表,并用对话框显示霍夫曼码表 CHuffmanCoding coding;

// 创建对话框

coding.grayfreq = grayfreq; // 初始化变量值 coding.graygrade = graygrade;

coding.DoModal(); // 显示对话框 EndWaitCursor(); // 恢复光标

5.2 香农-范诺编码

5.2.1 香农-范诺编码算法实现

资源文件ShannonCoding.cpp是香农-范诺编码的算法程序。与哈夫曼算法相似地从视图类中得到每个灰度值出现的概率,针对这个概率进行编码。

首先用冒泡法从小到大对概率进行排序,从概率大于0处开始进行编码,对概率区间进行分割,然后对每个灰度值对应的编码数组进行追加字符,初始时追加为1,当超出概率总和的一半时,追加的字符改为0,接着继续对上半部分的区间进行分割,此时概率的总和就改为上半部分的概率总和了,重复上述操作,完成整幅图像的编码。具体代码如下所示:

BOOL CShannonCoding::OnInitDialog()

第 16 页 共 32 页

{ // 调用默认得OnInitDialog()函数 CDialog::OnInitDialog(); // 字符串变量

CString str; str = \

int i; int j;

//图像灰度出现概率中间结果的数组

double * temp;

//数组用来存放灰度值和其位置之间 int * turn; temp = new double[graygrade];

// 数组用来存放灰度值和其位置之间的映射 turn = new int[graygrade]; //临时变量

int temp2; // 当前编码区间的概率和

double effectcum;

//初始的概率和为1.0 effectcum = 1.0; // 已经编码灰度值概率的统计和 double

dSum;

//初始化为0

dSum = 0;

// 已编码灰度值 int lCount = 0;

// 起始位置

int lBegin;

//指示编码是否已经完成一段 BOOL * bFinished; bFinished = new BOOL[graygrade]; // 分配内存

m_strCode = new CString[graygrade]; for (i = 0; i < graygrade; i ++) { // 初始化为FALSE

bFinished[i] = FALSE; // 将概率赋值temp数组

temp[i] = grayfreq[i];

// 按灰度值大小顺序排列 turn[i] = i; }

// 中间变量

double

te;

第 17 页 共 32 页

// 用冒泡法对进行灰度值出现的概率排序 // 同时改变灰度值位置的映射关系 for (j = 0; j < graygrade - 1; j ++) { for (i = 0; i < graygrade - j - 1; i ++) { if (temp[i] > temp[i + 1]) { // 互换 te = temp[i]; temp[i] = temp[i + 1]; temp[i + 1] = te;

// 将i和i+1灰度的位置值互换 temp2 = turn[i]; turn[i] = turn[i+1]; turn[i+1] = temp2;

}

} }

// 计算香农-弗诺编码表,从概率大于0处开始编码 for (lBegin = 0; lBegin < graygrade - 1; lBegin ++) { if (temp[lBegin] > 0) {

break; }

}

// 开始编码

while(lCount < graygrade)

{ // 从概率大于零的灰度值开始编码 lCount = lBegin; // 对区间进行分割,对每个区间的灰度值编码 for (i = lBegin; i < graygrade; i ++) { // 判断是否编码完成 if (bFinished[i] == FALSE) { // 增加当前编码区间的概率综合 dSum += temp[i]; // 判断是否超出总和的一半 if (dSum > effectcum/2.0) { // 超出,追加的字符改为0 str = \ } // 追加字符

m_strCode[turn[i]] = m_strCode[turn[i]] + str; 第 18 页 共 32 页

// 判断是否编码完一段

if (dSum == effectcum)

{ // 完成一部分编码,重新计算effectcum

dSum = 0; // 初始化dSum为0 // 判断是不是对所有灰度值已经编码一遍 if (i == graygrade - 1) {

j = lBegin; }

else {

j = i + 1; }

temp2 = j; // 保存j值 str = m_strCode[turn[j]];

// 计算下一编码区间的概率总和 effectcum = 0;

for (; j < graygrade; j++)

{ // 判断是否是同一段编码 if ((m_strCode[turn[j]].Right(1) != str.Right(1)) || (m_strCode[turn[j]].GetLength() != str.GetLength())) }

break;

//当前区间的概率总和增加 effectcum += temp[j];

// 码字增加值为1 str = \ // 判断该段编码已经完成 if (temp2 + 1 == j)

{

bFinished[temp2] = TRUE; }

} else

}

{ // 开始下一轮编码 lCount ++; // 重新赋dSum为0 dSum = 0;

// 判断是不是对所有灰度值已经编码一遍 if (i == graygrade - 1)

{

j = lBegin; }

第 19 页 共 32 页

else }

{

j = i + 1;

temp2 = j; // 保存j值 str = m_strCode[turn[j]];

// 计算下一编码区间的概率总和 effectcum = 0;

for (; j < graygrade; j++) {

// 判断是否是同一段编码 if ((m_strCode[turn[j]].Right(1) != str.Right(1)) }

|| (m_strCode[turn[j]].GetLength() != str.GetLength())) { // 退出循环 break; }

effectcum += temp[j]; // 累加

str = \

// 判断该段编码已经完成 if (temp2 + 1 == j) }

bFinished[temp2] = TRUE;

} }

// 计算图像熵

for (i = 0; i < graygrade; i ++) { // 判断概率是否大于0 if (grayfreq[i] > 0)

{ // 计算图像熵 m_shang -= grayfreq[i] * log(grayfreq[i]) / log(2.0);

} }

// 计算平均码字长度

for (i = 0; i < graygrade; i ++)

{ // 累加 m_length +=grayfreq[i] * m_strCode[i].GetLength(); }

// 计算编码效率

m_effect = m_shang / m_length; // 保存变动

UpdateData(FALSE); //输出编码结果

// 字符串变量,列表项目的显示

第 20 页 共 32 页


数字图像处理实验报告 (图像编码)(4).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:市政园林绿化工程施工管理中存在的问题研究

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: