加載圖像時經常會遇見要縮放圖像的情況,這種時候如何決定縮放后圖像對應像素點的像素值,這時候就需要用到插值算法
1.最鄰近插值算法
首先假設原圖是一個像素大小為W*H的圖片,縮放后的圖片是一個像素大小為w*h的圖片,這時候我們是已知原圖中每個像素點上的像素值(即灰度值等)的(⚠️像素點對應像素值的坐標都是整數)。這個時候已知縮放后有一個像素點為(x,y),想要得到該像素點的像素值,那么就要根據縮放比例去查看其對應的原圖的像素點的像素值,然后將該像素值賦值給該縮放后圖片的像素點(x,y)
縮放公式為:
- 根據橫軸,即寬可得:X/x = W/w
- 根據縱軸,即高可得:Y/y = H/h
- 那么能夠得到 f(X,Y)= f( W/w * x, H/h *y)
因此這個時候縮放后的圖片像素點(x,y)的像素值就對應着原圖像素點( W/w * x, H/h *y)的像素值
但是這個時候會出現一個問題就是因為縮放比例的原因,會導致像素點( W/w * x, H/h *y)中的值不是整數,那么就不知道應該對應的是哪個像素點的像素值
這個時候最鄰近插值算法使用的方法就是四舍五入法,表示為[.],所以像素值f(x,y) = f( [W/w * x], [H/h *y])
舉個例子,如果原圖為5*5,縮放后的圖為3*3,那么縮放后的圖的像素點(1,1)對應的就是原圖中([5/3 * 1], [5/3 * 1]) = ([0.6], [0.6]) = (1,1) 像素點對應的像素值
這種方法的好處就是簡單,但是壞處就是太過粗暴,會缺失精度,造成縮放后的圖像灰度上的不連續,在變化地方可能出現明顯鋸齒狀,如下圖所示:(左原圖,右縮放后)
生成圖片應用:https://dailc.github.io/image-process/examples/scale.html
2.雙線性插值算法
假如我們想得到縮放圖像素點對應在原圖中的像素點P= (x,y) 的值,假設我們原圖在Q11 = (x1,y1)、Q12 = (x1,y2), Q21 = (x2,y1) 以及Q22 = (x2,y2) 四個像素點的像素值。如上面最近鄰插值算法的例子,P= (0.6,0.6),那么這時候對應的最近的四個像素點為Q11 = (0,1)、Q12 = (0,0), Q21 = (1,1) 以及Q22 = (1,0),那么P= (0.6,0.6)點的像素值就是根據其與這些點的距離相關,距離越近的點的像素值影響越大,計算過程如下:
- 首先是先根據Q11 = (0,1)和Q21 = (1,1)這兩個像素點的像素值計算得到R1=(x,y1)像素點的像素值,然后根據Q12 = (0,0)和Q22 = (1,0)這兩個像素點的像素值計算得到R2=(x,y2)像素點的像素值
⚠️從上面的例子可以看出,但像素點P= (x,y)離x軸的x1點越近時,像素點Q11 = (0,1)和Q12 = (0,0)對應的像素值多占的比重更重;反之則是Q21 = (1,1)和Q22 = (1,0)對應的像素值多占的比重更重
- 接下來就是根據上一步得到的R1=(x,y1)和R2=(x,y2)這兩個像素點的像素值計算得到最終結果P= (x,y)像素點的像素值
⚠️從該式子可見在y軸上,如果P= (x,y)離y軸的y1點越近時,則由Q11 = (0,1)和Q21 = (1,1)得到的R1=(x,y1)像素點的像素值所占的比重更重;反之則是R2=(x,y2)像素點的像素值所占的比重更重
這樣就能夠得到相應的P= (x,y)的像素值了,例子可見:
很明顯看出效果更好點