用双线性内插法实现位深度为8的灰度图像的缩放。
输入原图像以及缩放后图像的像素要求(宽度*高度),处理后输出新图像。
我是用matlab来实现scale(input_img,scale_size)函数的,输入图像路径以及要求实现的宽度scale_w和高度值scale_h即可。通过matlab把原图像转化为img矩阵,这样矩阵img(a, b)元素的值就是原图像高度为a,宽度为b处的像素值。
设处理前后图像的宽度和高度分别为w、h,scale_w、scale_h。
如上图所示,row对应的是高度,设为x轴;col对应的是宽度,设为y轴;value对应的是灰度值,设为z轴。
通过缩放比例,可以求得新图像B在(i,j)处对应原图像的点为(x,y)(其中x= i*h/scale_h,y= j*w/scale_w)。
但是这两个值可能为浮点数,而像素中的位置是整数,所以这个点在原图像中对应的可能是“虚”点。所以,我们需
要根据找该“虚”点周围的四个点来进行双线性插值得到新图像的灰度值。我们应该取的是(x,y)邻近的四个像素
(x0,y0) 、(x0,y1) 、(x1,y0) 、(x1,y1),它们对应的灰度值为f(x0,y0) 、f(x0,y1)、 f(x1,y0)、 f(x1,y1)。
先对x方向进行插值,再对y方向进行插值,计算如下:
反过来,先对y方向:
显然,邻近像素的x1-x0 = y1-y0 = 1
整理式子得到:
这里u、v分别是x、y的小数部分,即u = x - x0; v = y - y0
要注意的是:上述公式img(a,b)中的a和b不能小于1,所以当x和y小于1时需要将其重新赋值为1。
function output_img = scale(input_img, scale_size)
%Input - input_img is a two-dimensional matrices storing image
% - scale_size is a tuple of [width, height] defining the spatial resolution of output
%Output - output_img is the same as input_img
img = imread(input_img); %读取输入图片的数据
[h,w] = size(img); %获取行和列,即原图的高度和宽度
scale_w = scale_size(1); %根据输入获得缩放后的新宽度
scale_h = scale_size(2); %根据输入获得缩放后的新高度
output_img = zeros(scale_h, scale_w); %初始化
for i = 1 : scale_h %缩放后的图像的(i,j)位置对应原图的(x,y)
for j = 1 : scale_w
x = i * h / scale_h;
y = j * w / scale_w;
u = x - floor(x);
v = y - floor(y); %取小数部分
if x < 1 %边界处理
x = 1;
end
if y < 1
y = 1;
end
%用原图的四个真实像素点来双线性插值获得“虚”像素的像素值
output_img(i, j) = img(floor(x), floor(y)) * (1-u) * (1-v) + ...
img(floor(x), ceil(y)) * (1-u) * v + ...
img(ceil(x), floor(y)) * u * (1-v) + ...
img(ceil(x), ceil(y)) * u * v;
end
end
imwrite(uint8(output_img), '../output_img.png'); %保存处理后的图像
imshow(input_img); %显示原图
figure,imshow(uint8(output_img)) %显示处理后的图像
运行时若图片在代码上一级目录,则输入scale('../a.png', [450,300]);
原图为384*256:
缩小成192*128:
放大成450*300:
缩放成500*200:
//
转载:https://blog.csdn.net/Stella_Chan/article/details/78025020?locationNum=5&fps=1