日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

使用C++实现DPCM编码(左向预测8bit、4bit、2bit、1bit和上向预测8bit)(更新过)

發(fā)布時(shí)間:2024/4/30 c/c++ 63 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用C++实现DPCM编码(左向预测8bit、4bit、2bit、1bit和上向预测8bit)(更新过) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

使用C++實(shí)現(xiàn)DPCM編碼(左向預(yù)測(cè)8bit、4bit、2bit、1bit和上向預(yù)測(cè)8bit)

  • 一、DPCM是什么?
  • 二、使用C++實(shí)現(xiàn)DPCM編碼(左向預(yù)測(cè)8bit、4bit、2bit、1bit和上向預(yù)測(cè)8bit)
    • 1、實(shí)驗(yàn)數(shù)據(jù)描述
    • 2、左向預(yù)測(cè)8bit、4bit、2bit、1bit
      • 1)左向預(yù)測(cè)8bit
      • 2)左向預(yù)測(cè)4bit
      • 3)左向預(yù)測(cè)2bit
      • 4)左向預(yù)測(cè)1bit
      • 5)左向預(yù)測(cè)8bit、4bit、2bit、1bit整體代碼
    • 3、上向預(yù)測(cè)8bit
    • 4、整體代碼
    • 5、實(shí)驗(yàn)結(jié)果分析
      • 1)左向預(yù)測(cè)8bit、4bit、2bit、1bit結(jié)果對(duì)比
      • 1)上向預(yù)測(cè)8bit與左向預(yù)測(cè)8bit對(duì)比
  • 三、歸納總結(jié)

一、DPCM是什么?

DPCM–差分脈沖編碼調(diào)制(Differential Pulse code modulation,DPCM),是一種對(duì)模擬信號(hào)的編碼模式,與PCM不同每個(gè)抽樣值不是獨(dú)立的編碼,而是先根據(jù)前一個(gè)抽樣值計(jì)算出一個(gè)預(yù)測(cè)值,再取當(dāng)前抽樣值和預(yù)測(cè)值之差作編碼用。此差值稱為預(yù)測(cè)誤差.抽樣值和預(yù)測(cè)值非常接近(因?yàn)橄嚓P(guān)性強(qiáng)),預(yù)測(cè)誤差的可能取值范圍比抽樣值變化范圍小。所以可用少幾位編碼比特來對(duì)預(yù)測(cè)誤差編碼,從而降低其比特率.這是利用減小冗余度的辦法,降低了編碼比特率。
? 根據(jù)某一模型利用以往的樣本值對(duì)新樣本進(jìn)行預(yù)測(cè),然后將樣本的實(shí)際值與其預(yù)測(cè)值相減得到一個(gè)誤差值,最后對(duì)這一誤差值進(jìn)行編碼。
? 如果模型足夠好,且樣本序列在時(shí)間上相關(guān)性較強(qiáng),則誤差信號(hào)的幅度將遠(yuǎn)遠(yuǎn)小于原始信號(hào),從而得到較大的數(shù)據(jù)壓縮。
在DPCM系統(tǒng)中,需要注意的是預(yù)測(cè)器的輸入是已經(jīng)解碼以后的樣本。之所以不用原始樣本來做預(yù)測(cè),是因?yàn)樵诮獯a端無法得到原始樣本,只能得到存在誤差的樣本。因此,在DPCM編碼器中實(shí)際內(nèi)嵌了一個(gè)解碼器,如編碼器中虛線框中所示。

二、使用C++實(shí)現(xiàn)DPCM編碼(左向預(yù)測(cè)8bit、4bit、2bit、1bit和上向預(yù)測(cè)8bit)

1、實(shí)驗(yàn)數(shù)據(jù)描述

此次用的是Lena.yuv,YUV灰度圖像,如下圖

因?yàn)樗脠D片為灰度圖像,所以需要先把文件中所有值賦為128,以便將UV分量填滿。

//給Buf128全賦值為128for (int i = 0; i < frameWidth * frameHeight / 2; i++){Buf128[i] = 128;}

2、左向預(yù)測(cè)8bit、4bit、2bit、1bit

1)左向預(yù)測(cè)8bit

因?yàn)槭亲笙蝾A(yù)測(cè),所以圖片中每一行的第一個(gè)值無法預(yù)測(cè),所以直接將預(yù)測(cè)值設(shè)為本身的值,插值設(shè)為0。

if (j == 0){yYuceBuf[j + i * frameWidth] = yBuf[j + i * frameWidth];yChazhiBuf[j + i * frameWidth] = 0;}

若不是每一行的第一個(gè)值,那就需要先先計(jì)算插值a,將這個(gè)像素值減去左側(cè)像素的預(yù)測(cè)值。但是因?yàn)閳D像是8bit(灰度值為0-255),所以如果相減值就會(huì)變?yōu)?255——+255因此如果想進(jìn)行8bit量化,需要將插值a/2+127(更新插值d=a/2+127)(量化插值b=a/2)。之后需要進(jìn)行反量化值c,將量化插值b乘2(c=b*2)。之后再將反量化值c與左側(cè)像素預(yù)測(cè)值相加得到本像素預(yù)測(cè)值

else{a = yBuf[j + i * frameWidth] - yYuceBuf[j + i * frameWidth - 1];//計(jì)算插值b = a / 2;//進(jìn)行量化c = b * 2;//進(jìn)行反量化d = b + 128;//進(jìn)行+128yChazhiBuf[j + i * frameWidth] = d;yYuceBuf[j + i * frameWidth] = yYuceBuf[j + i * frameWidth - 1] + c;}}

2)左向預(yù)測(cè)4bit

4bit量化與8bit量化的區(qū)別在于需要將插值a(-255–+255)轉(zhuǎn)變?yōu)?bit插值d,所以需要將插值a/32+7(更新插值d=a/32+7)(量化插值b=a/32),。之后需要進(jìn)行反量化值c,將插值a乘16(c=b*16)。之后再將反量化值c與左側(cè)像素預(yù)測(cè)值相加得到本像素預(yù)測(cè)值

if (j == 0){yYuceBuf[j + i * frameWidth] = yBuf[j + i * frameWidth];yChazhiBuf[j + i * frameWidth] = 0;}else{a = yBuf[j + i * frameWidth] - yYuceBuf[j + i * frameWidth - 1];//計(jì)算插值b = a / 32;//進(jìn)行量化c = b * 32;//進(jìn)行反量化d = b + 7;//進(jìn)行+7yChazhiBuf[j + i * frameWidth] = d*16;yYuceBuf[j + i * frameWidth] = yYuceBuf[j + i * frameWidth - 1] + c;}}

3)左向預(yù)測(cè)2bit

2bit量化與8bit量化的區(qū)別在于需要將插值a(-255–+255)轉(zhuǎn)變?yōu)?bit插值d,所以需要將插值a/128+2(更新插值d=a/128+2)(量化插值b=a/128),。之后需要進(jìn)行反量化值c,將插值a乘128(c=b*128)。之后再將反量化值c與左側(cè)像素預(yù)測(cè)值相加得到本像素預(yù)測(cè)值

if (j == 0){yYuceBuf[j + i * frameWidth] = yBuf[j + i * frameWidth];yChazhiBuf[j + i * frameWidth] = 0;}else{a = yBuf[j + i * frameWidth] - yYuceBuf[j + i * frameWidth - 1];//計(jì)算插值b = a / 128;//進(jìn)行量化c = b * 128;//進(jìn)行反量化d = b + 2;//進(jìn)行+2yChazhiBuf[j + i * frameWidth] = d*64;yYuceBuf[j + i * frameWidth] = yYuceBuf[j + i * frameWidth - 1] + c;}}

4)左向預(yù)測(cè)1bit

1bit量化與8bit量化的區(qū)別在于需要將插值a(-255–+255)轉(zhuǎn)變?yōu)?bit插值d,所以需要將插值a/256+1(更新插值d=a/256+1)(量化插值b=a/256)。之后需要進(jìn)行反量化值c,將插值a乘256(c=b*256)。之后再將反量化值c與左側(cè)像素預(yù)測(cè)值相加得到本像素預(yù)測(cè)值

if (j == 0){yYuceBuf[j + i * frameWidth] = yBuf[j + i * frameWidth];yChazhiBuf[j + i * frameWidth] = 0;}else{a = yBuf[j + i * frameWidth] - yYuceBuf[j + i * frameWidth - 1];//計(jì)算插值b = a / 256;//進(jìn)行量化c = b * 256;//進(jìn)行反量化d = b + 1;//進(jìn)行+1yChazhiBuf[j + i * frameWidth] = d*256;yYuceBuf[j + i * frameWidth] = yYuceBuf[j + i * frameWidth - 1] + c;}

5)左向預(yù)測(cè)8bit、4bit、2bit、1bit整體代碼

//左向預(yù)測(cè)8bit、4bit、2bit、1bit-計(jì)算差值與預(yù)測(cè)值for (int i = 0; i < frameHeight; i++){for (int j = 0; j < frameWidth; j++){if (x == 8){if (j == 0){yYuceBuf[j + i * frameWidth] = yBuf[j + i * frameWidth];yChazhiBuf[j + i * frameWidth] = 0;}else{a = yBuf[j + i * frameWidth] - yYuceBuf[j + i * frameWidth - 1];//計(jì)算插值b = a / 2;//進(jìn)行量化c = b * 2;//進(jìn)行反量化d = b + 128;//進(jìn)行+128yChazhiBuf[j + i * frameWidth] = d;yYuceBuf[j + i * frameWidth] = yYuceBuf[j + i * frameWidth - 1] + c;}}if (x == 4){if (j == 0){yYuceBuf[j + i * frameWidth] = yBuf[j + i * frameWidth];yChazhiBuf[j + i * frameWidth] = 0;}else{a = yBuf[j + i * frameWidth] - yYuceBuf[j + i * frameWidth - 1];//計(jì)算插值b = a / 16;//進(jìn)行量化c = b * 16;//進(jìn)行反量化d = b + 16;//進(jìn)行+64yChazhiBuf[j + i * frameWidth] = d*8;yYuceBuf[j + i * frameWidth] = yYuceBuf[j + i * frameWidth - 1] + c;}}if (x == 2){if (j == 0){yYuceBuf[j + i * frameWidth] = yBuf[j + i * frameWidth];yChazhiBuf[j + i * frameWidth] = 0;}else{a = yBuf[j + i * frameWidth] - yYuceBuf[j + i * frameWidth - 1];//計(jì)算插值b = a / 64;//進(jìn)行量化c = b * 64;//進(jìn)行反量化d = b + 4;//進(jìn)行+4yChazhiBuf[j + i * frameWidth] = d*32;yYuceBuf[j + i * frameWidth] = yYuceBuf[j + i * frameWidth - 1] + c;}}if (x == 1){if (j == 0){yYuceBuf[j + i * frameWidth] = yBuf[j + i * frameWidth];yChazhiBuf[j + i * frameWidth] = 0;}else{a = yBuf[j + i * frameWidth] - yYuceBuf[j + i * frameWidth - 1];//計(jì)算插值b = a / 128;//進(jìn)行量化c = b * 128;//進(jìn)行反量化d = b + 2;//進(jìn)行+2yChazhiBuf[j + i * frameWidth] = d*64;yYuceBuf[j + i * frameWidth] = yYuceBuf[j + i * frameWidth - 1] + c;}}}}

3、上向預(yù)測(cè)8bit

因?yàn)槭巧舷蝾A(yù)測(cè),所以圖片中每一列的第一個(gè)值無法預(yù)測(cè),所以直接將預(yù)測(cè)值設(shè)為本身的值,插值設(shè)為0。
若不是每一列的第一個(gè)值,那就需要先先計(jì)算插值a,將這個(gè)像素值減去上側(cè)像素的預(yù)測(cè)值。但是因?yàn)閳D像是8bit(灰度值為0-255),所以如果相減值就會(huì)變?yōu)?255——+255因此如果想進(jìn)行8bit量化,需要將插值a/2+127(更新插值d=a/2+127)(量化插值b=a/2),。之后需要進(jìn)行反量化值c,將量化插值b乘2(c=b*2)。之后再將反量化值c與上側(cè)像素預(yù)測(cè)值相加得到本像素預(yù)測(cè)值

//上預(yù)測(cè)8bitfor (int i = 0; i < frameWidth; i++){for (int j = 0; j < frameHeight; j++){if (x == 99){if (j == 0){yYuceBuf[i] = yBuf[i];yChazhiBuf[i] = 0;}else{a = yBuf[i + j * frameWidth] - yYuceBuf[i + (j - 1) * frameWidth];//計(jì)算插值b = a / 2;//進(jìn)行量化c = b * 2;//進(jìn)行反量化d = b + 127;//進(jìn)行+127yChazhiBuf[i + j * frameWidth] = d;yYuceBuf[i + j * frameWidth] = yYuceBuf[i + (j - 1) * frameWidth] + c;}}}}

4、整體代碼

#include "iostream" #include"stdio.h" #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include"math.h" #pragma warning (disable:4996) using namespace std; #define u_int8_t unsigned __int8 #define u_int unsigned __int32int main(int argc, char** argv) {char* yuvFileName = NULL;char* yuceFileName = NULL;char* chazhiFileName = NULL;u_int8_t* yBuf = NULL;u_int8_t* yuvBuf = NULL;u_int8_t* yYuceBuf = NULL;u_int8_t* yChazhiBuf = NULL;u_int8_t* Buf128 = NULL;FILE* yuvFile = NULL;FILE* chazhiFile = NULL;FILE* yuceFile = NULL;u_int frameWidth = 0;u_int frameHeight = 0;int a = 0;//量化前插值int b = 0;//量化后值int c = 0;//反量化后值int d = 0;//+128之后值int x = 0;//選擇4bit,8bit量化//讀取數(shù)據(jù)yuv文件數(shù)據(jù)yuvFileName = argv[1];yuceFileName = argv[2];chazhiFileName = argv[3];frameWidth = atoi(argv[4]);frameHeight = atoi(argv[5]);yuvFile = fopen(yuvFileName, "rb");yuvBuf = (u_int8_t*)malloc(frameWidth * frameHeight * 3 / 2);yBuf = (u_int8_t*)malloc(frameWidth * frameHeight);yYuceBuf = (u_int8_t*)malloc(frameWidth * frameHeight);yChazhiBuf = (u_int8_t*)malloc(frameWidth * frameHeight);Buf128 = (u_int8_t*)malloc(frameWidth * frameHeight / 2);fread(yuvBuf, 1, frameWidth * frameHeight * 3 / 2, yuvFile);yuceFile = fopen(yuceFileName, "wb");chazhiFile = fopen(chazhiFileName, "wb");//給Buf128全賦值為128for (int i = 0; i < frameWidth * frameHeight / 2; i++){Buf128[i] = 128;}//讀取y數(shù)據(jù)for (int i = 0; i < frameWidth * frameHeight; i++){yBuf[i] = yuvBuf[i];}//選擇4bit,8bit量化,2bit量化,1bit量化while ((x != 4) && (x != 8) && (x != 2) && (x != 1) && (x != 99)){cout << "如想左向預(yù)測(cè):選擇8bit量化或者4bit量化或者2bit量化或者1bit量化,請(qǐng)輸入“8”或“4”或“2”或“1”" << endl<< "如想上向預(yù)測(cè)請(qǐng)輸入“99”(8bit)" << endl;cin >> x;if (x == 8){cout << "您選擇了左向預(yù)測(cè)8bit量化";}else if (x == 4){cout << "您選擇了左向預(yù)測(cè)4bit量化";}else if (x == 2){cout << "您選擇了左向預(yù)測(cè)2bit量化";}else if (x == 1){cout << "您選擇了左向預(yù)測(cè)1bit量化";}if (x == 99){cout << "您選擇了上向預(yù)測(cè)";}else{cout << "您輸入有誤請(qǐng)重新輸入";}}//左向預(yù)測(cè)8bit、4bit、2bit、1bit-計(jì)算差值與預(yù)測(cè)值for (int i = 0; i < frameHeight; i++){for (int j = 0; j < frameWidth; j++){if (x == 8){if (j == 0){yYuceBuf[j + i * frameWidth] = yBuf[j + i * frameWidth];yChazhiBuf[j + i * frameWidth] = 0;}else{a = yBuf[j + i * frameWidth] - yYuceBuf[j + i * frameWidth - 1];//計(jì)算插值b = a / 2;//進(jìn)行量化c = b * 2;//進(jìn)行反量化d = b + 128;//進(jìn)行+128yChazhiBuf[j + i * frameWidth] = d;yYuceBuf[j + i * frameWidth] = yYuceBuf[j + i * frameWidth - 1] + c;}}if (x == 4){if (j == 0){yYuceBuf[j + i * frameWidth] = yBuf[j + i * frameWidth];yChazhiBuf[j + i * frameWidth] = 0;}else{a = yBuf[j + i * frameWidth] - yYuceBuf[j + i * frameWidth - 1];//計(jì)算插值b = a / 16;//進(jìn)行量化c = b * 16;//進(jìn)行反量化d = b + 16;//進(jìn)行+64yChazhiBuf[j + i * frameWidth] = d*8;yYuceBuf[j + i * frameWidth] = yYuceBuf[j + i * frameWidth - 1] + c;}}if (x == 2){if (j == 0){yYuceBuf[j + i * frameWidth] = yBuf[j + i * frameWidth];yChazhiBuf[j + i * frameWidth] = 0;}else{a = yBuf[j + i * frameWidth] - yYuceBuf[j + i * frameWidth - 1];//計(jì)算插值b = a / 64;//進(jìn)行量化c = b * 64;//進(jìn)行反量化d = b + 4;//進(jìn)行+4yChazhiBuf[j + i * frameWidth] = d*32;yYuceBuf[j + i * frameWidth] = yYuceBuf[j + i * frameWidth - 1] + c;}}if (x == 1){if (j == 0){yYuceBuf[j + i * frameWidth] = yBuf[j + i * frameWidth];yChazhiBuf[j + i * frameWidth] = 0;}else{a = yBuf[j + i * frameWidth] - yYuceBuf[j + i * frameWidth - 1];//計(jì)算插值b = a / 128;//進(jìn)行量化c = b * 128;//進(jìn)行反量化d = b + 2;//進(jìn)行+2yChazhiBuf[j + i * frameWidth] = d*64;yYuceBuf[j + i * frameWidth] = yYuceBuf[j + i * frameWidth - 1] + c;}}}}//上預(yù)測(cè)for (int i = 0; i < frameWidth; i++){for (int j = 0; j < frameHeight; j++){if (x == 99){if (j == 0){yYuceBuf[i] = yBuf[i];yChazhiBuf[i] = 0;}else{a = yBuf[i + j * frameWidth] - yYuceBuf[i + (j - 1) * frameWidth];//計(jì)算插值b = a / 2;//進(jìn)行量化c = b * 2;//進(jìn)行反量化d = b + 128;//進(jìn)行+128yChazhiBuf[i + j * frameWidth] = d;yYuceBuf[i + j * frameWidth] = yYuceBuf[i + (j - 1) * frameWidth] + c;}}}}fwrite(yYuceBuf, frameWidth * frameHeight, 1, yuceFile);fwrite(yChazhiBuf, frameWidth * frameHeight, 1, chazhiFile);fwrite(Buf128, frameWidth * frameHeight / 2, 1, chazhiFile);fwrite(Buf128, frameWidth * frameHeight / 2, 1, yuceFile);fclose(chazhiFile);fclose(yuceFile);fclose(yuvFile);free(yBuf);free(yuvBuf);free(yYuceBuf);free(yChazhiBuf);free(Buf128);return 0; }

5、實(shí)驗(yàn)結(jié)果分析

1)左向預(yù)測(cè)8bit、4bit、2bit、1bit結(jié)果對(duì)比


由圖像可知,量化bit數(shù)的減少會(huì)導(dǎo)致插值邊緣越來越不明顯,并且得到的恢復(fù)圖像與原始圖像的差距也越來越大,與預(yù)期相符

1)上向預(yù)測(cè)8bit與左向預(yù)測(cè)8bit對(duì)比


由圖可知,圈出的地方,上向預(yù)測(cè)是白,左向預(yù)測(cè)是黑,因?yàn)橥ㄟ^原圖可看出,在這個(gè)部分,下側(cè)像素比上側(cè)像素要白,也就是下側(cè)灰度值(down)大于上冊(cè)灰度值(up),所以u(píng)p-down為正值因此為白;而這個(gè)部分的右側(cè)像素比左側(cè)像素黑,也就是右側(cè)像素值(right)小于左側(cè)像素值(left),所以right-left為負(fù)值因此為黑。這樣也就能分辨出上向預(yù)測(cè)與左向預(yù)測(cè)。

三、歸納總結(jié)

通過此次實(shí)驗(yàn)進(jìn)一步了解DPCM編碼,并完成了DPCM左向8bit、4bit、2bit、1bit以及上向8bit的代碼實(shí)現(xiàn)。同時(shí),經(jīng)過詳細(xì)分析左向預(yù)測(cè)8bit、4bit、2bit、1bit和上向預(yù)測(cè)8bit的實(shí)驗(yàn)結(jié)果,明白了其之間的差異,并會(huì)通過結(jié)果區(qū)分左向預(yù)測(cè)與上向預(yù)測(cè)。并且熟悉鞏固了C++語言的使用,為后續(xù)進(jìn)一步學(xué)習(xí)數(shù)據(jù)壓縮打下了基礎(chǔ)。

與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的使用C++实现DPCM编码(左向预测8bit、4bit、2bit、1bit和上向预测8bit)(更新过)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。