Image Filter and Recover
阿新 • • 發佈:2020-05-03
這是CS50的第四次大作業,順便學習了影象的入門知識。
## 基礎
黑白圖(bitmap)的每個畫素點只能取值0/1,1代表白色,0代表黑色。
常見的圖片格式有JPEG/PNG/BMP,這些格式都支援RGB,每個畫素點可以用多個bit表示,常見的是24-bit,紅、綠、藍分別由8bit表示,範圍0~255。
BMP圖的開始位置有兩個header,第一個叫`BITMAPFILEHEADER`,14B;第二個叫`BITMAPINFOHEADER`,40B。接下來的每個畫素點是按照BGR的順序儲存的。
## 過濾器
Image Filter就是對原圖的畫素點的畫素進行操作,得到一幅新圖。主要有下面幾種:
- Grayscale
將RGB圖變為灰度圖。將每個畫素點的R/G/B的值改為相同,值越大,亮度越大。一般取三色的平均值。
- Sepia
比較像懷舊濾鏡,有很多演算法可以做,主要就是對3種顏色乘一些係數,做一些加減運算。
- Reflection
左右翻轉。
- Blur
影象模糊,對每個畫素點的每種顏色,取其周圍3*3格子的平均值。
- Edges
邊緣檢測,可以用Sobel Operator去做:
Blur是對周圍的格子取平均,Sobel是求一個加權和,對於x和y方向,有兩個kernel:
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200502165239931.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0VJTWFkcmlnYWw=,size_16,color_FFFFFF,t_70)
對每個畫素點的每種顏色,用周圍3*3格子的對應顏色分別去乘Gx/Gy,得到加權和sumx/sumy。
以x為例,如果左右兩邊差不多,那麼加權和接近0,否則得到一個大正數/負數,說明很有可能是**兩個物體的分界**。
綜合考慮x和y方向,取$\sqrt{sumx^2+sumy^2}$,再四捨五入到0~255之間。
對於邊緣的格子,可以做padding,圍一圈全黑(0)的格子,相當於不用計算。
## 圖片恢復
JPEG的前三個位元組分別是`0xff, 0xd8, 0xff`,第四個位元組的前四位是`1110`,這些可以唯一標識JPEG檔案。
記憶卡上所有圖片是連續儲存的,最小單位每塊512B,不到一塊的後面補0,不影響顯示,每張圖片可能佔若干塊。
可以每次讀512B扔到buffer裡,如果是jpeg,就將其寫入新檔案、繼續讀512B,直到遇到下一