日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【数字图像处理】图像内插“双线性内插法 Bilinear interpolation”代码演示(以像素中心点确定像素位置)(图像放大缩小)具有低通滤波性质,使高频分量受损,图像轮廓可能会有一点模糊

發布時間:2025/3/20 编程问答 23 豆豆

文章目錄

    • 原理
    • 代碼
      • 開了個jit加速(沒有提高太多)
      • 開numexpr加速
    • 總結
    • 直接調用opencv庫(不知為啥那么快)

原理

雙線性內插法是使用目標點四周最近的四個點,沿距目標點x方向、y方向的權重關系,去分配給目標點顏色值

如圖,P點是目標點,Q1、Q2、Q3、Q4是目標點周圍的四個點,先分別對Q1、Q2和Q3、Q4沿x方向進行內插,得到R1、R2兩個點,再對R1、R2沿y方向進行內插,得到目標點P

計算公式如下


注意:上面點p(x,y)里的x為換算到原圖的(pos_x - 1),y為換算到原圖后的(pos_y - 1)

我怎么想了一下,以像素右下角貌似不對,應該以像素中心點確定位置!!!

距離應該以絕對值來表示的,另外,以先計算四個點的方法確實好使,減少判斷(先計算點,再判斷點是否重合)

具體以正式運行的代碼為準

代碼

開了個jit加速(沒有提高太多)

# -*- coding: utf-8 -*- """ @File : 雙線性內插法(續).py @Time : 2020/6/27 21:05 @Author : Dontla @Email : sxana@qq.com @Software: PyCharm """ import cv2 as cv import numpy as np import numexpr as ne from numba import jit@jit(nopython=True) # # Set "nopython" mode for best performance, equivalent to @njit def BI(img, resolution):srcH, srcW, _ = img.shapedstH, dstW = resolution# img_ = np.zeros((dstH, dstW, 3), dtype=np.uint8)img_ = np.zeros((dstH, dstW, 3), dtype=np.uint8)# 列外層,行內層for y in range(dstH):for x in range(dstW):print(y, x)pos_y = (y + 0.5) / dstH * srcH # 比較的時候要以像素實際的位置(像素四方塊中心點),不能以像素下標pos_x = (x + 0.5) / dstW * srcW # 比較的時候要以像素實際的位置(像素四方塊中心點),不能以像素下標if pos_y <= 0.5 or pos_y >= srcH - 0.5: # 上區或下區# 先判斷是上區還是下區if pos_y <= 0.5: # 上區y_lim_index = 0else: # 下區y_lim_index = srcH - 1if pos_x <= 0.5: # 左上區或左下區img_[y, x] = img[y_lim_index, 0]elif pos_x >= srcW - 0.5: # 右上區或右下區img_[y, x] = img[y_lim_index, srcW - 1]else: # 中上區或中下區(需要判斷)if pos_x - int(pos_x) == 0.5: # 剛好與像素點重合# x_min_pos = x_max_pos = pos_xx_min_index = x_max_index = int(pos_x - 0.5)img_[y, x] = img[0, int((x_min_index + x_max_index) / 2)]else: # 與像素點不重合if pos_x - int(pos_x) < 0.5: # 左距大于等于右距x_min_pos = int(pos_x) - 0.5x_max_pos = int(pos_x) + 0.5else: # 左距小于右距x_min_pos = int(pos_x) + 0.5x_max_pos = int(pos_x) + 1.5x_min_index = int(x_min_pos - 0.5)x_max_index = int(x_max_pos - 0.5)fq1 = img[y_lim_index, x_min_index]fq2 = img[y_lim_index, x_max_index]img_[y, x] = (fq1 * (x_max_pos - pos_x) + fq2 * (pos_x - x_min_pos)) / (x_max_pos - x_min_pos)else: # 中區(y向)if pos_x <= 0.5 or pos_x >= srcW - 0.5: # 左中區或右中區if pos_x <= 0.5:x_lim_index = 0else:x_lim_index = srcW - 1if pos_y - int(pos_y) == 0.5: # 剛好與像素點重合y_min_index = y_max_index = int(pos_y - 0.5)img_[y, x] = img[0, int((y_min_index + y_max_index) / 2)]else: # 與像素點不重合if pos_y - int(pos_y) < 0.5: # 上距大于等于下距y_min_pos = int(pos_y) - 0.5y_max_pos = int(pos_y) + 0.5else: # 左距小于右距y_min_pos = int(pos_y) + 0.5y_max_pos = int(pos_y) + 1.5y_min_index = int(y_min_pos - 0.5)y_max_index = int(y_max_pos - 0.5)fq1 = img[y_min_index, x_lim_index]fq3 = img[y_max_index, x_lim_index]img_[y, x] = (fq1 * (y_max_pos - pos_y) + fq3 * (pos_y - y_min_pos)) / (y_max_pos - y_min_pos)else: # 正中區if pos_x - int(pos_x) == 0.5: # x方向點剛好與像素點重合x_min_index = x_max_index = int(pos_x - 0.5)if pos_y - int(pos_y) == 0.5: # y方向點剛好與像素點重合y_min_index = y_max_index = int(pos_y - 0.5)img_[y, x] = img[int((y_min_index + y_max_index) / 2), int((x_min_index + x_max_index) / 2)]else: # y方向點與像素點不重合if pos_y - int(pos_y) < 0.5: # 上距大于等于下距y_min_pos = int(pos_y) - 0.5y_max_pos = int(pos_y) + 0.5else: # 左距小于右距y_min_pos = int(pos_y) + 0.5y_max_pos = int(pos_y) + 1.5y_min_index = int(y_min_pos - 0.5)y_max_index = int(y_max_pos - 0.5)fq1 = img[y_min_index, int((x_min_index + x_max_index) / 2)]fq3 = img[y_max_index, int((x_min_index + x_max_index) / 2)]img_[y, x] = (fq1 * (y_max_pos - pos_y) + fq3 * (pos_y - y_min_pos)) / (y_max_pos - y_min_pos)else:if pos_x - int(pos_x) < 0.5: # 左距大于等于右距x_min_pos = int(pos_x) - 0.5x_max_pos = int(pos_x) + 0.5else: # 左距小于右距x_min_pos = int(pos_x) + 0.5x_max_pos = int(pos_x) + 1.5x_min_index = int(x_min_pos - 0.5)x_max_index = int(x_max_pos - 0.5)if pos_y - int(pos_y) == 0.5: # y方向點剛好與像素點重合y_min_index = y_max_index = int(pos_y - 0.5)fq1 = img[int((y_min_index + y_max_index) / 2), x_min_index]fq2 = img[int((y_min_index + y_max_index) / 2), x_max_index]img_[y, x] = (fq1 * (x_max_pos - pos_x) + fq2 * (pos_x - x_min_pos)) / (x_max_pos - x_min_pos)else: # y方向點與像素點不重合if pos_y - int(pos_y) < 0.5: # 上距大于等于下距y_min_pos = int(pos_y) - 0.5y_max_pos = int(pos_y) + 0.5else: # 左距小于右距y_min_pos = int(pos_y) + 0.5y_max_pos = int(pos_y) + 1.5y_min_index = int(y_min_pos - 0.5)y_max_index = int(y_max_pos - 0.5)fq1 = img[y_min_index, x_min_index]fq2 = img[y_min_index, x_max_index]fq3 = img[y_max_index, x_min_index]fq4 = img[y_max_index, x_max_index]fr1 = (fq1 * (x_max_pos - pos_x) + fq2 * (pos_x - x_min_pos)) / (x_max_pos - x_min_pos)fr2 = (fq3 * (x_max_pos - pos_x) + fq4 * (pos_x - x_min_pos)) / (x_max_pos - x_min_pos)img_[y, x] = (fr1 * (y_max_pos - pos_y) + fr2 * (pos_y - y_min_pos)) / (y_max_pos - y_min_pos)# print(fq1, fq2, fq3, fq4, img_[y, x])# print(x_min_index, x_max_index, y_min_index, y_max_index) # 0.0 1.0 1.0 2.0# lx, ly = x_max_index - x_min_index, y_max_index - y_min_index# fr1 = ((x_max_index - x) * fq1 + (x - x_min_index) * fq2) / lx# fr2 = ((x_max_index - x) * fq3 + (x - x_min_index) * fq4) / lx# img_[y, x] = ((y_max_index - y) * fr1 + (y - y_min_index) * fr2) / lyreturn img_# 在這里設置圖片最終分辨率(縱,橫) resolution = 1800, 2400 # print(type(scale)) # <class 'tuple'> img = cv.imread('cat.jpg') print(img.shape) # (600, 800, 3) img_ = BI(img, resolution) cv.imshow('win1', img) cv.imshow('win2', img_) cv.waitKey(0)

結果:

原圖:

開numexpr加速

開了還沒numba.jit快,不開了。。。

總結

代碼的適應性比較強,無論分辨率是多少的圖片,放大或縮小,成比例變換或非成比例變換,都不會產生bug,但是代碼邏輯有些混亂,代碼重復率較高,計算公式最好多使用函數的形式表示,同時這樣在使用numba加速時,能獲得較好的效果

參考文章1:雙線性插值算法進行圖像縮放及性能效果優化

另外,引用中又發現了一些端倪


他說這樣能夠提高運算速度

直接調用opencv庫(不知為啥那么快)

# -*- coding: utf-8 -*- """ @File : 雙線性內插法3(直接調用opencv庫).py @Time : 2020/6/29 17:14 @Author : Dontla @Email : sxana@qq.com @Software: PyCharm """ import cv2 as cvdef BI(img, resolution):return cv.resize(img, (resolution[1], resolution[0]), interpolation=cv.INTER_CUBIC)# return cv.resize(img, (resolution[1], resolution[0]), interpolation=cv.INTER_LINEAR)# return cv.resize(img, (resolution[1], resolution[0]), interpolation=cv.INTERSECT_PARTIAL)img = cv.imread('cat_150-200.jpg') # print(img.shape) # (600, 800, 3) resolution = 600, 800 img_ = BI(img, resolution) cv.imshow('win1', img) cv.imshow('win2', img_) # cv.imwrite('cat_150-200.jpg', BI(img, resolution)) cv.waitKey(0)

原圖:

結果:

參考文章:opencv庫實現圖像最近鄰、雙線性、雙三次插值

總結

以上是生活随笔為你收集整理的【数字图像处理】图像内插“双线性内插法 Bilinear interpolation”代码演示(以像素中心点确定像素位置)(图像放大缩小)具有低通滤波性质,使高频分量受损,图像轮廓可能会有一点模糊的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。