图片 压缩

#include <iostream>   
using namespace std;   
  
const int N =11;//数组元素个数-1 
  
int length(int i);  //二进制数的位数 
void Compress(int n,int p[],int s[],int l[],int b[]);  //压缩 
void Tracebace(int n,int& i,int s[],int l[]);//递归构造最优解  
void Output(int s[],int l[],int b[],int n);  //输出 
  
int main()  
{  
    //图像灰度数组 下标从1开始计数
    int p[] = {0,6, 5, 7, 245, 180, 28,28,19, 22, 25,20}; 
	//int p[]={4,6,5,7,129,138};
    //s[N]为像素序列最优分段所需的存储位数
	//l[N]为最优分段的有最高位数的像素个数
	//b[N]为最优分段的二进制数最高位数 
	int s[N],l[N],b[N];    
    cout<<"图像的灰度序列为:"<<endl;
	   
    for(int i=1;i<=N;i++)  
    {  
        cout<<p[i]<<" ";  
    }  
    cout<<endl;
	   
    Compress(N,p,s,l,b);  //压缩过程 
    Output(s,l,b,N);  //回溯输出 
    return 0;  
}  
  
void Compress(int n,int p[],int s[],int l[],int b[])  
{  
    //灰度值的范围为0~255,header=l[i]+b[i]=8+3=11 
    int Lmax = 256,header = 11;
	//从第一位开始,所以S[0]=0;   
    s[0] = 0;   
    for(int i=1; i<=n; i++)  
    {  
        b[i] = length(p[i]);//计算像素点p需要的存储位数  
         
		int bmax = b[i];//b[i]为最优分段的二进制数值的位数
		  
        s[i] = s[i-1] + bmax; //每次加对应的位数  
        l[i] = 1;//第一段像素个数  
         
         //p[] = {0,6, 5, 7, 245, 180, 28,28,19, 22, 25,20}
         //从{0,6}开始进行计算 
        for(int j=2; j<=i && j<=Lmax;j++)  
        {  
            //p[i]的位数比较,谁的位数大要谁 
            if(bmax<b[i-j+1])  
            {  
                bmax = b[i-j+1];  
            }  
  
            if(s[i]>s[i-j]+j*bmax)  
            {  
                s[i] = s[i-j] + j*bmax;  
                l[i] = j;  
            }  
        }  
        s[i] += header; //最优分段消耗位数 
    }  
}  
 
 //十进制数转换为二进制数时二进制数的位数 
int length(int i)  
{  
    int k=1; //初始化时位数的数值 
    i = i/2; 
	//当i大于0时循环 
    while(i>0)  
    {  
        k++;  
        i=i/2;  
    }  
    return k;  
}  
 
 //递归构造最优解 
void Traceback(int n,int& i,int s[],int l[])  
{  
    if(n==0)  
        return;  
    Traceback(n-l[n],i,s,l);//当n-l[n]的值为0时返回  
    s[i++]=n-l[n];//重新为s[]数组赋值,用来存储分段位置  
}  
  
void Output(int s[],int l[],int b[],int n)  
{  
    //在输出s[n]存储位数后,s[]数组则被重新赋值,用来存储分段的位置  
    cout<<"图像压缩后的最小空间为:"<<s[n]<<endl;  
    int m = 0;  
    Traceback(n,m,s,l);  
    s[m] = n;  
    cout<<"将原灰度序列分成"<<m<<"段序列段"<<endl; 
	
	//求最优分段的像素个数l[i]以及最高位数b[i] 
    for(int j=1; j<=m; j++)  
    {  
        l[j] = l[s[j]];  
        b[j] = b[s[j]];  
    } 
    
	//输出最优分段像素个数l[j]以及最高位数b[j]的值 
    for(int j=1; j<=m; j++)  
    {  
        cout<<"段长度(最优分段的像素个数):"<<l[j]<<",所需存储位数:"<<b[j]<<endl;  
    }  
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值