在 Python 中使用双线性插值调整大小

2024-01-05

我正在尝试使用双线性插值手动实现调整图像大小。 到目前为止,我得到的是插值本身的函数,它似乎工作正常,但调整大小函数似乎仅在角上正常工作:

def bilinear_interpolation(image, y, x):
height = len(image)
width = len(image[0])

x1 = min(math.floor(x), width - 1)
y1 = min(math.floor(y), height - 1)
x2 = min(math.ceil(x), width - 1)
y2 = min(math.ceil(y), height - 1)

a = image[y1][x1]
b = image[y2][x1]
c = image[y1][x2]
d = image[y2][x2]

new_pixel = a * (1 - x) * (1 - y)
new_pixel += b * y * (1 - x)
new_pixel += c * x * (1 - y)
new_pixel += d * x * y
return round(new_pixel)
def resize(image, new_height, new_width):

new_image = [[0 for _ in range(new_width)] for _ in range(new_height)]

for y in range(new_height):
    for x in range(new_width):
        x_ = (x / (new_width - 1)) * len(image[0])
        y_ = (y / (new_height - 1)) * len(image)

        new_image[y][x] = bilinear_interpolation(image, y_, x_)

return new_image

所以对于矩阵:

[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]

I got

[[1, 4], [9, 12], [13, 16]]

代替

[[1, 4], [7, 10], [13, 16]]

提前致谢。


用于计算x_ and y_,你可以看看我的下面answer https://stackoverflow.com/a/69996885/4926757.

公式为:

x_ = (x - x_scaled_center) * scale_x + x_orig_center
y_ = (y - y_scaled_center) * scale_y + y_orig_center

在双线性插值中,您错过了计算dx and dy:

dx = x - x1
dy = y - y1

new_pixel = a * (1 - dx) * (1 - dy)
new_pixel += b * dy * (1 - dx)
new_pixel += c * dx * (1 - dy)
new_pixel += d * dx * dy

这是一个完整的代码示例(将结果与cv2.resize):

import cv2
import math
import numpy as np

def bilinear_interpolation(image, y, x):
    height = image.shape[0]
    width = image.shape[1]

    x1 = max(min(math.floor(x), width - 1), 0)
    y1 = max(min(math.floor(y), height - 1), 0)
    x2 = max(min(math.ceil(x), width - 1), 0)
    y2 = max(min(math.ceil(y), height - 1), 0)

    a = float(image[y1, x1])
    b = float(image[y2, x1])
    c = float(image[y1, x2])
    d = float(image[y2, x2])

    dx = x - x1
    dy = y - y1

    new_pixel = a * (1 - dx) * (1 - dy)
    new_pixel += b * dy * (1 - dx)
    new_pixel += c * dx * (1 - dy)
    new_pixel += d * dx * dy
    return round(new_pixel)


def resize(image, new_height, new_width):
    new_image = np.zeros((new_height, new_width), image.dtype)  # new_image = [[0 for _ in range(new_width)] for _ in range(new_height)]

    orig_height = image.shape[0]
    orig_width = image.shape[1]

    # Compute center column and center row
    x_orig_center = (orig_width-1) / 2
    y_orig_center = (orig_height-1) / 2

    # Compute center of resized image
    x_scaled_center = (new_width-1) / 2
    y_scaled_center = (new_height-1) / 2

    # Compute the scale in both axes
    scale_x = orig_width / new_width;
    scale_y = orig_height / new_height;

    for y in range(new_height):
        for x in range(new_width):
            x_ = (x - x_scaled_center) * scale_x + x_orig_center
            y_ = (y - y_scaled_center) * scale_y + y_orig_center

            new_image[y, x] = bilinear_interpolation(image, y_, x_)

    return new_image

img = cv2.imread('graf.png', cv2.IMREAD_GRAYSCALE)  # http://man.hubwiz.com/docset/OpenCV.docset/Contents/Resources/Documents/db/d70/tutorial_akaze_matching.html

new_width = 500
new_height = 400

resized_img = resize(img, new_height, new_width)

# Reference for testing
reference_resized_img = cv2.resize(img, (new_width, new_height), interpolation=cv2.INTER_LINEAR)

abs_diff = cv2.absdiff(reference_resized_img, resized_img)
print('max abs_diff = ' + str(abs_diff.max()))  # 1 gray level difference

cv2.imshow('img', img)
cv2.imshow('resized_img', resized_img)
cv2.imshow('reference_resized_img', reference_resized_img)
cv2.imshow('abs_diff*10', abs_diff*10)
cv2.waitKey()
cv2.destroyAllWindows()

img:
enter image description here

resized_img:
enter image description here


注意(对于其他用户):

  • 其实现更多的是学术性多于实践性。
    如果有人正在寻找一种有效的实施方式,请寻找其他地方。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Python 中使用双线性插值调整大小 的相关文章

随机推荐

  • 使用 R grid 包的线条

    我正在使用 R 和 cygwin 并尝试绘制一些基本图形 以下是 Paul Murrell 的一篇论文中的一个简单示例 library grid x lt rnorm 50 y lt x rnorm 50 1 2 rx lt range x
  • 要在实体框架中编辑多对多关系,为什么必须先清除集合?

    我有以下代码用于编辑用户所在的部门 出于某种原因 method1导致 EF 尝试再次插入关系 并导致主键错误 其中method2成功了 为什么代码是method1不知道通过重新分配值 我只想要新的部门集合 是method2更新值的首选方法
  • 多个服务主机有什么好处?一个 ServiceHost 是否支持一个端点上的多个同时连接?

    我正在考虑自行托管我的 WCF 服务 而不是使用 IIS 对我来说 一个大问题是我是否需要像 IIS 那样实例化多个服务主机 或者一个就足够了 除了由于隔离而导致的安全原因之外 多个服务主机还有什么好处吗 一台服务主机可以同时为一个端点上的
  • ssis 过滤掉值以字母开头的行

    在 SSIS 项目中 我尝试从 Excel 文件源中筛选出行 其中列的值以字母开头 后跟数字 某些单元格包含多个值 并且并非所有单元格都遵循某种数据类型格式 目前数据流程如下 Excel Source gt Data Conversion
  • Google Drive API - 获取包括文件夹在内的文件列表

    我需要列出用户驱动器云中的所有图像 I use https www googleapis com drive v2 files https www googleapis com drive v2 files使用正确的过滤器来查询所有图像 我
  • inotify 不会在文件修改时触发通知

    我一直在调整这个例子here http www ibm com developerworks linux library l ubuntu inotify index html使其反复监视文件的 修改 我的代码是here http past
  • Fluent NHibernate - 配置 Oracle Data Provider ODP

    我是 NHibernate 和 Fluent NHibernate 的新手 我正在尝试让以下配置正常工作 private static ISessionFactory CreateSessionFactory return Fluently
  • Python 中的正则表达式反向引用问题

    我不知道为什么这不起作用 也许我遗漏了 Python 正则表达式的一些东西 这是我的正则表达式和我希望它匹配的示例字符串 PHONE REGEX lt gt phone EXAMPLE
  • 向传单地图添加任意图像

    我正在尝试使用传单来显示比平时更小的地图 所以我不想使用普通的平铺系统 我不关心平滑缩放和在需要时加载更高分辨率的图块 相反 我尝试从图像文件添加光栅图像 可以这么说当我谷歌 手绘地图 时出现 So I try download file
  • 将角色关联到正在运行的 AWS 实例

    为了运行AWS监控脚本 http docs aws amazon com AmazonCloudWatch latest DeveloperGuide mon scripts perl html http docs aws amazon c
  • 创建 TCP 网络错误以进行单元测试

    我想在测试期间创建各种网络错误 我在 Linux 上直接在 C 中使用 Berkely 套接字 API 我正在 Boost Test 中的另一个线程中运行模拟服务器 该线程在本地主机上侦听 例如 我想在连接期间创建超时 到目前为止 我已经尝
  • 取消图标的亮点

    在编程和查看所有不同的应用程序时 我意识到应用程序商店中的某些应用程序顶部没有亮起的突出显示 使其看起来更具 3D 效果 我有一个应用程序的想法 但我需要去掉重点 该应用程序已在 Xcode 中编程 因此如果有人回答 那就太好了 谢谢 fr
  • C# 中的多媒体定时器中断(前两个中断不好)

    我使用分辨率为 1 毫秒 周期为 10 毫秒的多媒体计时器 问题是多媒体计时器严重中断了前两个事件 因为我得到了 1 ms 的差异 这不是我想要的 public partial class Form1 Form public Form1 I
  • 使用 django-autocomplete-light 添加更多字段时出错

    我有一个问题 我正在使用 2 个库 Django 自动完成灯 and Django 动态表单集 两人都非常擅长完成自己的工作 第一个用于自动完成 第二个用于使 django 表单集动态化 but当你想加入这两个时 就会出现问题 问题的图像
  • 工具栏按钮单击事件功能

    我已经在中创建了设置按钮Toolbar 现在每当我单击设置按钮时 我都需要将屏幕导航到设置屏幕 menu menu
  • 如何淡化 UIImageView 的角/边缘/边框

    我在论坛上找不到这个 所以我决定发布这个 我有一个 UIImageView 其代码如下 可以使图像彼此淡出 void viewDidLoad super viewDidLoad Do any additional setup after l
  • Emacs 23、emacsclient 参数?

    我最近安装了 Emacs 23 在 OS X Leopard 上 并尝试了 emacs 服务器 我尝试了两种方法 1 将 server start 放入我的 emacs文件中 2 在终端运行emacs daemon 在单独的试验中 不是同时
  • 有没有办法获得有关未使用功能的警告?

    我想在代码库中找到未使用的函数 包括跨编译单元 我使用 gcc 作为我的编译器 这是一个例子 foo c 假设适当foo h void foo void bar main c include
  • Capybara 找不到 Semantic-ui 的选择框

    I use capybara with 水豚 webkit and 语义用户界面 但似乎下拉菜单不能开箱即用 因为
  • 在 Python 中使用双线性插值调整大小

    我正在尝试使用双线性插值手动实现调整图像大小 到目前为止 我得到的是插值本身的函数 它似乎工作正常 但调整大小函数似乎仅在角上正常工作 def bilinear interpolation image y x height len imag