C++实现图像压缩的示例代码

 更新时间:2023年12月26日 10:54:29   作者:可以帮我找找钥匙吗.  
这篇文章主要为大家详细介绍了如何使用C++实现图像压缩的功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

一、问题描述

一幅图像由n*m个像素点组成,其中每个像素的灰度值范围是0~255(即需要8bit来存储像素的灰度值),由此可以得出存储此图像需要的存储空间为n*m*8(bit)。

不难看出,直接采用上述的存储方式是需要占用很多存储空间的。此时可以采用图像压缩算法来节省存储空间。

二、算法分析

1、算法思想

将像素序列分段,段内的像素灰度值相似(可以用小于8bit的空间来存储一个像素灰度值),一段内的像素用相同的bit数来存储,只需要额外存储每段的长度和bit数即可,这样可以节省很多空间

于是问题的关键就在于如何分段,使得存储空间的占用最少

2、算法实现

假设像素点的灰度集合为p[n],创建三个表 s[i]、l[i]、b[i],其中:

  • s[i]来记录前 i 个数字的最优处理方式得到的最优解。
  • l[i]来记录当前第 i 个数所在组中有多少个数。
  • b[i]中存放前 i 个像素点最后一段位数的最大值。

假设产生了m个段,则存储第i段像素所需要的空间为 : l[i] * b[i] + 11(l[i] * b[i]表示这一段像素本身需要的信息, 11则表示这一段的长度l[i]以及该段像素每一个都用几位来表示b[i], 即3 + 8 = 11位)

总存储空间为 11m+∑ l[i]*b[i] 

此时只要找出最优数组,即可得到最有效的压缩方法。最优数组含义是:s[i],1≤i≤n,是像素序列{p1,…,pi}的最优分段所需的存储位数。

递推关系式:

三、代码实现

#include<iostream>
using namespace std;
const int N = 10;
 
 
void show(int s[], int l[], int b[], int n)
{
	//在输出s[n]存储位数后,s[]数组则被重新赋值,用来存储分段的位置  
	cout << "图像压缩后的最小空间为:" << s[n] << endl;
}
 
 
int length(int x)
{
	int count = 1;
	x = x / 2;
	while (x > 0)
	{
		count++;
		x = x / 2;
	}
	return count;
}
 
void compress(int n,int p[N], int s[N], int l[N], int b[N])
{
	int lmax = 256,bmax;
	int header = 11;
	s[0] = 0;
	for (int i = 1; i <= n; i++)
	{
		b[i] = length(p[i]);
		bmax = b[i];
		s[i] = s[i - 1] + bmax;
		l[i] = 1;
		for (int j = 2; j <= i && j <= lmax; j++)
		{
			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 main()
{
	int data[N] = { 10,12,11,9,145,238,2,3,5,1 };
	cout << "图像的灰度值序列:";
	for (int i = 0; i < N; i++)
	{
		cout << data[i]<<" ";
	}
	cout << endl;
	int s[N],l[N], b[N];
	compress(N - 1, data, s, b, l);
	show(s,l,b,N - 1);
	
}

运行结果:

到此这篇关于C++实现图像压缩的示例代码的文章就介绍到这了,更多相关C++图像压缩内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++抛出和接收异常的顺序

    C++抛出和接收异常的顺序

    这篇文章主要介绍了C++抛出和接收异常的顺序,帮助大家更好的理解和学习C++,感兴趣的朋友可以了解下
    2020-08-08
  • C++使用cuBLAS加速矩阵乘法运算的实现代码

    C++使用cuBLAS加速矩阵乘法运算的实现代码

    这篇文章主要介绍了C++使用cuBLAS加速矩阵乘法运算,将cuBLAS库的乘法运算进行了封装,方便了算法调用,具体实现代码跟随小编一起看看吧
    2021-09-09
  • Qt qml实现动态轮播图效果

    Qt qml实现动态轮播图效果

    这篇文章主要为大家详细介绍了Qt和qml实现动态轮播图效果的相关知识,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下
    2024-12-12
  • Qt创建SQlite数据库的示例代码

    Qt创建SQlite数据库的示例代码

    本文主要介绍了Qt创建SQlite数据库的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • OpenCV实现特征检测和特征匹配方法汇总

    OpenCV实现特征检测和特征匹配方法汇总

    一幅图像中总存在着其独特的像素点,这些点我们可以认为就是这幅图像的特征,成为特征点,本文主要介绍了OpenCV实现特征检测和特征匹配方法,感兴趣的可以了解一下
    2021-08-08
  • C++ pair的用法案例详解

    C++ pair的用法案例详解

    这篇文章主要介绍了C++ pair的用法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-09-09
  • C语言详细分析讲解struct与union使用方法

    C语言详细分析讲解struct与union使用方法

    最近开始自学C语言,从最基础部分的开始学起。今天看书的时候注意到了struct和union似乎很像,除了名字不同,看起来几乎没有区别。<BR>既然C中定义了struct和union两个关键字,那么它们肯定是有区别的,在查了一些资料之后我来总结一下他们的使用
    2022-04-04
  • C++如何判断一个数字是否为质数

    C++如何判断一个数字是否为质数

    这篇文章主要为大家详细介绍了C++如何判断一个数字是否为质数,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • Qt利用QJson实现解析数组的示例详解

    Qt利用QJson实现解析数组的示例详解

    这篇文章主要为大家详细介绍了Qt如何利用QJson实现解析数组功能,文中的示例代码讲解详细,对我们学习Qt有一定帮助,需要的小伙伴可以了解一下
    2022-10-10
  • 利用C++11原子量如何实现自旋锁详解

    利用C++11原子量如何实现自旋锁详解

    当自旋锁尝试获取锁时以忙等待(busy waiting)的形式不断地循环检查锁是否可用,下面这篇文章主要给大家介绍了关于利用C++11原子量如何实现自旋锁的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2018-06-06

最新评论