双线性插值算法详解并用matlab实现「建议收藏」

双线性插值算法详解并用matlab实现「建议收藏」参考:https://blog.csdn.net/huang1024rui/article/details/46545329数字图像处理双线性插值算法介绍双线性插值法又称为二次线性插值法。在传统的插值算法中,它的插值效果比nearest插值法要好的多,但是速度上也必然会慢很多,比bicubic(二次立方法)效果要差,但速度上要优于bicubic。它主要思想就是利用某像…

大家好,又见面了,我是你们的朋友全栈君。

参考:
https://blog.csdn.net/huang1024rui/article/details/46545329
数字图像处理

双线性插值算法

介绍

双线性插值法又称为二次线性插值法。在传统的插值算法中,它的插值效果比nearest插值法要好的多,但是速度上也必然会慢很多,比bicubic(二次立方法)效果要差, 但速度上要优于bicubic。
它主要思想就是利用某像素点周围的4个像素来计算出浮点坐标像素值。
举个例子,假设我们现在需要获得坐标为(6.6,4)的像素值T,该坐标离(6,4)和(7,4)这2个像素点最近。设(6,4)像素值为T_64,(7,4)像素值为T_74,直观地表现在图上就是:
这里写图片描述
按照距离越近混合的比例越大的原则可以得到:
这里写图片描述
其中u,v分别表示浮点坐标距离(6,4)和(7,4)这2个像素点的距离。此时就使用了一次线性插值得到了(6.6,4)的像素值。
通过上面一个简短的例子,我们知道了如何使用2个邻点来计算出坐标分量有一个为小数的情况,那么如果我们坐标分量2个都为小数呢,该如何插值?双线性插值通过多次线性插值就解决了这样的问题。
如图:
这里写图片描述
上图的求解思路用语言表述就是:先用一次线性插值分别求出f1、f2的像素值,然后再对f1、f2利用一次线性插值得到f的像素值。这就是双线性插值的原理。
用公式来展示一下求解的过程:
先求出2个红点的像素值,然后根据这2个像素值做一次线性插值得到目标点f的像素值。
这里写图片描述
这里写图片描述
这里写图片描述

伪代码

输入:
Img:原始图像
zmf:为缩放因子
输出:
new_img:输出图像
step1:求出原图像Img的大小,记为height×width×channel,接着生成大小为(zmf×height)×(zmf×width)×channel的全0矩阵new_img;
step2 :把Img边界扩展一圈得到IT,大小为(height+2)×(width+2)×channel;
step3 :对于缩放后的新图new_img中某像素位置(zi,zj)映射回(zi/zmf,zj/zmf)原图Img中得到(x,y),由于(x,y)不一定为整数,故向下取整得到(i,j),其中x = i+u,y = j+v,且u,v[0,1)为小数部分;
step4 :根据下式进行双线性插值计算f(zi,zj)的值,也就是其对应的像素值。
f(zi,zj)=f(x,y)=(1-u)×(1-v)×f(i,j)+(1-u)×v×f(i,j+1)+u×(1-v)×f(i+1,j)+u×v×f(i+1,j+1);
其中f(zi,zj)表示新图(zi,zj)处的像素值,f(x,y)表示新图(zi,zj)对应在原图中的位置(x,y)处的像素值;
step5:重复3-4,直至将矩阵new_img

2 matlab代码

2.1 主程序代码

clear;
close all;
clc;
img = imread('image/my_gray_512.jpg');
[ori,img_new] = imblizoom(img,0.5);
% [ori,img_new] = imblizoom('image/my_gray_512.jpg',0.5);
img_show(ori,img_new);

2.2 核心代码

function [ original,new_img ] = imblizoom( original,zmf )
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
%-----------------双线性插值法缩放矩阵或图像---------------------
% Input:
% original:原始图像图像文件名或矩阵(整数值(0~255))
% zmf:缩放因子,即缩放的倍数
% Output:
% original: 原始图像矩阵
% new_img: 缩放后的图像矩阵 
% Usage:
% [original,new_img] = imblizoom('ImageFileName',zmf)
% 对图像I进行zmf倍的缩放
% Or:
% [original,new_img] = imblizoom(I,zmf)
% 对矩阵I进行zmf倍的缩放
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % 
%% Step1 对数据进行预处理
if ~exist('original','var') || isempty(original)
    error('输入图像 I未定义或为空!');
end
if ~exist('zmf','var') || isempty(zmf) || numel(zmf) ~= 1
     error('位移矢量 zmf未定义或为空或 zmf中的元素超过2!');
end
if isstr(original)
    [original,M] = imread(original);
end
if zmf <= 0
     error('缩放倍数 zmf的值应该大于0!');
end
%% Step2 通过原始图像和缩放因子得到新图像的大小,并创建新图像
[height,width,channel] = size(original);
new_height = round(height*zmf); % 计算缩放后的图像高度,最近取整
new_width = round(width*zmf); % 计算缩放后的图像宽度,最近取整
new_img = zeros(new_height,new_width,channel); % 创建新图像

%% Step3 扩展原始矩阵I边缘
img_scale = zeros(height+2,width+2,channel); % 为了边界点考虑的
img_scale(2:height+1,2:width+1,:) = original;
% % ========================================================
% 为4周各添加的一行或列做值的初始化
% % ========================================================= 
% 为扩展而来的各边赋值
img_scale(1,2:width+1,:) = original(1,:,:);
img_scale(height+2,2:width+1,:) = original(height,:,:);
img_scale(2:height+1,1,:) = original(:,1,:);
img_scale(2:height+1,width+2,:) = original(:,width,:);
% 用原图的4个顶点为扩展而来的4个顶点赋值
img_scale(1,1,:) = original(1,1,:);
img_scale(1,width+2,:) = original(1,width,:);
img_scale(height+2,1,:) = original(height,1,:);
img_scale(height+2,width+2,:) = original(height,width,:);
%% ============================================================
% Step4 由新图像的某个像素(zi,zj)映射到原始图像(ii,jj)处, 并在原始
% 图像的(ii,jj)位置利用其周围4个像素点进行插值得到(ii,jj)处的像素值
% % ====================================================================
for zj = 1:new_width         % 对图像进行按列逐元素扫描
    for zi = 1:new_height
        % (zi,zj)表示在新图中的坐标,(ii,jj)表示在原图中的坐标
        % 注意:(ii,jj)不一定是整数
        ii = (zi-1)/zmf; jj = (zj-1)/zmf;
        i = floor(ii); j = floor(jj); % 向下取整得到在原图中坐标的整数部分
        u = ii - i; v = jj - j;       % 得到在原图中坐标的小数部分
        i = i + 1; j = j + 1;
        new_img(zi,zj,:) = (1-u)*(1-v)*img_scale(i,j,:) + u*(1-v)*img_scale(i,j+1,:)...
                    + (1-u)*v*img_scale(i+1,j,:) + u*v*img_scale(i+1,j+1,:);
    end
end
new_img = uint8(new_img);

end  

2.3 用于显示的代码

function img_show(original,new_img) [height,width,channel] = size(original);
figure;imshow(original);
axis on
title(['原图像(大小: ',num2str(height),'*',num2str(width),'*',num2str(channel),')']);
[new_height,new_width,~] =size(new_img); 
figure;imshow(new_img);
axis on
title(['缩放后的图像(大小: ',num2str(new_height),'*',num2str(new_width),'*',num2str(channel)',')']); end
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/132017.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • HTTP协议中GET、POST和HEAD的介绍(请求方式总结)

    HTTP协议中GET、POST和HEAD的介绍(请求方式总结)

  • java教程 电子书_java教程合集(25本)「建议收藏」

    java教程合集25本,pc6帮您一一整理的,这样的入门级java教程应该不会给你带来太大的困惑,起码我没有。相关软件软件大小版本说明下载地址java教程合集(25本),pc6帮您一一整理的,这样的入门级java教程应该不会给你带来太大的困惑,起码我没有。由一个简单的程序谈起――之五(精华).pdf由一个简单的程序谈起――之三(精华).pdf由一个简单的程序谈起――之六(精华).pdf由一个简单的…

  • IT界名人_it行业精英人物

    IT界名人_it行业精英人物互联网  张朝阳搜狐公司CEO  丁磊网易创始人/首席架构设计师  茅道临新浪CEO  陈天桥盛大CEO  马化腾腾讯CEO  王峻涛珠峰伟业(6688)总裁  鲍岳桥联众电脑总裁  宫玉国IT168网站CEO  黄明生263网络集团总裁兼COO  邵亦波易趣网CEO  王树彤原卓越网CEO  李彦宏百度

  • 数据挖掘十大经典算法(9) 朴素贝叶斯分类器 Naive Bayes

    数据挖掘十大经典算法(9) 朴素贝叶斯分类器 Naive Bayes

  • translate函数用法_fork函数在循环体中

    translate函数用法_fork函数在循环体中TranslateMessage函数函数功能描述:将虚拟键消息转换为字符消息。字符消息被送到调用线程的消息队列中,在下一次线程调用函数GetMessage或PeekMessage时被读出。.函数原型:   BOOLTranslateMessage( CONSTMSG*lpMsg);.参数:   lpMsg       指向一个含有用GetMessage或PeekMe

  • ziw文件用什么打开_html文件怎么打开

    ziw文件用什么打开_html文件怎么打开方法1:.ziw格式文件是为知笔记的文本文档,可以用为知笔记打开,直接去为知笔记官方网站下载就可以了,然后该软件的试用期是100天,不过它是经过邮箱注册的,并且没有验证邮箱这一步,所以你在100天之后可以换一个邮箱就可以了,比如之前用QQ邮箱,下次用163邮箱,另外它不会验证邮箱,所以你可以随意伪造一个邮箱登录方法2:直接把文件名后缀名改成.zip,然后解压,解压成功之后生成的是html网页,直接点击index.html就可以在浏览器中打开文件了,里面的图片不要删除,它们是index.html网页要用

    2022年10月12日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号