图像中的像素访问
前面的一些例子中,我们都是利用Image.open()来打开一幅图像,然后直接对这个PIL对象进行操作。如果只是简单的操作还可以,但是如果操作稍微复杂一些,就比较吃力了。因此,通常我们加载完图片后,都是把图片转换成矩阵来进行更加复杂的操作。
一 打开图像并转化为矩阵,并显示:
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
img=np.array(Image.open('D:\\杨幂.jpg')) #打开图像并转化为数字矩阵
plt.figure("杨幂")
plt.imshow(img)
plt.axis('off')
plt.show()
结果如下图所示:
我们可以查看一下图片矩阵的一些信息,具体操作如下:
print (img.shape)
print (img.dtype )
print (img.size)
print (type(img))
结果如下所示:
(2745, 2048, 3)
uint8
16865280
<class 'numpy.ndarray'>
如果是RGB图片,那么转换为array之后,就变成了一个rows*cols*channels的三维矩阵,因此,我们可以使用img[i,j,k]来访问像素值。
二 打开图片,并随机添加一些椒盐噪声
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
img=np.array(Image.open('D:\\杨幂.jpg'))
#随机生成5000个椒盐
rows,cols,dims=img.shape
for i in range(5000):
x=np.random.randint(0,rows)
y=np.random.randint(0,cols)
img[x,y,:]=255
plt.figure("杨幂")
plt.imshow(img)
plt.axis('off')
plt.show()
结果如下图所示:
这里提到了椒盐噪声,为了更好的理解我想从图像噪声说起,并介绍几种常见的图像噪声:
(1)什么是图像噪声?
噪声在图像上常表现为一引起较强视觉效果的孤立像素点或像素块。一般,噪声信号与要研究的对象不相关,它以无用的信息形式出现,扰乱图像的可观测信息。通俗的说就是噪声让图像不清楚。
(2)噪声来源
- 图像获取过程中
两种常用类型的图像传感器CCD和CMOS采集图像过程中,由于受传感器材料属性、工作环境、电子元器件和电路结构等影响,会引入各种噪声,如电阻引起的热噪声、场效应管的沟道热噪声、光子噪声、暗电流噪声、光响应非均匀性噪声。
- 图像信号传输过程中
由于传输介质和记录设备等的不完善,数字图像在其传输记录过程中往往会受到多种噪声的污染。另外,在图像处理的某些环节当输入的对象并不如预想时也会在结果图像中引入噪声。
(3)常见噪声
图像常见噪声基本上有以下四种,高斯噪声,泊松噪声,乘性噪声,椒盐噪声。为了更好的理解,我们以一幅图像为例介绍各种噪声产生的影响,原图如下:
- 高斯噪声
高斯噪声是指它的概率密度函数服从高斯分布(即正态分布)的一类噪声。如果一个噪声,它的幅度分布服从高斯分布,而它的功率谱密度又是均匀分布的,则称它为高斯白噪声。高斯白噪声的二阶矩不相关,一阶矩为常数,是指先后信号在时间上的相关性。
产生原因:
1)图像传感器在拍摄时市场不够明亮、亮度不够均匀;
2)电路各元器件自身噪声和相互影响;
3)图像传感器长期工作,温度过高。
- 泊松噪声
泊松噪声,就是符合泊松分布的噪声模型,泊松分布适合于描述单位时间内随机事件发生的次数的概率分布。如某一服务设施在一定时间内受到的服务请求的次数,电话交换机接到呼叫的次数、汽车站台的候客人数、机器出现的故障数、自然灾害发生的次数、DNA序列的变异数、放射性原子核的衰变数等等
- 乘性噪声
乘性噪声一般由信道不理想引起,它们与信号的关系是相乘,信号在它在,信号不在他也就不在。
- 椒盐噪声
椒盐噪声,椒盐噪声又称脉冲噪声,它随机改变一些像素值,是由图像传感器,传输信道,解码处理等产生的黑白相间的亮暗点噪声。
椒盐噪声往往由图像切割引起。
三 将图像二值化,像素值大于128的变为1,否则变为0
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
img=np.array(Image.open('D:\\杨幂.jpg').convert('L'))
rows,cols=img.shape
for i in range(rows):
for j in range(cols):
if (img[i,j]<=128):
img[i,j]=0
else:
img[i,j]=1
plt.figure("杨幂")
plt.imshow(img,cmap='gray')
plt.axis('off')
plt.show()
结果如下图所示:
如果要对多个像素点进行操作,可以使用数组切片方式访问。切片方式返回的是以指定间隔下标访问 该数组的像素值。下面是有关灰度图像的一些例子:
img[i,:] = im[j,:] # 将第 j 行的数值赋值给第 i 行
img[:,i] = 100 # 将第 i 列的所有数值设为 100
img[:100,:50].sum() # 计算前 100 行、前 50 列所有数值的和
img[50:100,50:100] # 50~100 行,50~100 列(不包括第 100 行和第 100 列)
img[i].mean() # 第 i 行所有数值的平均值
img[:,-1] # 最后一列
img[-2,:] (or im[-2]) # 倒数第二行
参考:
https://www.cnblogs.com/denny402/p/5096491.html
https://blog.csdn.net/weixin_40446557/article/details/81451651