数字图像处理学习(1)——图像插值Python代码实现

最近在学习数字图像处理,打算长期记录下来。

1. 图像插值 (Image Interpolation)

当我们需要放大或者缩小一张数字图像的时候,我们所进行的操作称之为Image Interpolation

例如:把一张 275*185 的图像转化为原图的一半大小,如下:

在这里插入图片描述                                                                            在这里插入图片描述

实际上就是根据原来的图片中,所有像素点,按照某种关系在新的图片当中进行 pixel填充的一种操作,这种操作最常见的有几种方法:

  • 最近邻插值法(Nearest Neighbor Interpolation)
  • 双线性插值法(bilinear interpolation)
  • 双三次插值法(bicubic interpolation)

在介绍方法之前,我先总结下个人对图像插值整体思路描述,可以分为4步曲:

  1. 读取图片
  2. 选定插值算法
  3. pixel 填充
  4. 新图片保存

2. 最近邻插值法

2.1 最近邻插值法

这是最简单、易懂的一种方法。

设原图片的大小为 ( h e i g h t , w i d t h ) (height, width) (height,width), 图片中某一个像素点的位置为 ( s r c x , s r c y ) (srcx, srcy) (srcx,srcy)

目标图片的大小为 ( d e s h e i g h t , d e s w i d t h ) (desheight, deswidth) (desheight,deswidth). 目标图片中某一个像素点的位置为 ( d e s x , d e s y ) (desx, desy) (desx,desy)
在这里插入图片描述

根据等比例关系,易得如下关系:

s r c x = d e s x ⋅ ( w i d t h / d e s w i d t h ) srcx=desx·(width/deswidth) srcx=desx(width/deswidth)
s r c y = d e s y ⋅ ( h e i g h t / d e s h e i g h t ) srcy=desy·(height/desheight) srcy=desy(height/desheight)

其中会遇到小数的值,那么则一般可以设置四舍五入的方式取整,选择位置。

2.2 最近邻插值法(Python 代码实现——图像缩小)

#!/usr/bin/env python
# encoding: utf-8
"""
@author: H
@software: Pycharm
@file: ImageInterpolation.py
@time: 2020/10/16 8:28
"""


import os
import numpy as np
from PIL import Image

file_path = r'D:\postgraduate\first_year\数字图像处理\作业\homework1\practice1\image\jerry.jpg'
img = Image.open(file_path)  # 读取图片,格式为Image

# 把Image格式的图片转化为numpy格式进性图像处理
img = np.array(img, dtype=np.uint8)

height, width, mode = img.shape[0], img.shape[1], img.shape[2]  # 取出高、宽、通道数
print(height, width, mode)  # (275 183 3)

# 缩放的目标大小,这里以缩放为原图的1/2为例
desWidth = int(width * 0.5)
desHeight = int(height * 0.5)
desImage = np.zeros((desHeight, desWidth, mode), np.uint8)  # 定义一个目标图片代表的array,纯黑图片

# 像素填充
# 方法1:最近邻插值法
for des_x in range(0, desHeight):
    for des_y in range(0, desWidth):
        # 判断新像素点在原图中的像素点坐标
        src_x = int(des_x * (height/desHeight))
        src_y = int(des_y * (width/desWidth))

        desImage[des_x, des_y] = img[src_x, src_y]  # 填充
print(desImage.shape)
des_img = Image.fromarray(desImage)
des_img.save('./image/jerry.jpg')  # 图片另存为

2.3 运行结果示例

在这里插入图片描述                                                                           缩小后
       缩放前                                                                                                 缩放后


3. 双线性插值法

3.1 双线性插值法

在介绍双线性插值之前,我们需要知道单线性插值的概念。

已知要求点 ( x , y ) (x,y) (x,y)某一条直线上(某一维度),其他两个点坐标为: ( x 0 , y 0 ) (x_0,y_0) (x0,y0), ( x 1 , y 1 ) (x_1,y_1) (x1,y1)

其中 y y y 是关于 x x x 的某种函数,根据 x x x 计算出 x x x 对应的像素值 y y y
在这里插入图片描述
可以得出:
在这里插入图片描述
这个结果就好比,一条直线上的两个磁铁,对中间的铁块的力的作用的矢量叠加(不考虑方向)。
在这里插入图片描述

  • 式子第一项: ( x , f ( x ) ) (x,f(x)) (x,f(x)) ( x 1 , f ( x 1 ) ) (x_1,f(x_1)) (x1,f(x1))的距离为 ( x 1 − x ) (x_1-x) (x1x);当无限靠近 ( x 1 , f ( x 1 ) ) (x_1,f(x_1)) (x1,f(x1))时, f ( x ) f(x) f(x) 就无限接近 f ( x 1 ) f(x_1) f(x1),最终等于 f ( x 1 ) f(x_1) f(x1)
  • 式子第二项: ( x , f ( x ) ) (x,f(x)) (x,f(x)) ( x 0 , f ( x 0 ) ) (x_0,f(x_0)) (x0,f(x0))的距离为 ( x − x 0 ) (x-x_0) (xx0);当无限靠近 ( x 0 , f ( x 0 ) ) (x_0,f(x_0)) (x0,f(x0))时, f ( x ) f(x) f(x) 就无限接近 f ( x 0 ) f(x_0) f(x0),最终等于 f ( x 0 ) f(x_0) f(x0)

总结为:

f ( x ) = x 1 − x x 1 − x 0 ⋅ f ( x 0 ) + x − x 0 x 1 − x 0 ⋅ f ( x 1 ) f(x)=\frac{x_1-x}{x_1-x_0}·f(x_0)+\frac{x-x_0}{x_1-x_0}·f(x_1) f(x)=x1x0x1xf(x0)+x1x0xx0f(x1)


双线性插值法实际上就是进行了两个维度的单线性插值。可分为:

  • 两次水平方向的单线性插值( x x x 轴)
  • 根据 x x x 的结果进行一次垂直方向的单线性插值( y y y 轴)

当然 x x x y y y 可以互换。

这是找的一张比较经典的图:
在这里插入图片描述

结合单线性插值的结论,可以进行如下运算:
① 两次 x x x 轴的线性插值

f ( R 1 ) = x 2 − x x 2 − x 1 ⋅ f ( Q 11 ) + x − x 1 x 2 − x 1 ⋅ f ( Q 21 ) f(R_1)=\frac{x_2-x}{x_2-x_1}·f(Q_{11})+\frac{x-x_1}{x_2-x_1}·f(Q_{21}) f(R1)=x2x1x2xf(Q11)+x2x1xx1f(Q21)

f ( R 2 ) = x 2 − x x 2 − x 1 ⋅ f ( Q 12 ) + x − x 1 x 2 − x 1 ⋅ f ( Q 22 ) f(R_2)=\frac{x_2-x}{x_2-x_1}·f(Q_{12})+\frac{x-x_1}{x_2-x_1}·f(Q_{22}) f(R2)=x2x1x2xf(Q12)+x2x1xx1f(Q22)

② 进行一次 y y y 轴的线性插值

f ( P ) = y 2 − y y 2 − y 1 ⋅ f ( R 1 ) + y − y 1 y 2 − y 1 ⋅ f ( R 2 ) f(P)=\frac{y_2-y}{y_2-y_1}·f(R_1)+\frac{y-y_1}{y_2-y_1}·f(R_{2}) f(P)=y2y1y2yf(R1)+y2y1yy1f(R2)

联合① ②两式(害,偷个懒直接上才草稿),可得:
在这里插入图片描述

3.2 双线性插值法(Python代码实现——图片放大)

#!/usr/bin/env python
# encoding: utf-8
"""
@author: H
@software: Pycharm
@file: ImageInterpolation1.py
@time: 2020/10/17 20:31
"""

import os
import numpy as np
from PIL import Image

"""
    图像缩放常见三种方法的实现:
        - 最近邻插值法
        - 双线性插值法
        - 双立方插值法
"""


def Interpolation_NNI(filepath):
    """
        最近邻插值法(nearest neighbor interpolation)
    :param filepath:
    :return:
    """
    img = Image.open(file_path)  # 读取图片,格式为Image
    # img.show()  # 显示图片

    # 把Image格式的图片转化为numpy格式进性图像处理
    img = np.array(img, dtype=np.uint8)

    height, width, mode = img.shape[0], img.shape[1], img.shape[2]  # 取出高、宽、通道数
    print(height, width, mode)  # (275 183 3)

    # 缩放的目标大小,这里以缩放为原图的1/2为例
    desWidth = int(width * 0.5)
    desHeight = int(height * 0.5)
    desImage = np.zeros((desHeight, desWidth, mode), np.uint8)  # 定义一个目标图片代表的array,纯黑图片

    # 像素填充
    # 方法1:最近邻插值法
    for des_x in range(0, desHeight):
        for des_y in range(0, desWidth):
            # 判断新像素点在原图中的像素点坐标
            src_x = int(des_x * (height / desHeight))
            src_y = int(des_y * (width / desWidth))
            desImage[des_x, des_y] = img[src_x, src_y]  # 填充
    print(desImage.shape)
    des_img = Image.fromarray(desImage)
    des_img.save('./image/jerry.jpg')


def Interpolation_Bilinear(filepath, desHeight, desWidth):
    # 双线性插值法
    img = Image.open(filepath)  # 读取图片
    img = np.array(img, np.uint8)  # 转化为numpy数组
    desImageNumpy = np.zeros(img.shape, np.uint8)  # 生成一个大小相同的全0的numpy数组
    height, width, mode = img.shape[0], img.shape[1], img.shape[2]  # 高、宽、channel数

    # 找出目标位置在源图中的位置
    scale_x = float(width)/desWidth  # x轴缩放比例
    scale_y = float(height)/desHeight  # y轴缩放比例
    des_image = np.zeros((desHeight, desWidth, mode), np.uint8)
    for n in range(mode):
        for des_y in range(desHeight):
            for des_x in range(desWidth):
                # 确定四个近邻点坐标
                src_x = (des_x + 0.5) * scale_x - 0.5  #
                src_y = (des_y + 0.5) * scale_y - 0.5

                src_x_1 = int(np.floor(src_x))  #
                src_y_1 = int(np.floor(src_y))
                src_x_2 = min(src_x_1+1, width-1)  # 防止坐标点寻找溢出
                src_y_2 = min(src_y_1+1, height-1)
                # 两次x轴线性插值
                value_1 = (src_x_2 - src_x)*img[src_y_1, src_x_1, n]+(src_x - src_x_1)*img[src_y_1, src_x_2, n]
                value_2 = (src_x_2 - src_x)*img[src_y_2, src_x_1, n]+(src_x - src_x_1)*img[src_y_2, src_x_2, n]
                # y轴线性插值
                des_image[des_y, des_x, n] = (src_y_2 - src_y)*value_1 + (src_y - src_y_1)*value_2
    print(des_image.shape)
    des_img = Image.fromarray(des_image)
    des_img.save('./image/new_bilinear.jpg')


if __name__ == '__main__':
    file_path = r'D:\postgraduate\first_year\数字图像处理\作业\homework1\practice1\image\kobe1.jpg'
    Interpolation_Bilinear(file_path, int(183*2), int(275*2))  # 双线性插值法


3.3 结果展示

在这里插入图片描述                                    在这里插入图片描述


像这张放大的图片的男人一样,加油加油!

  • 27
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
CT image compression (a) Implement the simplified DCT compression process above for n = 2, 4, and 8 and apply it to the attached image. Show the reconstructed images for these three different cases. [3 images] Compute the PSNR values of the three reconstructed images and discuss what the PSNR value means here. (b) Use the same process in (a) with image transformed to YIQ color model and show the reconstructed image in RGB space. [3 images] Compute the PSNR values of the three reconstructed images and discuss what the PSNR value means here. Dithering 2. Dithering (30%) Convert the image cat2_gray.png to binary (black and white) image with different methods of dithering, show the results, and make some comparison with the results. (a) Apply noise (random) dithering on the provided image and show the result. [1 image] (b) Apply average dithering on the provided image and show the result. [1 image] (c) Apply error diffusion dithering (Floyd-Steinberg algorithm) on the provided image and show the result. [1 image] Image Interpolation Implement the image interpolation function to upsample an image to four times the original width and height. Implement the following two different interpolation methods and show the 4× upsampled images. (a) Apply nearest-neighbor interpolation on the low resolution image, cat3_LR.png, and compute the PSNR with the original high resolution image, cat3_HR.png. [1 image] (b) Apply bilinear interpolation on the low resolution image and compute the PSNR with the high resolution image. [1 image] (c) Apply bicubic interpolation on the low resolution image and compute the PSNR with the high resolution image. [1 image]
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值