標籤:

??徹底搞懂雙線性插值

??徹底搞懂雙線性插值

來自專欄 TensorFlow

在FCN中upsampling的時候會用到雙線性插值,雙線性插值實際上是一個非常基礎的圖像resize的手段,但是網上沒有任何一篇博客真正說清楚了每一個細節,什麼叫說清楚?就是當我看完對這個問題的解釋之後能夠用代碼實現出來,這就是說清楚了,也是理解清楚了,但是很抱歉,我暫時沒有發現任何一篇文章真正做到這一點了(我不是針對誰,我是說所有文章的都是複製一下Wikipedia的垃圾,holly crap),在我理解這個知識點的過程中我發現很多人都並沒有真正搞懂,只是知道套用公式而已,所以這片文章兩個目的:個人筆記;他人資料!

step1:什麼是插值?

自行百度

step2:什麼是線性插值?

自行百度

step3:為什麼要對圖像插值?

resize

step4:什麼是雙線性插值?

自行百度

step5:雙線性插值

根據點1??2??算出來m處的像素值:

(p2-p1)/(x2-x1) = (p2-pm)/(x2-xm)

x2-x1 = 1

p2-p1 = (p2-pm)/(x2-xm) => pm = p2 - (p2-p1)*(x2-xm)

根據點3??4??算出來n處的像素值:

(p4-p3)/(x4-x3) = (p4-pn)/(x4-xn)

x4-x3 = 1

p4-p3 = (p4-pn)/(x4-xn) => pn = p4 - (p4-p3)*(x4-xn)

根據點m、n算出來5處的像素值:

(pn-pm)/(yn-ym) = (pn-p5)/(yn-y5)

yn-ym = 1

pn-pm = (pn-p5)/(yn-y5) => p5 = pn - (pn-pm)*(yn-y5)

p5 = p4 - (p4-p3)*(x4-xn) - (p4 - (p4-p3)*(x4-xn) - p2 - (p2-p1)(x2-xm))*(yn-y5)

xn = xm = x5

yn = y3 = y4

通過1,3算a;2,4算b再算5點的結果是相同的

=========================================================

要通過雙線性插值的方法算出dst中每一個像素點的像素值,是通過dst像素點的坐標對應到src圖像當中的坐標;然後通過雙線性插值的方法算出src中相應坐標的像素值

坐標對應關係:

?按比例對應:

SrcX=(dstX)* (srcWidth/dstWidth)

SrcY=(dstY) * (srcHeight/dstHeight)

?按比例對應最後一列沒有辦法參與計算,所以按幾何中心對應:

SrcX+0.5=(dstX+0.5)* (srcWidth/dstWidth)

SrcY+0.5=(dstY+0.5) * (srcHeight/dstHeight)

幾何中心對應中,如果索引是負值,實際上是從一行像素值的末端取值

現在我們需要對上面這個3x3的圖片resize為5x5的圖片:

首先np.zeros([5, 5])生成一個空的shape = [5, 5]的圖片,如下圖

============================================================

找到對應的坐標SrcX和SrcY之後如何找到相鄰的四個坐標呢?

(np.floor(srcX), np.floor(srcY))就是點1??的坐標

(np.floor(srcX)+1, np.floor(srcY)+1)就是點2??的坐標

但是不能超過src的邊界同時坐標必須是整型,綜合起來有:

src_x_0 = int(np.floor(srcX))

src_y_0 = int(np.floor(srcY))

src_x_1 = min(src_x_0 + 1, src_w - 1)

src_y_1 = min(src_y_0 + 1, src_h - 1)

============================================================

按channel循環遍歷每一個坐標點:

for n in range(3): # 對channel循環 for dst_y in range(dst_h): # 對height循環 for dst_x in range(dst_w): # 對width循環 # 目標在源上的坐標 src_x = (dst_x + 0.5) * scale_x - 0.5 src_y = (dst_y + 0.5) * scale_y - 0.5 # 計算在源圖上四個近鄰點的位置 src_x_0 = int(np.floor(src_x)) src_y_0 = int(np.floor(src_y)) src_x_1 = min(src_x_0 + 1, src_w - 1) src_y_1 = min(src_y_0 + 1, src_h - 1) # 雙線性插值 value0 = (src_x_1 - src_x) * src[src_y_0, src_x_0, n] + (src_x - src_x_0) * src[src_y_0, src_x_1, n] value1 = (src_x_1 - src_x) * src[src_y_1, src_x_0, n] + (src_x - src_x_0) * src[src_y_1, src_x_1, n] dst[dst_y, dst_x, n] = int((src_y_1 - src_y) * value0 + (src_y - src_y_0) * value1) return dst

完整代碼:

胡今朝:??雙線性插值的代碼實現?

zhuanlan.zhihu.com圖標
推薦閱讀:

《數學大迷思》摘錄
快跟著華數學英語       錢江晚報
幼兒「卡通數獨」大全,可愛到讓孩子愛上數學!

TAG:數學 | TensorFlow |