Python图像处理三:图像基本属性的操作

一、图像的空间分辨率

图像的空间分辨率对应于图像的像素个数,空间分辨率低,图像的像素数少,图像质量差,严重时出现马赛克效应;空间分辨率高,图像的像素数多,图像质量好,但数据量较大。

例1:读入一幅数字图像,通过设置不同的采样比率,改变图像的空间分辨率,显示原图像及处理后的图像,代码示例如下:

from skimage import data
from matplotlib import pyplot as plt
import numpy as np             #导入所需类包

image=data.coffee()            #载入测试图像
plt.imshow(image)
plt.show()
print(image.shape)            #显示图像原始大小
print(type(image))            #显示图像类型

ratio=20                      #设置采样比率
image1=np.zeros((int(image.shape[0]/ratio),int(image.shape[1]/ratio),image.shape[2]),dtype='int32')    #设置采样后图像大小

for i in range(image1.shape[0]):
    for j in range(image1.shape[1]):
        for k in range(image1.shape[2]):     #对图像进行遍历
            delta=image[i*ratio:(i+1)*ratio,j*ratio:(j+1)*ratio,k]   #获取需要采样图像块
            image1[i,j,k]=np.mean(delta)   #计算均值,并存入结果图像
            
plt.imshow(image1)#打印采样后图像图像
plt.show()
print(image1.shape)  #显示图像原始大小
print(type(image1))  #显示图像类型

输出
啊啊啊

上述代码中采用了求平均值的方法计算像素值,也可以采用求最大值或最小值的方法求像素值,相应的代码修改为:

image1[i,j,k]=np.max(delta)          #计算最大值
image1[i,j,k]=np.min(delta)          #计算最小值

此外,可以修改代码中的采样比率 ratio 的值,体验采样频率对图像空间分辨率的影响。

二、图像的幅度分辨率

图像的幅度分辨率对应于图像像素值的量化级数,量化等级越多,图像的幅度分辨率越高,图像质量好,但数据量较大;量化等级越少,幅度分辨率越低,图像质量差,严重时可能出现假轮廓。

例2:读入一幅数字图像,通过设置不同的量化比率,改变图像的幅度分辨率,显示原图像及处理后的图像,代码示例如下:

from skimage import data
from matplotlib import pyplot as plt
image=data.coffee()  #载入测试图像
plt.imshow(image)
plt.show()

ratio=128     #设置量化比率
image1=image
for i in range(image.shape[0]):
    for j in range(image.shape[1]):
        for k in range(image.shape[2]):
            image1[i][j][k]=int(image[i][j][k]/ratio)*ratio
            #对图像每个像素进行量化
plt.imshow(image1)#打印采样后图像图像
plt.show()

输出
三次方

三、图像的对比度与亮度调整

skimage的exposure模块中包含指数变换的函数 adjust_gamma和对数变换的函数adjust_log,可以对图像进行指数变换和对数变换。

1、指数变换(gamma变换)

对原图像的像素,进行幂运算,得到新的像素值。
公式: I=I^g,其中的g就是gamma值。
如果gamma>1, 新图像比原图像暗;如果gamma<1,新图像比原图像亮。
函数格式为:skimage.exposure.adjust_gamma(image, gamma=1)
gamma参数默认为1,原像不发生变化 。

例3:对图像做指数变换,分别取gamma=0.2,0.67,2,代码示例如下:

from skimage import data, exposure, img_as_float
import matplotlib.pyplot as plt
image = img_as_float(data.moon())
#读入图像

#分别计算gamma=0.2,0.67,2时的图像
image_1=exposure.adjust_gamma(image,0.2)
image_2=exposure.adjust_gamma(image,0.67)
image_3=exposure.adjust_gamma(image,2)
#分别展示原图及结果图像
plt.figure('gamma',figsize=(8,8))
plt.subplot(2,2,1)
plt.title('gamma=1')
plt.imshow(image,plt.cm.gray)
plt.subplot(2,2,2)
plt.title('gamma=0.2')
plt.imshow(image_1,plt.cm.gray)
plt.subplot(2,2,3)
plt.title('gamma=0.67')
plt.imshow(image_2,plt.cm.gray)
plt.subplot(2,2,4)
plt.title('gamma=2')
plt.imshow(image_3,plt.cm.gray)
plt.show()

输出
AV

2、对数变换

公式:I=log(I)
例4:对图像做对数变换,代码示例如下:

from skimage import data, exposure, img_as_float
import matplotlib.pyplot as plt
image = img_as_float(data.moon())
gam1= exposure.adjust_log(image)   #对数变换
plt.figure('adjust_log',figsize=(8,8))

plt.subplot(121)
plt.title('origin image')
plt.imshow(image,plt.cm.gray)
plt.axis('off')

plt.subplot(122)
plt.title('log')
plt.imshow(gam1,plt.cm.gray)
plt.axis('off')

plt.show()

输出
画家

3、强度调整

强度调整函数:
skimage.exposure.rescale_intensity(image, in_range=‘image’, out_range=‘dtype’)
in_range 表示输入图像的强度范围,默认为’image’, 表示用图像的最大/最小像素值作为范围;
out_range 表示输出图像的强度范围,默认为’dype’, 表示用图像的类型的最大/最小值作为范围;

默认情况下,输入图像的[min,max]范围被拉伸到[dtype.min, dtype.max],如果dtype=uint8, 那么dtype.min=0, dtype.max=255
例:

import numpy as np
from skimage import exposure
image = np.array([51, 102, 153], dtype=np.uint8)
mat=exposure.rescale_intensity(image)
print(mat)

输出为 [ 0 127 255]
即像素最小值由51变为0,最大值由153变为255,整体进行了拉伸,但是数据类型没有变,还是uint8

前面我们说过,可以通过img_as_float()函数将unit8类型转换为float型,实际上还有更简单的方法,就是乘以1.0

import numpy as np
image = np.array([51, 102, 153], dtype=np.uint8)
print(image*1.0)

即由[51,102,153]变成了[ 51. 102. 153.]

而float类型的范围是[0,1],因此对float进行rescale_intensity 调整后,范围变为[0,1],而不是[0,255]

import numpy as np
from skimage import exposure
image = np.array([51, 102, 153], dtype=np.uint8)
tmp=image*1.0
mat=exposure.rescale_intensity(tmp)
print(mat)

结果为[ 0. 0.5 1. ]

如果原始像素值不想被拉伸,只是等比例缩小,就使用in_range参数,如:

import numpy as np
from skimage import exposure
image = np.array([51, 102, 153], dtype=np.uint8)
tmp=image*1.0
mat=exposure.rescale_intensity(tmp,in_range=(0,255))
print(mat)

输出为:[ 0.2 0.4 0.6],即原像素值除以255

如果参数in_range的[min,max]范围要比原始像素值的范围[min,max] 大或者小,那就进行裁剪,如:

mat=exposure.rescale_intensity(tmp,in_range=(0,102))
print(mat)

输出[ 0.5 1. 1. ],即原像素值除以102,超出1的变为1

如果一个数组里面有负数,现在想调整到正数,就使用out_range参数。如:

import numpy as np
from skimage import exposure
image = np.array([-10, 0, 10], dtype=np.int8)
mat=exposure.rescale_intensity(image, out_range=(0, 127))
print(mat)

输出[ 0 63 127]

四、图像的颜色通道操作

例5:读入彩色图像,将图像的红色分量与蓝色分量互换,代码示例如下:

from skimage import data,io
from matplotlib import pyplot as plt
#读入图像
#image=io.imread('C2_256.bmp')
image=data.coffee()
# 显示原图
plt.imshow(image)
plt.title('Original image')
plt.axis('off')
plt.show()

image1=image
#分别取出红、绿、蓝三个颜色通道
image_r=image[:,:,0]
image_g=image[:,:,1]
image_b=image[:,:,2]
#红色和蓝色互换
temp=image_r
image_r=image_b
image_b=temp
#将互换后的通道颜色重新赋值给图像
image1[:,:,0]=image_r
image1[:,:,2]=image_b
#图像显示
plt.imshow(image1)
plt.title('New image')
plt.axis('off')
plt.show()

输出
那么久

猜你喜欢

转载自blog.csdn.net/weixin_52051554/article/details/127609604