上一篇所说的图像金字塔处理,包括图像向上取样和向下取样。需要注意,向上取样放大后的图像比原始图像要模糊,而每次向下取样会删除偶数行和列,它会不停地丢失图像的信息。此外,向上采样和向下采样不是互逆的操作,经过两种操作后,是无法恢复原始图像的。

14.1 图像采样处理原理

图像采样(Image Sampling)处理是将一幅连续图像在空间上分割成M×N个网格,每个网格用一个亮度值或灰度值来表示,其示意图如下图所示。

图像采样的间隔越大,所得图像像素数越少,空间分辨率越低,图像质量越差,甚至出现马赛克效应;相反,图像采样的间隔越小,所得图像像素数越多,空间分辨率越高,图像质量越好,但数据量会相应的增大。下图展示了不同采样间隔的“Lena”图,其中图(a)为原始图像,图(b)为128×128的图像采样效果,图(c)为64×64的图像采样效果,图(d)为32×32的图像采样效果,图(e)为16×16的图像采样效果,图(f)为8×8的图像采样效果。

14.2 示例:图像采样实现

下面讲述python图像采样处理相关代码操作。其核心流程是建立一张临时图片,设置需要采样的区域大小(如16×16),接着循环遍历原始图像中所有像素点,采样区域内的像素点赋值相同(如左上角像素点的灰度值),最终实现图像采样处理。

import cv2
import numpy as np
import matplotlib.pyplot as plt
 
def sampling(image,sample_size):
    #获取图像高度和宽度
    height = image.shape[0]
    width = image.shape[1]
    #采样转换成sample_size*sample_size区域
    numHeight = int(height/sample_size)
    numWidth = int(width/sample_size)
    #创建一幅图像(值为0)
    new_img = np.zeros((height, width, 3), np.uint8)
    #图像循环采样16*16区域
    for i in range(sample_size):
        #获取Y坐标
        y = i*numHeight
        for j in range(sample_size):
            #获取X坐标
            x = j*numWidth
            #获取填充颜色 左上角像素点
            b = img[y, x][0]
            g = img[y, x][1]
            r = img[y, x][2]
        
            #循环设置小区域采样
            for n in range(numHeight):
                for m in range(numWidth):
                    new_img[y+n, x+m][0] = np.uint8(b)
                    new_img[y+n, x+m][1] = np.uint8(g)
                    new_img[y+n, x+m][2] = np.uint8(r)
    return new_img

#读取原始图像
img = cv2.imread('C:\\Users\\liyou\\Downloads\\lena.jpg')
sampling4 = sampling(img,4)
sampling8 = sampling(img,8)
sampling16 = sampling(img,16)
sampling32 = sampling(img,32)
sampling64 = sampling(img,64)
sampling128 = sampling(img,128)
sampling256 = sampling(img,256)

#比较不同采样大小的画质
names = ['Original','sampling256','sampling128','sampling64',
         'sampling32','sampling16','sampling8','sampling4']
images =  [img,sampling256,sampling128,sampling64,
           sampling32,sampling16,sampling8,sampling4]

plt.figure(figsize=(25.6,9.6))
for i in range(2):
    for j in range(4):
        plt.subplot(2,4,i*4+j+1),plt.imshow(images[i*4+j])
        plt.title(names[i*4+j],fontsize=30), plt.xticks([]), plt.yticks([])
        num=i*4+j
        if num >= len(names)-1:
            break

plt.show()

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐