图像压缩问题
问题描述
给定像素序列,求出最优分段及所占字节数。
输出s[0],s[1],s[2]…及l[1],l[2],l[3]…的计算过程,并给出最终解。
例如实例1最后输出:
最优分段是:<10,12,15>,<255>,<1,2> 总存储位数为:57
完整代码
//Copyright (c) 2021 @CSDN_每天三点睡 All rights reserved.
#include<iostream.h>
#define MAX 20
int S[MAX]={0},l[MAX]={0},b[MAX],C[MAX];//全局数组初始化
//计算P[i]对应的对数
int length(int n)
{
int t=1;
while(n>=2)
{
t++;
n/=2;
}
return t;
}
//求最优分段
void Traceback(int P[],int n,int l[])
{
int i=1,j,k=1,x=0;
while(n!=0)//当n不为0,即P中数据还没有分配完
{
C[i]=l[n];//C[i]从后往前追踪第i段长度
n-=l[n];//n减去上一个分段的长度
i++;
x++;//x记录分成多少段
}
cout<<"最小位数的最优分段是:";
for(i=x;i>=1;i--)//输出x个分段
{
cout<<"<";
for(j=C[i];j>=1;j--)//该段有C[i]个数据,从后往前输出
{
cout<<" "<<P[k++]<<" ";
if(j-1>=1)
cout<<",";
}
cout<<">";
if(i-1>=1)
cout<<" , ";
}
cout<<endl;
}
//压缩图像(核心代码) 包含输出
void Compress(int P[],int n)
{
int Lmax=256,header=11,bmax;//Lmax为最大段长,header为每个段头占用的空间11
S[0]=0;
int i,j;
for (i=1;i<=n;i++)
{
b[i]=length(P[i]);//b[i]为第i个像素灰度的二进制位数
bmax=b[i];//初始化bmax为p[i]的二进制位数
S[i]=S[i-1]+bmax;//初始化当前的二进制位数是上一段的位数加上当前p[i]的二进制位数
l[i]=1;//初始化分段为1,如果找到更好的分段,就等于新的分段
cout<<"S["<<i<<"]=min{"; //输出求解过程,实际上可利用数组转存,在子函数中调用输出
for(j=1;j<=i;j++)//最后一段含有j个像素,j=2,3,4....t
{
if(bmax<b[i-j+1])//统一段内表示像素的二进制位数
bmax=b[i-j+1];
cout<<S[i-j]+j*bmax;//输出选择可能数据
if(S[i]>S[i-j]+j*bmax)
{
S[i]=S[i-j]+j*bmax; //将最小的长度赋给S[i]
l[i]=j;//l[i]记录更新后分段的元素个数
}
if(j+1<=i)
cout<<" ,"; //优化格式输出(边求解边输出过程)
}
S[i]+=header;//加上段头长度11
cout<<"}+"<<header<<"=";
cout<<S[i]<<endl;
cout<<"l["<<i<<"]="<<l[i]<<endl;//输出S[i],此时包含了段头长度
cout<<endl;
}
Traceback(P,n,l);//调用追踪函数
}
int main()
{
int P[]={0,10,12,15,255,1,2};
int P2[]={0,1,1,0,1,233,28,58,60};
cout<<"实例1"<<endl;
Compress(P,6);
cout<<"总存储位数为:" <<S[6]<<endl;
cout<<"实例2"<<endl;
Compress(P2,8);
cout<<"总存储位数为:" <<S[8]<<endl;
}
结语
制作不易,喜欢点赞支持一下。