We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
数字图像处理的第一次作业就是用图像的插值算法实现图片的放缩,在网上查了一些资料后,总结如下:
首先我们定义几个变量:
- 原图矩阵: Source - 目标图矩阵: Destination - 宽度缩放比: ratioW - 高度缩放比: ratioH
先得到原图的宽和高
Source = imread('src.png'); [srcM, srcN] = size(Source);
接着根据下面的公式计算出目标图的宽和高:
ratioW = dstM / srcM; ratioH = dstN / srcN;
新建目标图,根据目标图的大小建立一个空的Matrix,记作M
Destination = zeros(dstM, dstN); M = Destination;
然后要对M中的每个点赋值,即所谓的插值运算,这个值从哪里来呢?当然是原图。
现在 设M矩阵的坐标点为(dx, dy),则它对应的原图坐标(sx, sy)满足:
dx / sx = dstM / srcM; dy / sy = dstN / srcN;
这样我们就能求出
(sx, sy) = (dx * srcM / dstM, dy * srcN / dstN);
到此,我们就把目标图中的坐标点映射到原图中去了
但是这个坐标点不一定是整数,假如(2, 0) 映射的结果为 (0.75, 0),这显然是不科学的,怎么办呢? 第一种方法,四舍五入 得到 (1, 0),然后把原图中(1, 0)点的像素值赋给目标图的(2, 0)位置即可:
fd(2, 0) = fs(1, 0);
这种放大图像的方法就叫做 最临近插值算法,这是一种最基本、最简单的图像缩放算法,效果也是最不好的,放大后的图像有很严重的马赛克,缩小后的图像有很严重的失真。
另一种算法就是双线性插值算法,它的失真情况会好很多。
算法思路是: 对于一个目的像素,映射后得到的浮点坐标为(i+u,j+v), (其中i、j均为浮点坐标的整数部分,u、v为浮点坐标的小数部分,是取值[0,1)区间的浮点数),则这个像素得值 f(dx,dy) 可由原图像中坐标为 (i,j)、(i+1,j)、(i,j+1)、(i+1,j+1)所对应的周围四个像素的值决定,即:
f(dx, dy) = (1-u)(1-v)f(i,j) + (1-u)vf(i,j+1) + u(1-v)f(i+1,j) + uvf(i+1,j+1)
这里我们就可以由原图中的 4 个像素点推出了目标图中1个像素点,最后遍历目标图,我们就能实现图片的放缩了。
双线性插值算法代码如下所示:
% Bilinear Function function [ output_img ] = scale( input_img, Size ) % Using bilinear algorithm to change the SIZE of input_img. dstM = Size(1); dstN = Size(2); [srcM srcN]=size(input_img); output_img = zeros(dstM, dstN); for i = 1:dstM - 1 for j = 1:dstN - 1 src_i = i * (srcM / dstM); src_j = j * (srcN / dstN); int_i = fix(src_i); int_j = fix(src_j); u = src_i - int_i; v = src_j - int_j; if int_i == 0 int_i = int_i + 1; end if int_j == 0 int_j = int_j + 1; end output_img(i,j)=(1-u)*(1-v)*input_img(int_i,int_j)+(1-u)*v*input_img(int_i,int_j+1) +u*(1-v)*input_img(int_i+1,int_j)+u*v*input_img(int_i+1,int_j+1); end end output_img = uint8(output_img); figure,imshow(input_img) axis on figure,imshow(output_img) axis on end % call function scale() close all clear all clc input_img = imread('test.png') size = [100, 100] output_img = scale(input_img, size) imtool(output_img)
The text was updated successfully, but these errors were encountered:
No branches or pull requests
数字图像处理的第一次作业就是用图像的插值算法实现图片的放缩,在网上查了一些资料后,总结如下:
首先我们定义几个变量:
先得到原图的宽和高
接着根据下面的公式计算出目标图的宽和高:
新建目标图,根据目标图的大小建立一个空的Matrix,记作M
然后要对M中的每个点赋值,即所谓的插值运算,这个值从哪里来呢?当然是原图。
现在 设M矩阵的坐标点为(dx, dy),则它对应的原图坐标(sx, sy)满足:
这样我们就能求出
到此,我们就把目标图中的坐标点映射到原图中去了
但是这个坐标点不一定是整数,假如(2, 0) 映射的结果为 (0.75, 0),这显然是不科学的,怎么办呢?
第一种方法,四舍五入 得到 (1, 0),然后把原图中(1, 0)点的像素值赋给目标图的(2, 0)位置即可:
这种放大图像的方法就叫做 最临近插值算法,这是一种最基本、最简单的图像缩放算法,效果也是最不好的,放大后的图像有很严重的马赛克,缩小后的图像有很严重的失真。
另一种算法就是双线性插值算法,它的失真情况会好很多。
算法思路是:
对于一个目的像素,映射后得到的浮点坐标为(i+u,j+v),
(其中i、j均为浮点坐标的整数部分,u、v为浮点坐标的小数部分,是取值[0,1)区间的浮点数),则这个像素得值 f(dx,dy) 可由原图像中坐标为 (i,j)、(i+1,j)、(i,j+1)、(i+1,j+1)所对应的周围四个像素的值决定,即:
这里我们就可以由原图中的 4 个像素点推出了目标图中1个像素点,最后遍历目标图,我们就能实现图片的放缩了。
双线性插值算法代码如下所示:
The text was updated successfully, but these errors were encountered: