1. 程式人生 > >Image Filter and Recover

Image Filter and Recover

這是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,直到遇到下一