Datawhale_计算机视觉基础_图像处理(1)——最近邻插值原理及numpy实现

一、最近邻插值原理

原理:根据缩放后的位置,最近邻的像素作为缩放后位置的像素

公式如下:
f ( m p o s , n p o s ) = h ( m p o s s r c 宽 d s t 宽 , n p o s s r c 长 d s t 长 ) \begin{array}{c} f(m_{pos}, n_{pos}) = h(\frac{m_{pos}src_{宽}} {dst_{宽}}, \frac{n_{pos}src_{长}} {dst_{长}}) \end{array} f(mpos,npos)=h(dstmpossrc,dstnpossrc)

f() 为缩放后像素位置 对应原图的像素的位置
h() 为原图像的像素位置

可以分布化简:
原图片宽 / 缩放后图片的宽
宽 f = s r c 宽 / d s t 宽 宽_{f} = src_{宽}/dst_{宽} f=src/dst
原图片长 / 缩放后图片的长
长 f = s r c 长 / d s t 长 长_{f} = src_{长}/dst_{长} f=src/dst
那么公式就变成
f ( m , n ) = h ( 宽 f ∗ m , 长 f ∗ n ) f(m, n)=h(宽_{f} * m,长_{f} * n) f(m,n)=h(fm,fn)

numpy.array.shape 中 (m ,n ,z) m为行(y-宽 垂直方向), n为列(x-长 水平方向)
这有助于 后面用numpy去实现

例如:
将 3 * 3 数组 用近邻方法 转化成 4 * 4
宽 f = 长 f = 3 / 4 = 0.75 宽_{f}=长_{f}=3/4=0.75 f=f=3/4=0.75

  • 新图 第一个点(0,0)对应的像素位置
    f ( 0 , 1 ) = h ( 0 ∗ 0.75 , 1 ∗ 0.75 ) = h ( 0 , 1 ) f(0,1) = h(0*0.75, 1 * 0.75) = h(0, 1) f(0,1)=h(00.75,10.75)=h(0,1)
  • 新图 最后个点(3,3)
    f ( 3 , 3 ) = h ( 3 ∗ 0.75 , 3 ∗ 0.75 ) = h ( 2 , 2 ) f(3,3) = h(3*0.75, 3 * 0.75) = h(2, 2) f(3,3)=h(30.75,30.75)=h(2,2)
    在这里插入图片描述

二、最近邻插值numpy实现

import numpy as np
def near_insert_1color(pic_dt, resize, x_scale=None, y_scale=None):
	"""
	最近邻插值(图片 m * n * 图层)
	param pic_dt: 为一个图片的一个图层的数据 len(pic_dt) == 2
	param resize: set (长, 宽)
	param x_scale: float 长度缩放大小
	param y_scale: float 宽带缩放大小
	"""
    m, n = pic_dt.shape
    # 获取新的图像的大小
    if resize is None:
        n_new, m_new  =  np.round(x_scale * n).astype(int), np.round(y_scale * m).astype(int)
    else:
        n_new, m_new  = resize
    
    fx, fy = n / n_new, m / m_new # src_{长}/dst_{长}, src_{宽}/dst_{宽}
    # 初始化X, Y的位置点
    idx_x_orign = np.array(list(range(n_new)) * m_new).reshape(m_new, n_new)
    idx_y_orign = np.repeat(list(range(m_new)), n_new).reshape(m_new, n_new)
    # 需要的近邻的位置
    x_indx = np.round(idx_x_orign * fx).astype(int)
    y_indx = np.round(idx_y_orign * fy).astype(int)
    return   pic_dt[y_indx, x_indx]

def near_insert(pic_dt_, resize, fx=None, fy=None):
    # 三个通道分开处理再合并
    if len(pic_dt_.shape) == 3:
        out_img0 = near_insert_1color(pic_dt_[:,:,0], resize=resize, x_scale=fx, y_scale=fy)
        out_img1 = near_insert_1color(pic_dt_[:,:,1], resize=resize, x_scale=fx, y_scale=fy)
        out_img2 = near_insert_1color(pic_dt_[:,:,2], resize=resize, x_scale=fx, y_scale=fy)
        out_img_all = np.c_[out_img0[:,:,np.newaxis], out_img1[:,:,np.newaxis], out_img2[:,:,np.newaxis]]
    else:
        out_img_all = near_insert_1color(pic_dt_, resize=resize, x_scale=fx, y_scale=fy)
    return out_img_all

2-1 对例子的3*3用near_insert_1color实现

pic_3_3 = np.array([[56, 23, 15],
                    [65, 32, 78], 
                    [12, 45, 62]])
pic_new = near_insert(pic_3_3, (4, 4))

"""
显然和想象的一样
>>> pic_new
array([[56, 23, 15, 15],
       [65, 32, 78, 78],
       [12, 45, 62, 62],
       [12, 45, 62, 62]])
"""

三、openCV2实现

import cv2 
"""
v2.resize(
src	【必需】原图像
dsize	【必需】输出图像所需大小 (长 , 宽) (shape[1], shape[0])
fx	【可选】沿水平轴的比例因子
fy	【可选】沿垂直轴的比例因子
interpolation	【可选】插值方式
)

cv.INTER_NEAREST	最近邻插值
cv.INTER_LINEAR	双线性插值
cv.INTER_CUBIC	基于4x4像素邻域的3次插值法
cv.INTER_AREA	基于局部像素的重采样
"""
# 读取图片
img =  cv2.imread(pic_fil, cv2.IMREAD_UNCHANGED) 
# cv2.resize 方法 放大1.5倍
resized1_5_img_near = cv2.resize(img
				, dsize=None
				, fx=1.5
				, fy=1.5)
				, interpolation=cv2.INTER_NEAREST)

# 用自己写的函数实现近邻插值
out_img_all = near_insert(img, resize=None, fx=1.5, fy=1.5)

四、实现比对

cv2.imshow('Origin', img)
cv2.imshow('near_insert*1.5', out_img_all)
cv2.imshow('Origin-[INTER_NEAREST] * 1.5', resized1_5_img_near)
cv2.waitKey(0)
  • 原始图片
    在这里插入图片描述

  • 两种方式放大的图片(左边是numpy写的, 右边是cv的包)
    在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Scc_hy

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

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

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

打赏作者

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

抵扣说明:

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

余额充值