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++判断传入的UTC时间是否当天的实现方法

    C/C++判断传入的UTC时间是否当天的实现方法

    在项目中经常会显示一个时间,如果这个时间在今日内就显示为时分秒,否则显示为年月日,有需要的朋友可以参考一下
    2014-01-01
  • Qt操作SQLite数据库的教程详解

    Qt操作SQLite数据库的教程详解

    SQLite是一款开源、轻量级、跨平台的数据库,无需server,无需安装和管理配置。它的设计目标是嵌入式的,所以很适合小型应用,也是Qt应用开发种常用的一种数据库。本文为大家介绍了Qt操作SQLite数据库的示例,希望对大家有所帮助
    2022-12-12
  • C语言二叉排序树的创建,插入和删除

    C语言二叉排序树的创建,插入和删除

    本文主要介绍了Java实现二叉排序树的查找、插入、删除、遍历等内容。具有很好的参考价值,下面跟着小编一起来看下吧
    2021-10-10
  • C++实现ETW进行进程变动监控详解

    C++实现ETW进行进程变动监控详解

    ETW提供了一种对用户层应用程序和内核层驱动创建的事件对象的跟踪记录机制。为开发者提供了一套快速、可靠、通用的一系列事件跟踪特性。本文将利用ETW进行进程变动监控,需要的可以参考一下
    2022-07-07
  • 解析c++中的默认operator=操作的详解

    解析c++中的默认operator=操作的详解

    本篇文章是对c++中的默认operator=操作的应用进行了详细的分析介绍。需要的朋友参考下
    2013-05-05
  • 关于memcpy和memmove的一点重要说明

    关于memcpy和memmove的一点重要说明

    下面小编就为大家带来一篇关于memcpy和memmove的一点重要说明。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-12-12
  • C/C++位段超详细整理大全

    C/C++位段超详细整理大全

    以位为单位来定义结构体中的成员变量所占的空间内存,含有位段的结构体称为位段结构,这篇文章主要给大家介绍了关于C/C++位段的相关资料,需要的朋友可以参考下
    2024-01-01
  • C语言 超详细顺序表的模拟实现实例建议收藏

    C语言 超详细顺序表的模拟实现实例建议收藏

    程序中经常需要将一组数据元素作为整体管理和使用,需要创建这种元素组,用变量记录它们,传进传出函数等。一组数据中包含的元素个数可能发生变化,顺序表则是将元素顺序地存放在一块连续的存储区里,元素间的顺序关系由它们的存储顺序自然表示
    2022-03-03
  • C语言全面梳理文件操作方法

    C语言全面梳理文件操作方法

    这篇文章主要为大家详细介绍了C语言的文件操作,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-05-05
  • c++ vector 常用函数示例解析

    c++ vector 常用函数示例解析

    这篇文章主要介绍了c++ vector 常用函数示例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07

最新评论