【CV视觉基础】图像插值算法&OpenCV框架

简介

在图像处理中,平移变换、旋转变换以及放缩变换是一些基础且常用的操作。这些几何变换并不改变图象的象素值,只是在图象平面上进行象素的重新排列。在一幅输入图象 [ u , v ] [u,v] [uv]中,灰度值仅在整数位置上有定义。然而,输出图象[x,y]的灰度值一般由处在非整数坐标上的 ( u , v ) (u,v) uv值来决定。这就需要插值算法来进行处理,常见的插值算法有最近邻插值、双线性插值和三次样条插值。

算法理论介绍与推荐

最近邻插值算法原理

在这里插入图片描述
在这里插入图片描述
实现代码 numpy和cv2

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_al
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)

缺点: 用该方法作放大处理时,在图象中可能出现明显的块状效应

双线性插值算法

线性插值多项式:
在这里插入图片描述
双线性插值就是线性插值在二维时的推广,在两个方向上做三次线性插值,具体操作如下图所示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

映射方法

向前映射法

可以将几何运算想象成一次一个象素地转移到输出图像中。如果一个输入象素被映射到四个输出像素之间的位置,则其灰度值就按插值算法在4个输出象素之间进行分配。称为向前映射法,或象素移交影射。 注:从原图象坐标计算出目标图象坐标镜像、平移变换使用这种计算方法

向后映射法

向后映射法(或象素填充算法)是输出象素一次一个地映射回到输入象素中,以便确定其灰度级。如果一个输出象素被映射到4个输入象素之间,则其灰度值插值决定,向后空间变换是向前变换的逆。
注:从结果图象的坐标计算原图象的坐标

旋转、拉伸、放缩可以使用
解决了漏点的问题,出现了马赛克

实现
在这里插入图片描述
通常,缩小使用cv.INTER_AREA,放缩使用cv.INTER_CUBIC(较慢)和cv.INTER_LINEAR(较快效果也不错)。默认情况下,所有的放缩都使用cv.INTER_LINEAR。

import cv2
 
if __name__ == "__main__":
    img = cv2.imread('D:/image/yuner.jpg', cv2.IMREAD_UNCHANGED)
    
    print('Original Dimensions : ',img.shape)
    
    scale_percent = 30       # percent of original size
    width = int(img.shape[1] * scale_percent / 100)
    height = int(img.shape[0] * scale_percent / 100)
    dim = (width, height)
    # resize image
    resized = cv2.resize(img, dim, interpolation = cv2.INTER_LINEAR)

    fx = 1.5
    fy = 1.5

    resized1 = cv2.resize(resized, dsize=None, fx=fx, fy=fy, interpolation = cv2.INTER_NEAREST)
    
    resized2 = cv2.resize(resized, dsize=None, fx=fx, fy=fy, interpolation = cv2.INTER_LINEAR)
    print('Resized Dimensions : ',resized.shape)
    
    cv2.imshow("Resized image", resized)
    cv2.imshow("INTER_NEAREST image", resized1)
    cv2.imshow("INTER_LINEAR image", resized2)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值