C++實(shí)現(xiàn)圖像壓縮的示例代碼
一、問題描述
一幅圖像由n*m個像素點(diǎn)組成,其中每個像素的灰度值范圍是0~255(即需要8bit來存儲像素的灰度值),由此可以得出存儲此圖像需要的存儲空間為n*m*8(bit)。
不難看出,直接采用上述的存儲方式是需要占用很多存儲空間的。此時可以采用圖像壓縮算法來節(jié)省存儲空間。
二、算法分析
1、算法思想
將像素序列分段,段內(nèi)的像素灰度值相似(可以用小于8bit的空間來存儲一個像素灰度值),一段內(nèi)的像素用相同的bit數(shù)來存儲,只需要額外存儲每段的長度和bit數(shù)即可,這樣可以節(jié)省很多空間
于是問題的關(guān)鍵就在于如何分段,使得存儲空間的占用最少
2、算法實(shí)現(xiàn)
假設(shè)像素點(diǎn)的灰度集合為p[n],創(chuàng)建三個表 s[i]、l[i]、b[i],其中:
- s[i]來記錄前 i 個數(shù)字的最優(yōu)處理方式得到的最優(yōu)解。
- l[i]來記錄當(dāng)前第 i 個數(shù)所在組中有多少個數(shù)。
- b[i]中存放前 i 個像素點(diǎn)最后一段位數(shù)的最大值。
假設(shè)產(chǎn)生了m個段,則存儲第i段像素所需要的空間為 : l[i] * b[i] + 11(l[i] * b[i]表示這一段像素本身需要的信息, 11則表示這一段的長度l[i]以及該段像素每一個都用幾位來表示b[i], 即3 + 8 = 11位)
總存儲空間為 11m+∑ l[i]*b[i]
此時只要找出最優(yōu)數(shù)組,即可得到最有效的壓縮方法。最優(yōu)數(shù)組含義是:s[i],1≤i≤n,是像素序列{p1,…,pi}的最優(yōu)分段所需的存儲位數(shù)。
遞推關(guān)系式:
三、代碼實(shí)現(xiàn)
#include<iostream> using namespace std; const int N = 10; void show(int s[], int l[], int b[], int n) { //在輸出s[n]存儲位數(shù)后,s[]數(shù)組則被重新賦值,用來存儲分段的位置 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); }
運(yùn)行結(jié)果:
到此這篇關(guān)于C++實(shí)現(xiàn)圖像壓縮的示例代碼的文章就介紹到這了,更多相關(guān)C++圖像壓縮內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++使用cuBLAS加速矩陣乘法運(yùn)算的實(shí)現(xiàn)代碼
這篇文章主要介紹了C++使用cuBLAS加速矩陣乘法運(yùn)算,將cuBLAS庫的乘法運(yùn)算進(jìn)行了封裝,方便了算法調(diào)用,具體實(shí)現(xiàn)代碼跟隨小編一起看看吧2021-09-09Qt qml實(shí)現(xiàn)動態(tài)輪播圖效果
這篇文章主要為大家詳細(xì)介紹了Qt和qml實(shí)現(xiàn)動態(tài)輪播圖效果的相關(guān)知識,文中的示例代碼講解詳細(xì),具有一定的借鑒價值,有需要的小伙伴可以參考一下2024-12-12Qt創(chuàng)建SQlite數(shù)據(jù)庫的示例代碼
本文主要介紹了Qt創(chuàng)建SQlite數(shù)據(jù)庫的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05OpenCV實(shí)現(xiàn)特征檢測和特征匹配方法匯總
一幅圖像中總存在著其獨(dú)特的像素點(diǎn),這些點(diǎn)我們可以認(rèn)為就是這幅圖像的特征,成為特征點(diǎn),本文主要介紹了OpenCV實(shí)現(xiàn)特征檢測和特征匹配方法,感興趣的可以了解一下2021-08-08C++如何判斷一個數(shù)字是否為質(zhì)數(shù)
這篇文章主要為大家詳細(xì)介紹了C++如何判斷一個數(shù)字是否為質(zhì)數(shù),具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-03-03Qt利用QJson實(shí)現(xiàn)解析數(shù)組的示例詳解
這篇文章主要為大家詳細(xì)介紹了Qt如何利用QJson實(shí)現(xiàn)解析數(shù)組功能,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Qt有一定幫助,需要的小伙伴可以了解一下2022-10-10利用C++11原子量如何實(shí)現(xiàn)自旋鎖詳解
當(dāng)自旋鎖嘗試獲取鎖時以忙等待(busy waiting)的形式不斷地循環(huán)檢查鎖是否可用,下面這篇文章主要給大家介紹了關(guān)于利用C++11原子量如何實(shí)現(xiàn)自旋鎖的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2018-06-06