数字图像处理学习笔记(七)——用Pycharm及MATLAB实现三种图像内插法(最近邻内插法、双线性内插法、双三次内插法)

Florence ·
更新时间:2024-09-20
· 797 次阅读

数字图像处理(Digital Image Processing)是通过计算机对图像进行去除噪声、增强、复原、分割、提取特征等处理的方法和技术。本专栏将以学习笔记形式对数字图像处理的重点基础知识进行总结整理,欢迎大家一起学习交流!
专栏链接:数字图像学习笔记

★由于之前学习笔记(四)有对于图像三种插值的理论讲解,这里就不再赘余;
可参照此文阅读学习图像的三种内插法

一、Pycharm实现过程 from PIL import Image import matplotlib.pyplot as plt import numpy as np import math def NN_interpolation(img,dstH,dstW): scrH,scrW,_=img.shape retimg=np.zeros((dstH,dstW,3),dtype=np.uint8) for i in range(dstH): for j in range(dstW): scrx=round((i+1)*(scrH/dstH)) scry=round((j+1)*(scrW/dstW)) retimg[i,j]=img[scrx-1,scry-1] return retimg def BiLinear_interpolation(img,dstH,dstW): scrH,scrW,_=img.shape img=np.pad(img,((0,1),(0,1),(0,0)),'constant') retimg=np.zeros((dstH,dstW,3),dtype=np.uint8) for i in range(dstH): for j in range(dstW): scrx=(i+1)*(scrH/dstH)-1 scry=(j+1)*(scrW/dstW)-1 x=math.floor(scrx) y=math.floor(scry) u=scrx-x v=scry-y retimg[i,j]=(1-u)*(1-v)*img[x,y]+u*(1-v)*img[x+1,y]+(1-u)*v*img[x,y+1]+u*v*img[x+1,y+1] return retimg def BiBubic(x): x=abs(x) if x<=1: return 1-2*(x**2)+(x**3) elif x<2: return 4-8*x+5*(x**2)-(x**3) else: return 0 def BiCubic_interpolation(img,dstH,dstW): scrH,scrW,_=img.shape #img=np.pad(img,((1,3),(1,3),(0,0)),'constant') retimg=np.zeros((dstH,dstW,3),dtype=np.uint8) for i in range(dstH): for j in range(dstW): scrx=i*(scrH/dstH) scry=j*(scrW/dstW) x=math.floor(scrx) y=math.floor(scry) u=scrx-x v=scry-y tmp=0 for ii in range(-1,2): for jj in range(-1,2): if x+ii<0 or y+jj=scrH or y+jj>=scrW: continue tmp+=img[x+ii,y+jj]*BiBubic(ii-u)*BiBubic(jj-v) retimg[i,j]=np.clip(tmp,0,255) return retimg im_path='/home/jovyan/img/earth.jpg' image=np.array(Image.open(im_path)) image1=NN_interpolation(image,image.shape[0]*2,image.shape[1]*2) image1=Image.fromarray(image1.astype('uint8')).convert('RGB') image1.save('/home/jovyan/img/NNEarth.jpg') image2=BiLinear_interpolation(image,image.shape[0]*2,image.shape[1]*2) image2=Image.fromarray(image2.astype('uint8')).convert('RGB') image2.save('/home/jovyan/img/BiLinearEarth.jpg') image3=BiCubic_interpolation(image,image.shape[0]*2,image.shape[1]*2) image3=Image.fromarray(image3.astype('uint8')).convert('RGB') image3.save('/home/jovyan/img/BiCubicEarth.jpg')

运行结果截图

原图earth.jpg

在这里插入图片描述
最近邻插值 NNEarth.jpg
在这里插入图片描述
双线性内插法 BiLinearEarth.jpg

在这里插入图片描述

双三次内插法 BiCubicEarth.jpg

在这里插入图片描述

三种方法的细节表现图

在这里插入图片描述
由此可见,插值效果从左到右依次增强
但随之而来的是计算量的增加(也就是说越来越耗时)

在这里插入图片描述
:3是原图,4是最近邻插值,2是双线性内插法,1是双三次内插法;
实现时间分别是4min、5min、12min。

二、MATLAB实现过程

①最近邻插值

代码部分

% 最近邻插值 % 输入图像文件及放大率 % 输出根据放大率变化后的新图像 function nearest_neighbor = nearest_neighbor(filename,R) % 初始化,读入图像,图像数据为m*n*color img = imread('E:\earth.GIF'); % 变化后图像 [row,col,color] = size(img); % 获得图像的行列数及色板数 row = round(row*0.8); % 新图像行 col = round(col*0.8); % 新图像列 % 新图像初始化 % 使用class获得原图像的数据类型,使得新图像数据类型与原图像保持一致 img_new = zeros(row,col,color,class(img)); % 对新图像的行、列、色板赋值 for i = 1:row for j = 1:col for n = 1:color x = round(i/0.8); y = round(j/0.8); % 为了避免x和y等于0而报错,采取+1处理即可 if x == 0 x = x+1; end if y == 0 y = y+1; end img_new(i,j,n) = img(x,y,n); end end end % 显示原图像 figure; imshow(img); title("Original Image"); % 显示新图像 figure; imshow(img_new); title("New Image"); end

运行结果截图

在这里插入图片描述

②双线性插值

代码部分

% 双线性插值 % 输入图像文件及放大率 % 输出根据放大率变化后的新图像 function bilinear_interpolation = bilinear_interpolation(filename,R) % 初始化,读入图像,图像数据为m*n*color img = imread('H:\earth.JPG'); % 变化后图像 [row,col,color] = size(img); % 获得图像的行列数及色板数 row = round(row*0.8); % 新图像行 col = round(col*0.8); % 新图像列 % 新图像初始化 % 使用class获得原图像的数据类型,使得新图像数据类型与原图像保持一致 img_new = zeros(row,col,color,class(img)); % 对新图像的行、列、色板赋值 for i = 1:row for j = 1:col for n = 1:color x = round(i/0.8); y = round(j/0.8); if x == 0 x = x+1; end if y ==0 y = y+1; end u = i/0.8-floor(i/0.8); %求取水平方向上的权重 v = j/0.8-floor(j/0.8); %求取垂直方向上的权重 % 此处需要对图像边缘进行例外处理 % 本例对图像右边缘及下边缘用最近邻插值计算 if i >= row-0.8 || j >= col-0.8 img_new(i,j,n) = img(x,y,n); else img_new(i,j,n) = u*v*img(x,y,n)+(1-u)*v*img(x+1,y,n)+u*(1-v)*img(x,y+1,n)+(1-u)*(1-v)*img(x+1,y+1,n); end end end end % 显示原图像 figure; imshow(img); title("Original Image"); % 显示新图像 figure; imshow(img_new); title("New Image");

运行结果截图

在这里插入图片描述

③双三次插值

代码部分

% Author: Dabao % Time: 2020年4月15日09:12:59 tic; % calculate running time % read original image I I = imread('G:\earth.GIF'); I = double(I); [oh,ow,od] = size(I); zmf = 2; %缩放因子 % initial target image TI th = round(oh*zmf); tw = round(ow*zmf); TI = zeros(th,tw,od); %预分配内存提高计算速度 % add original image with 2 rows and 2 cols % expand the border to prevent calculation overflow a = I(1,:,:); b = I(oh,:,:); temp_I = [a;a;I;b;b]; c = temp_I(:,1,:); d = temp_I(:,ow,:); FI = [c,c,temp_I,d,d]; % fill target image with new pixels for w = 1:tw j = floor(w/zmf)+2; v = rem(w,zmf)/zmf; for h = 1:th i = floor(h/zmf)+2; u = rem(h,zmf)/zmf; A = [s(u+1),s(u),s(u-1),s(u-2)]; C = [s(v+1);s(v);s(v-1);s(v-2)]; for d = 1:od % image's 3 channels B = FI(i-1:i+2,j-1:j+2,d); TI(h,w,d) = A*B*C; end end end figure; imshow(uint8(TI)); toc; % 插值核函数 function w = s(wx) wx = abs(wx); if wx=1 && wx<2 w = 4 - 8*wx + 5*wx^2 - wx^3; else w = 0; end end

运行结果截图

在这里插入图片描述

:为便于比较,以上所有图片均放置统一大小。

欢迎留言,一起学习交流~~~

感谢阅读

END
作者:IT_change



数字图像 学习笔记 数字图像处理 学习 线性 matlab pycharm 图像处理

需要 登录 后方可回复, 如果你还没有账号请 注册新账号