bmp 雙線性插值 雙線性插值原理與實現

2021-10-13 05:44:35 字數 3360 閱讀 6594

在對影象進行空間變換的過程中,典型的情況是在對影象進行放大處理的時候,影象會出現失真的現象。這是由於在變換之後的影象中,存在著一些變換之前的影象中沒有的畫素位置。為了說明這個問題,不妨假設有一副大小為64x64的灰度影象a,現在將影象放大到256x256,不妨令其為影象b,如圖1所示。顯然,根據簡單的幾何換算關係,可以知道b影象中(x,y)處的畫素值應該對應著a影象中的(x/4,y/4)處的象素值,即

b(x,y) = a(x/4,y/4) (式1)

對於b中的(4,4),(4,8),(4,16)…(256,256)這些位置,通過式1就可以計算出其在a中的位置,從而可以得到灰度值。但是,對於b中的(1,1),(1,2),(1,3)…等等這些座標點而言,如果按照式1計算的話,那麼它們在a中對應的座標不再是整數。比如,對於b中的座標點(1,1),其在a中的對應座標就變成了(0.25,0.25)。對於數字影象而言,小數座標是沒有意義的。因此,必須考慮採用某種方法來得到b中畫素點在a中對應位置上的灰度級。處理這一問題的方法被稱為影象灰度級插值。常用的插值方式有三種:最近鄰域插值、雙線性插值、雙三次插值。理論上來講,最近鄰域插值的效果最差,雙三次插值的效果最好,雙線性插值的效果介於兩者之間。不過對於要求不是非常嚴格的影象插值而言,使用雙線性插值通常就足夠了。

本文中將採用matlab實現乙個雙線性插值的程式。雙線性插值的原理如圖2所示。影象之間座標對映有兩種方式:如果是從原影象的座標對映到目標影象,稱為前向對映,反之則稱為後向對映。顯然,雙線性插值採用的是後向對映方式。下面對圖2的具體含義進行說明。首先,根據幾何關係,從b影象中的座標(x,y)得到a影象中的座標(x/4,y/4),但是,對映得到的這個座標(x/4,y/4)並沒有剛好位於a影象中的整數座標上,而是對映到了四個畫素座標(a,b)、(a+1,b)、(a,b+1)、(a+1,b+1)所圍成的矩形之間,其中,a、b是a影象的整數座標。現在的問題就是如何根據a(a,b)、a(a+1,b)、a(a,b+1)、a(a+1,b+1)這四個點上的灰度級求出a(x/4,y/4)處的灰度級。雙線性插值技術採用的方法是:假設a影象的灰度級變化在縱向方向上是線性變化的,這樣根據直線方程或者幾何比例關係就能夠求得(a,y/4)和(a+1,y/4)座標處的灰度級a(a,y/4)和a(a+1,y/4)。然後,再假設在((a,y/4),a(a,y/4))和(a+1,y/4),a(a+1,y/4))這兩點所確定的直線上,灰度級仍然是線性變化的。求出直線方程,於是就可以求得(x/4,y/4)處的灰度級a(x/4,y/4)。這就是雙線性插值的基本思路。其中用到的兩個基本假設是:首先灰度級在縱向方向上是線性變化的,然後假定灰度級在橫向方向上也是線性變化的。

圖1 影象縮放示意圖

圖2 雙線性插值示意圖

附錄:i=imread('image1.bmp');

[m,n]=size(i);

k=3;

width = k * m;

height = k * n;

j = uint8(zeros(width,height));

% width scale and height scale

widthscale = m/width;

heightscale = n/height;

% bilinear interplot

for x = 5:width - 5

for y = 5:height - 5

xx = x * widthscale;

yy = y * heightscale;

if (xx/double(uint16(xx)) == 1.0) & (xx/double(uint16(xx)) == 1.0)

j(x,y) = i(int16(xx),int16(yy));

else % a or b is not integer

a = double(uint16(xx)); % (a,b) is the base-dot

b = double(uint16(yy));

x11 = double(i(a,b)); % x11

x12 = double(i(a,b+1)); % x12

x21 = double(i(a+1,b)); % x21

x22 = double(i(a+1,b+1)); % x22

j(x,y) = uint8( (b+1-yy) * ((xx-a)*x21 + (a+1-xx)*x11) + (yy-b) * ((xx-a)*x22 +(a+1-xx) * x12)); % calculate j(x,y)

endend

end% 顯示影象

imwrite(j, '放大的影象.jpg', 'jpg');

imshow(i),title('原圖');

figure

imshow(j),title('放大圖');

i=imread('image1.bmp');

[m,n]=size(i);

k=3;

width = k * m;

height = k * n;

j = uint8(zeros(width,height));

% width scale and height scale

widthscale = m/width;

heightscale = n/height;

% bilinear interplot

for x = 5:width - 5

for y = 5:height - 5

xx = x * widthscale;

yy = y * heightscale;

if (xx/double(uint16(xx)) == 1.0) & (xx/double(uint16(xx)) == 1.0)

j(x,y) = i(int16(xx),int16(yy));

else % a or b is not integer

a = double(uint16(xx)); % (a,b) is the base-dot

b = double(uint16(yy));

x11 = double(i(a,b)); % x11

x12 = double(i(a,b+1)); % x12

x21 = double(i(a+1,b)); % x21

x22 = double(i(a+1,b+1)); % x22

j(x,y) = uint8( (b+1-yy) * ((xx-a)*x21 + (a+1-xx)*x11) + (yy-b) * ((xx-a)*x22 +(a+1-xx) * x12)); % calculate j(x,y)

endend

end% 顯示影象

imwrite(j, '放大的影象.jpg', 'jpg');

imshow(i),title('原圖');

figure

imshow(j),title('放大圖');

bmp 雙線性插值 雙線性插值原理和實現

在對影象進行空間變換的過程中,典型的情況是在對影象進行放大處理的時候,影象會出現失真的現象。這是由於在變換之後的影象中,存在著一些變換之前的影象中沒有的畫素位置。為了說明這個問題,不妨假設有一副大小為64x64的灰度影象a,現在將影象放大到256x256,不妨令其為影象b,如圖1所示。顯然,根據簡單...

雙線性插值

雙線性插值作為opencv中預設使用的影象縮放演算法,其效果和速度都是不錯的。並且效果也比較穩定,計算複雜度並不算太高。我看了很多網上的演算法,自己也沒看太懂,下面是從網上找的雙線性插值 演算法的講解。影象的雙線性插值放大演算法中,目標影象中新創造的象素值,是由源影象位置在它附近的2 2區域4個鄰近...

雙線性插值

轉至 雙線性插值,這個名字咋一聽很高大上的樣紙,再在維基百科上一查 見文末,我去,一堆的公式嚇死人 像俺這種半文盲,看到公式腦子就懵的型別,真心給跪。雖然看著好複雜,但仔細一看道理再簡單不過了,所以還是自己梳理一下好。雙線性插值,顧名思義就是兩個方向的線性插值加起來 這解釋過於簡單粗暴,哈哈 所以只...