通過這些


媽耶200贊了

先說明一下,這個回答只是對計算機存儲圖像的最最最基礎的原理做一個科普,實際上對於一個圖像文件和視頻文件而言,本身還有文件格式、編碼和壓縮等各種內容,不是以本回答這種原始二進位進行存儲的,但是那些說起來就很複雜了,有時間的話我會在這個答案後面追加一些額外的介紹

=====================分割線==================

首先說答案:如果你有一串很長的,和某一個視頻相同的0和1序列,把這些序列存到計算機里,然後用播放器打開這個序列,你會發現播放器放的就是這個視頻!

這是數字世界的本質:所有東西都是由1和0構成的,如果你擁有了這串1和0,那你就擁有了數字世界裡面的這個東西。至於為什麼,往下看

首先視頻這個東西,和電影、動畫片等本質上是一樣的,都是一連串的圖片按順序顯示,因為人眼的暫留特性,只要圖片是連續變化的,那麼人看著就像是在動起來一樣。

那麼我們回到本質,先看看一張圖片是怎麼存儲的

不舉那麼複雜的例子,舉一個最簡單的火柴人動畫

見過數碼刺繡吧?就是那種刺繡一個格子一個格子的,現在我們在數碼刺繡上面畫畫

假設我們有一個8X8個格子的小畫板(或者小刺繡布),先畫上火柴人

然後我們假定,塗黑的地方是1,沒塗黑的地方是0,那麼第一行是不是可以表示成

0 0 1 1 1 0 0 0

同理我們把所有行都寫出來(累死我了)

0 0 1 1 1 0 0 0
0 0 1 1 1 0 0 0
0 0 0 1 0 0 0 0
1 1 0 1 1 1 0 0
1 0 0 1 0 1 1 0
0 0 1 1 0 0 0 0
0 1 1 0 1 0 0 0
0 1 0 0 1 0 0 0

你脫掉眼鏡看一看,裡面的1組成的形狀是不是和裡面的火柴人一樣呢?這就對了,這就是這一幅圖在計算機裡面的存儲模式,一共有多少個1和0呢?

這個刺繡布是8行8列,那麼一共是8X8=64個1和0 (具體幾個1幾個0我就不數了)

=====================分割線=====================

剛剛說了,視頻是一連串圖片連續播放的結果,那麼一定會有一大堆圖片,那我可以再畫一張

同樣可以寫出一樣的8X8的那一堆1和0

把兩張圖片很快速的放在一起間隔顯示,就是這樣

看,動起來了吧!

計算機裡面存儲圖像和視頻就是這麼簡單,無非是格子更多了,這樣就能畫得更精細了

翻出我以前畫的一張線稿

我們放大來看

看見沒,本質上還是在塗方塊,和火柴人沒有本質的區別,區別只是在於格子更多,畫畫的人更牛(不是說我哈哈哈哈,我是個手殘)

那照片呢?一樣的,只不過畫畫的變成了感測器,感測器負責把外界的光按照同樣的方法塗格子而已!本質還就是在塗格子

至於彩色圖像我最後再說。

回過頭來我們來看看視頻裡面有多少個1和0,還是以我們的火柴人動畫為例

一張圖片的1和0總數為64個

為了人眼看起來足夠的連貫,一秒至少要顯示24張圖片,那麼一秒鐘的火柴人視頻1和0數量為

64X24=1536 個1和0

如果你要顯示1分鐘的火柴人動畫,那麼需要

1536X60=92160 個1和0

別驚訝,對於數字世界來說,這個數字很小了

換句話說,這92160個有規律的1和0,就代表了這1分鐘的火柴人動畫

你擁有了這92160個有規律的1和0,就意味著你擁有了這1分鐘的火柴人動畫

你把這92160個有規律的1和0告訴朋友,你朋友也擁有了這1分鐘的火柴人動畫

數字世界就是這麼簡單【大霧

==================補充知識分割線======================

怎麼顯示彩色的?

在上面的火柴人裡面,我每一個格子只能代表塗黑或者不塗黑,那麼如果我選擇塗別的顏色呢?

可以的

三原色知道吧,就是紅R綠G藍B

道家云:一生二,二生三,三生萬物。三原色就是典型的三生萬物

通過紅綠藍的組合,可以表示這個世界大部分的顏色,舉個例子

這個紫色就是由 65%的紅,65%的藍混合而成的

如果我用255來表示100%,那麼紫色我可以寫成

R166 G0 B166 == 紫色

換句話說,我把剛剛的火柴人動畫裡面的每一個1換成R166 G0 B166,那這個火柴人就是個紫色的火柴人

同樣的道理,每一個格子都可以換成不同的顏色代號,那這個8X8的小圖片就可以變成彩色的圖片

那麼一幅8X8的彩色圖片需要多少個0和1呢?

在計算機中,存儲一個0~255的數字,需要8個0和1,那麼RGB一共需要24個0和1,那麼一張8X8的圖片需要

24X8X8=1536 個0和1

看,一張圖頂之前一秒鐘的火柴人動畫

那一分鐘彩色動畫或者視頻需要多少呢?

1536X24X60= 2211840 個0和1

別以為這個好像很大的數字了,咱換算一下吧

2211840/8/1024 = 270KB 大概是0.26MB不到的大小

所以說起來,數字世界的本質就是這麼簡單,就是0和1的組成

當然,簡單的背後一定是複雜,為了讓你能盡量用少的空間放下足夠多的的視頻和圖片,後面還有大量的編碼、演算法在支撐著整個數字世界,涉及到編碼就很複雜了,就不具體展開了


文件是不是都由0和1組成的

顯然是。現在的通用計算機(包括手機、嵌入式設備)在邏輯層只有這一種文件內容。

一個視頻文件包含多少0和1呢?

有文件大小乘以八那麼多個。因為文件尺寸以位元組計算,現在幾乎所有的計算機都是一位元組八位二進位數。

通過這些0和1可以得到視頻嗎?

顯然必須可以,不然你在電腦上是怎麼看視頻的?

簡單來講,不考慮一些不重要的事情(比如壓縮演算法),視頻是由一系列圖片組成的,每秒放出特定數量的圖片就是視頻。而每張圖片是由寬度x高度那麼多個格子組成的,(對於彩色內容)每個格子是三個位元組,來表示紅綠藍的強度。


多說無益,給你看實際的。

打開一個視頻。這個視頻多長。當然,我擦掉點網站鏈接什麼。

視頻都是聲音和圖像組成的,我這個是mp4封裝,當然封裝和壓制還能講一整天,這裡忽略,總之你下載下來的視頻,最後到手就是這麼個mp4的玩意,裡面你要看的都有了。

你看紅色箭頭。位率,也有人叫碼率的,也就是說,這個通道上,一秒鐘有多少數據。當然,現在的視頻都是可變比特率的,根據畫面動的快慢自動變化。好在我這個視頻,都是室內鏡頭,沒什麼高速公路追車的,變化不大,就近似看成一樣好了。

6899kbps,就是我這個視頻,一秒鐘快7000,000 b,你注意,計算機裡面B是byte,b是bits,差八倍。bit就是0或1,當然bit到Byte還有什麼校驗位啊,字長啊,放到計算機裡面還有塊長啊之類的,我們這不是考組成,都忽略了,理解個原理就成。

一秒鐘就是七百萬個0或1. 我這個電影,兩個多小時。504億個0和1.正常語速大概200到300音節一分鐘,你要講一分鐘不停全速念,得五年半才能念完。

這0和1可不能隨便,是有要求的。

比如上面這一幀,截圖下來看是這樣的,這就是最常見的我們IT講的「二進位」,普通人講的0和1,其實是十六進位啦,省的太長顯示不下來,畢竟二進位和十六進位天生fit

比如我在中間插入了一大段其他的0,1,紅色部分

再打開,就變成這樣了,因為每個位元組都是有自己的要求的,不能隨便上。

所以要直接寫出500億個有格式規定的01來生成視頻,幾乎是不可能的啦,起碼現在科技不行。


可以。

雖然也許和題主想得到的答案無關,不過作為大作業報告之前的預演,我來口胡一些關於視頻編碼的內容吧。

在提到視頻編碼之前,不得不先說點圖像編碼的廢話。

首先,我們要說到「顏色空間」這樣的一個概念…

比如說平時我們比較常見的RGB…這也是和顯示器的顯示原理很搭的一種做法。

啊,很可惜,我現在是寸頭,沒辦法演示——但是自己剪一根頭髮放在電腦顯示器上,很有可能就能見到紅綠藍三種顏色…

那麼,對於任意一種給定的顏色,我們都可以用紅綠藍三種顏色的線性組合,拼湊出一個「人眼看起來一樣」的顏色。

那麼除了RGB之外,還有沒有別的顏色空間?

眾所周知,我們對一張圖片的第一印象往往取決於圖片亮不亮以及色不色(劃掉)。

啊,剛才是說錯了。

眾所不周知,我們對一個顏色的觀感當中,亮度往往比色調更重要…(比如說舊式電視,黑白電視也能看)

比如說,讓我迫害一下某人…如下兩圖,左側是只有亮度的,右側是只有色度的(

所以我們希望能夠把亮度和色度分開來。一個很常見的做法就是YUV顏色空間…

啊,當然,實際上我們用的更多的是YCbCr(亮度、藍色組分、紅色組分)…不過既然大家都這麼叫,那就索性都叫做YUV了吧…

在解決了「如何用數字化的方式表示一個顏色」的問題之後,我們進入下一個話題。

如何用數字化的方式表示一張圖片。

我們在這裡找一個照片…然後拉到最大的放大倍數看一看…

啊,雖然WIndows自帶畫圖的極限就是這樣了…不過得益於網圖不怎麼清楚,我們還是看到了明顯的小的「方塊」對吧…(很明顯,畫師並不會在人的頭上畫方塊玩…)

實際上,圖片本來就是作為無數個小的「採樣點」來表示的。

在每個點採集自己的顏色分量,就能夠重組成這個圖片…

啊,當然,也有一些比較迷惑的行為…

比如說,我們剛剛說過對於YUV顏色空間來說,Y要比UV重要一些對吧。

所以就有了YUV420YUV422YUV440之類的玄學方案——在這些設計里,Y的採樣點要比UV的採樣點多…

雖然一般情況下達不到那個解析度,但是實際上,人眼作為一個光學系統,它的角解析度上限也是被瑞利判據所約束的。

因此,只要這些採樣點足夠密,它們之間形成的角度足夠小——人就是沒辦法分辨出來它們的。

說完了圖像那點事,我們再向時間方向稍微稍微延伸那麼一點…

小時候很多人應該都在各種奇怪的讀物上聽說過視覺殘留…

這也就意味著,當圖像快速變化時,它看起來就是「運動著」的…

一般認為只要超過每秒24幀,就可以給人這種感覺了…

換句話說,一個很zz的做法是——我們完全可以把「一系列的圖片」當成一個視頻的儲存形式。

當然,對於我們題干中提到的0-1打字機同學來說,這樣進行輸入顯得太菜了,而且另一方面,手指也會有點麻。

所以就要開始尋找可以少打幾個字的方式。

一個比較簡單的做法是,試圖降低幀率…

當然,如果只是單純降低幀率,視頻的效果會顯著下降…

所以我們提出了「隔行掃描」的做法——一幀只有單數行,一幀只有雙數行,或者類似的…

那麼沒有的那些行怎麼辦呢?一個比較直白的做法是保持上一幀的樣子…

當然,還可以用附近的像素進行估計…什麼的做法。如果要具體分析可能要提到反商矩陣等一系列我聽說這課不考試就忘了的東西,所以暫時不這麼做吧…有興趣的話可以買教材啊!

數字視頻處理及應用京東¥ 24.40去購買?

但是這種做法聽起來就很不「elegant」…

所以我們還要討論其它的做法。

比如說,在現在的很多視頻格式中頗為常用的DCT變換。

啊,說到底它就是一矩陣的像素點值做一個變換,這個變換本身並不縮小大小,但是它使得視頻中的高頻成分被丟到右下角去、低頻成分被丟到左上角(最左上角為直流分量)。

這樣的好處在於,左上角的部分往往集中了絕大多數的能量,而右下角的東西往往比較小而且沒什麼用。

因此我們可以降低對右下角的表示精度,從而使得需要的內容變小…

當然,對整張圖片做DCT的效率未免丟人,所以我們一般會把圖片拆分成小塊(常見8x8…),再對每一個小塊進行DCT。

這樣做有一個明顯的缺點,就是…雖然每個「小塊」都儘可能保持了比較好的清晰度,但是小塊之間會有明顯的差距…用隨便什麼軟體在保持解析度的前提下把jpg品質降低,大概就能看到小小的方塊了。

比如下圖,是將品質因數降低很多之後得到的,

我想大家都能看到明顯的「方塊化」了……

為了解決這個問題,一般會在解碼器里設計一個「環路濾波」的過程,靠這個過程把塊與塊之間的邊緣「軟化」掉…從而得到一個看起來還說得過去的圖像。

另一方面,比如「奔跑的人」、比如「疾馳的列車」…其中的很多部分是可以用其它部分來表示的…

為了這個,人們還提出了所謂「運動估計」的方式。把圖像分割成一個又一個小「塊」,之後用一個塊去表示另一個相近的塊。然後,只要用很小的代價去表示它們之間的差值就可以啦!

為了方便,畢竟我們一般只考慮附近的塊嘛,所以直接把附近的有可能被「引用」的塊排一下順序,記下來用第幾個就好了…

啊,說了這麼多廢話,到現在,我們的所謂「視頻文件」還是一大攤圖表(指DCT結果)以及箭頭(指運動向量)。

那麼,我們還要想一個辦法,把它展開成一長串的01流。

只是展開當然是容易的——從左到右、從上到下、每個塊開頭說一下運動向量——問題是,人力有窮,為了能夠更快地敲完這個視頻,我們還需要進行更進一步的壓縮。

比如說,基於算術編碼的壓縮方案——或者如果說點更廣為人知的東西來類比的話——Huffman編碼,這玩意現在已經普及到在推理遊戲里出現了(逃

雖然我不太清楚人腦計算算術編碼(以及維護上下文)的可行性,但是姑且認為「大神」自然是有這個能力的。

那麼,該如何把一個DCT塊展開成一個位元組流呢?又如何把若干個DCT塊組成的圖像展開呢?又如何把若干個圖像組成的序列展開?最後,如何讓它成為一個可以播放的視頻呢?

對於DCT塊,為了讓壓縮更加有效,我們往往希望其中的值分布的不那麼「均勻」。

換句話說,我們希望高頻部分(較小)和低頻部分可以被區分開。因此,我們往往採用一種類似Z形的順序依次編碼這些值。

而每一幀,本質上也是按照約定好的格式和順序,編碼一些基本信息和算術編碼需要的東西…剩下的就是還原這些DCT塊需要用到的內容了…(具體的Block格式什麼的就要看用的是什麼編碼方案了倒是…實際上我這裡說的幀格式也並不怎麼普適……

然後把這些幀按順序連起來,在開頭(以及,有的時候,結尾)添加上一些視頻的「容器」所需要的信息。

這些信息往往是整個視頻的一些關鍵信息…比如視頻的元信息、比如需要使用的解碼器之類的…

「老師,我知道怎麼把視頻轉換成位元組流了!」我高高地舉起手,向老師示意。

「那個內容剛才就已經講完了啊」老師看了看我,「不是告訴你們用ffmpeg了嗎…」


這是個數字信息科學的問題。

我們常說的數字化是因應人的識別能力有限,以及呈現設備能力等原因。把無限的信息,通過採樣量化等手段壓縮起來,變成有限信息。

譬如說,自然界有千變萬化的顏色,但是,反正你都辨別不了 ,數字化過程中,就可以只取2^24種,成為真色彩(當然有很多種色彩模型,不展開了),因此我們需要一個24位的空間(就是24個0或者1)來存放顏色,這是編碼過程。最後為了能正確呈現,我們就要有一個約定,哪個數字代表哪種顏色,需要跟編碼一致,這就是解碼過程。

同樣的一個數字,既可以代表一個顏色,也可以代表一個字元,也可以代表一個音頻採樣。怎麼來解讀一串數字,關鍵就是靠約定


推薦閱讀:
相关文章