用最近邻插值(Nearest Neighbor interpolation)进行图片缩放

本文介绍了最近邻插值(Nearest Neighbor interpolation)算法用于图像缩放的基本原理和Python实现。该算法通过找到新像素位置最近的原像素值来填充,适合快速简单的图像缩放。在放大过程中可能会产生锯齿,但在一定比例内能保持较好的图像质量。文章还提及了双线性内插法作为对比,并提到了在darknet框架中采用的双线性内插值缩放算法。

图片缩放的两种常见算法:

  1.     最近邻域内插法(Nearest Neighbor interpolation)
  2.     双向性内插法(bilinear interpolation)

本文主要讲述最近邻插值(Nearest Neighbor interpolation算法的原理以及python实现

基本原理

最简单的图像缩放算法就是最近邻插值。顾名思义,就是将目标图像各点的像素值设为源图像中与其最近的点。算法优点在与简单、速度快。

如下图所示,一个4*4的图片缩放为8*8的图片。步骤:

  1.     生成一张空白的8*8的图片,然后在缩放位置填充原始图片值(可以这么理解)
  2.     在图片的未填充区域(黑色部分),填充为原有图片最近的位置的像素值。

实现算法:

新图像是原图像的线性映射。

设新图像的坐标为P_x,P_y,原图像坐标为p_x,p_y,则像素的映射关系是:

p_x =\frac{W_{old}}{W_{new}}P_x = \frac{W_{old}}{W_{new}}P_x + 0 \cdot P_y

p_y=\frac{H_{old}}{H_{new}}P_y=0\cdot P_x + \frac{H_{old}}{H_{new}}P_y

转换为矩阵形式为:

\begin{bmatrix} p_x\\ p_y \end{bmatrix} = \begin{bmatrix}\frac{W_{old}}{W_{new}} & 0\\ 0 & \frac{H_{old}}{H_{new}}\end{bmatrix}\begin{bmatrix} P_x\\ P_y \end{bmatrix}

所以, 最近邻域内插法进行图像缩放,本质上是一种线性变换,既然是线性的,变换就是一次的,变换矩阵如上。

那么目标图像中的像素点(P_x,P_y),对应原图像的像素点p_x,p_y,要取整。 

实现代码:

import cv2
import numpy as np

def nearest_neighbor_resize(img, new_w, new_h):
    # height and width of the input img
    h, w = img.shape[0], img.shape[1]
    # new image with rgb channel
    ret_img = np.zeros(shape=(new_h, new_w, 3), dtype='uint8')
    # scale factor
    s_h, s_c = (h * 1.0) / new_h, (w * 1.0) / new_w

    # insert pixel to the new img
    for i in range(new_h):
        for j in range(new_w):
            p_x = int(j * s_c)
            p_y = int(i * s_h)

            ret_img[i, j] = img[p_y, p_x]

    return ret_img

img_path = './dice.jpg'
img = cv2.imread(img_path)

#ret_img = nearest_neighbor_resize(img, 222, 220)
ret_img = nearest_neighbor_resize(img, 640, 480)

cv2.imshow("source image", img)
cv2.imshow("after bilinear image", ret_img)
cv2.waitKey()
cv2.destroyAllWindows()

 将一个96*96的图像经过算法转换,变成了一张640*480的图像。

放大到1920*1080

缩小,从892*650->96*96

以上介绍的是最邻近域内插法,实际的媒体处理SOC中,VPU(VE),DE(Display Engine),G2D(2D Graphic accelerator)都具备图像缩放的能力,各自实现的算法不同,但都是基于这两种基础算法,比如AW的VPU,基于的就是双线性内插法实现的图片放大缩小.

至于放大出现锯齿,得看你放多大,1.5倍内的图像质量还是有保证的,再大点出现锯齿也不足为奇,缩放比例算法是不限制的. 可以很大,也可以很小,不一定要求倍数比例缩放.缩略图一般有限制,但是视频都是无级缩放.

在darknet框架的实现中,用的是双线性内差值法进行缩放的,具体原理可以参考这篇博文。

darknet中的图像缩放算法(双线性内插值法)_猫猫虫(——)的博客-优快云博客

关于这段代码的使用,请参考博客:

验证darknet中做scale的算法_papaofdoudou的博客-优快云博客关于图形scale原理的介绍可以参考下面的文章用最近邻插值(Nearest Neighbor interpolation)进行图片缩放_papaofdoudou的博客-优快云博客_最近邻插值算法原理个图片缩放的两种常见算法: 最近邻域内插法(Nearest Neighbor interpolation) 双向性内插法(bilinear interpolation)本文主要讲述最近邻插值(Nearest Neighbor interpolation算法的原理以及python实现基本原理最简单的图像缩放算https://blog.youkuaiyun.com/tugouxp/article/details/123551480?spm=1001.2014.3001.5501

结束!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

papaofdoudou

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值