图像处理-几何变换

问题:请分别用最近邻法和双线性插值法将附件中80*60的小图放大至800*600,并分别截取边缘区域与原图相比较。

最近邻法是一种最简单的图像缩放方法,它对于每个新像素,都寻找最接近的原始像素,并直接将其值赋给新像素。

对于每个输出像素,都计算与该像素最接近的输入像素位置,并将该像素的值作为输出像素的值。这种方法实现起来简单,计算速度非常快,但缩放后图像的质量可能会受到影响,尤其是在进行放大时会产生锯齿状效果,所以不适用于对图像质量要求较高的应用。

双线性插值法是一种更高级的缩放方法。这种方法首先对输入图像中每个像素周围的四个像素进行加权平均,以确定新像素的值。

对于每个输出像素,其值由位于其四个相邻像素的值插值计算而来。插值公式使用每个相邻像素的距离和这些像素的灰度值进行计算,在距离越远的像素处分配更小的权重,最终得到一个加权平均值,将其作为该像素的值。

这种方法比最近邻法更准确,并能在处理后的图像中产生更平滑的过渡效果,但计算成本较高。

在图像处理中,最近邻法和双线性插值法通常用于缩放、旋转和图像变换等操作。具体使用哪种方法可以根据应用需求和处理速度要求来选择。

import numpy as np
import cv2


def nearest(img, h, w):
   height, width, channels = img.shape
   emptyImage = np.zeros((h, w, channels), np.uint8)
   sh = h / height
   sw = w / width
   for i in range(h):
       for j in range(w):
           x = int(i / sh)
           y = int(j / sw)
           emptyImage[i, j] = img[x, y]
   return emptyImage


def bilinear(img, out_dim):
   src_h, src_w, channel = img.shape
   dst_h, dst_w = out_dim[1], out_dim[0]
   print("src_h, src_w = ", src_h, src_w)
   print("dst_h, dst_w = ", dst_h, dst_w)
   if src_h == dst_h and src_w == dst_w:
       return img.copy()
   dst_img = np.zeros((dst_h, dst_w, 3), dtype=np.uint8)
   scale_x, scale_y = float(src_w) / dst_w, float(src_h) / dst_h
   for i in range(3):
       for dst_y in range(dst_h):
           for dst_x in range(dst_w):
               # find the origin x and y coordinates of dst image x and y
               # use geometric center symmetry
               # if use direct way, src_x = dst_x * scale_x
               src_x = (dst_x + 0.5) * scale_x - 0.5
               src_y = (dst_y + 0.5) * scale_y - 0.5

               # find the coordinates of the points which will be used to compute the interpolation
               src_x0 = int(np.floor(src_x))
               src_x1 = min(src_x0 + 1, src_w - 1)
               src_y0 = int(np.floor(src_y))
               src_y1 = min(src_y0 + 1, src_h - 1)

               # calculate the interpolation
               temp0 = (src_x1 - src_x) * img[src_y0, src_x0, i] + (src_x - src_x0) * img[src_y0, src_x1, i]
               temp1 = (src_x1 - src_x) * img[src_y1, src_x0, i] + (src_x - src_x0) * img[src_y1, src_x1, i]
               dst_img[dst_y, dst_x, i] = int((src_y1 - src_y) * temp0 + (src_y - src_y0) * temp1)

   return dst_img


if __name__ == '__main__':
   img = cv2.imread('Snoopy-small.jpg')
   img1 = bilinear(img, (800, 600))
   img2 = nearest(img, 600, 800)
   cv2.imshow('bilinear interp', img1)
   cv2.imshow('nearest', img2)
   cv2.imwrite('bilinear.png', img1)
   cv2.imwrite('nearest.png', img2)
   cv2.waitKey(0)
   cv2.destroyAllWindows()

结果图:

最近邻:

 双线性插值法:

通过两张不同方法处理后的图片与原图比较可以显著看出,两者虽然都成功放大了图像,但是最近邻法会产生锯齿状效果,图像质量较低,优点是计算成本低;双线性插值法则能在处理后的图像中产生更平滑的过渡效果,但计算成本较高,耗时较长。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

F0reverBound

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值