numpy.array 提供了 item()和 itemset() 函数来访问和修改像素值,而且这两个函数都是经过优化处理的,能够更大幅度地提高处理效率,在访问及修改像素点的值时,利用numpy.array 提供的函数比直接使用索引要快得多,同时,这两个函数的可读性也更好
### 1.二值图像及灰度图像
可以将二值图像理解为特殊的灰度图像,所以这里仅以灰度图像为例讨论像素点值的读取
和修改。
函数 item() 能够更加高效地访问图像的像素点,该函数的语法格式为:
item(行,列)
函数 itemset() 可以用来修改像素值,其语法格式为:
itemset(索引值,新值)
为了便于理解,我们首先使用 Nmpy 库生成一个 5×5 大小的随机数组,用来模拟一幅灰度图像,并对其进行用简单的处理。
【例 2.7】使用 Numpy 生成一个二维随机数组,用来模拟一幅灰度图像,并对其像素进行访问、修改
分析:使用 Numpy 中的 random.randint 可以生成一个随机数组,该随机数组对应一幅灰度图像。然后分别使用函数 item()及函数 itemset() 对其像素进行访问、修改
根据题目要求及分析,编写代码如下:
import numpy as np
img=np.random.randint(10,99,size=[5,5],dtype=np.uint8)
print("img=\n",img)
print("读取像素点img.item(3,2)=",img.item(3,2))
img.itemset((3,2),255)
print("修改后img=\n",img)
print("修改后像素点img.item(3,2)=",img.item(3,2))
运行结果如下:
img=
[[83 19 42 12 58]
[87 10 77 76 23]
[22 87 81 56 83]
[70 49 55 27 41]
[90 96 40 43 23]]
读取像素点img.item(3,2)= 55
修改后img=
[[ 83 19 42 12 58]
[ 87 10 77 76 23]
[ 22 87 81 56 83]
[ 70 49 255 27 41]
[ 90 96 40 43 23]]
修改后像素点img.item(3,2)= 255
通过观察输出结果可以发现,语句 img. itemset( (3,2),255)将图像第3 行第2 列位置上的像素值修改为 255了
在例 2.7中,为方便读者仔细观察数组内的每一个值,生成的数组规模(尺寸)较小。
实际使用中,可以利用随机函数生成更大尺寸的随机数组,并使用函数 imshow() 观察随机数组对应的灰度图像
【例 2.8】生成一个灰度图像,让其中的像素值均为随机数
根据题目要求,编写代码如下:
import numpy as np
import cv2
img=np.random.randint(0,256,size=[512,512],dtype=np.uint8)
cv2.imshow("demo",img)
cv2.waitKey()
cv2.destroyAllWindows()
运行结果如下,生成一副256*256大小的灰度图像
【例 2.9】 读取一副灰度图像,并对其像素值进行访问,修改
根据题目要求,编写代码如下:
import cv2
img=cv2.imread("C:\\Users\\Administrator\\Desktop\\opencv\\lena.bmp",0)
#测试读取、修改单个像素值
print("读取像素点img.item(3,2)=",img.item(3,2))
img.itemset((3,2),255)
print("修改后像素点img.item(3,2)=",img.item(3,2))
#测试修改一个区域的像素值
cv2.imshow("before",img)
for i in range(10,100):
for j in range(80,100):
img.itemset((i,j),255)
cv2.imshow("after",img)
cv2.waitKey()
cv2.destroyAllWindows()
运行结果如下:
本程序首先修改了一个像素点的像素值:使用 item() 函数读取了第3 行第2 列位置的像素值:接下来使用 itemset 函数对该像或值进行了修改
接下来使用嵌套征环语句修改了一个区域的像值,将位于“第 10 行到第 90行”和“第80 列到第 99列”的行列交叉区域的像素值设置(修改)为 255,即让该区域星示为白色
2.彩色图像
我们也可以使用函数 item()和函数 itemset()来访问和修改彩色图像的像素值,过程与操作灰度图像相似,不同之处在于需要补充通道信息
函数 item() 访问 RGB 模式图像的像素值时,其语法格式为:
item(行,列,通道)
函数 itemset()修改(设置)RGB 模式图像的像素值时,其语法格式为:
itemset(三元组索引值,新值)
需要注意,针对 RGB 图像的访问,必须同时指定行、列以及行列索素引(通道),例如
img. item(a, b,c)仅仅指定行和列是不可以的
【例 2.10】使用 Numpy 生成一个由随机数构成的三维数组,用来模拟一幅 RGB 色彩空间的彩色图像,并使用函数 item()和 itemset()来访问和修改它
根据题日要求,编写代码如下:
import numpy as np
img=np.random.randint(10,99,size=[2,4,3],dtype=np.uint8)
print("img=\n",img)
print("读取像素点img[1,2,0]=",img.item(1,2,0))
print("读取像素点img[0,2,1]=",img.item(0,2,1))
print("读取像素点img[1,0,2]=",img.item(1,0,2))
img.itemset((1,2,0),255)
img.itemset((0,2,1),255)
img.itemset((1,0,2),255)
print("修改后img=\n",img)
print("修改后像素点img[1,2,0]=",img.item(1,2,0))
print("修改后像素点img[0,2,1]=",img.item(0,2,1))
print("修改后像素点img[1,0,2]=",img.item(1,0,2))
运行结果如下
img=
[[[69 96 37]
[77 69 15]
[51 22 38]
[12 59 14]]
[[23 68 61]
[68 83 60]
[36 34 75]
[69 96 88]]]
读取像素点img[1,2,0]= 36
读取像素点img[0,2,1]= 22
读取像素点img[1,0,2]= 61
修改后img=
[[[ 69 96 37]
[ 77 69 15]
[ 51 255 38]
[ 12 59 14]]
[[ 23 68 255]
[ 68 83 60]
[255 34 75]
[ 69 96 88]]]
修改后像素点img[1,2,0]= 255
修改后像素点img[0,2,1]= 255
修改后像素点img[1,0,2]= 255
在本例中,为了方便读者纠致观察数内的值,生成的数组尺寸较小,在实际使用中,读者可以利用随机函数生成更大尺寸的随机数组,并使用函
cv2.imshow()观察随机数组对应的彩色图像
【例2.11】 生成一幅彩色图像,让其中的像素值均为随机数
根据口要求,编写代码如下
import cv2
import numpy as np
img=np.random.randint(0,256,size=[256,256,3],dtype=np.uint8)
cv2.imshow("demo",img)
cv2.waitKey()
cv2.destroyAllWindows()
上述程序可以生成一幅 256×256×3 的彩色图像,显示的图像图 2-14 所示。由于本书为黑白印,所以为了更好地观察运行效果,请大家米自上机运行
【例2.12】读取一副彩色图像,并对其像素进行访问,修改
根据口要求,编写代码如下
import cv2
img=cv2.imread("C:\\Users\\Administrator\\Desktop\\opencv\\lenacolor.png")
cv2.imshow("before",img)
print("访问img.item(0,0,0)=",img.item(0,0,0))
print("访问img.item(0,0,1)=",img.item(0,0,1))
print("访问img.item(0,0,2)=",img.item(0,0,2))
for i in range(0,50):
for j in range(0,100):
for k in range(0,3):
img.itemset((i,j,k),255) #白色
cv2.imshow("after",img)
print("修改后img.item(0,0,0)=",img.item(0,0,0))
print("修改后img.item(0,0,1)=",img.item(0,0,1))
print("修改后img.item(0,0,2)=",img.item(0,0,2))
cv2.waitKey()
cv2.destroyAllWindows()
在本程序中,首先,使用 iemO 函数读取了第0 行第0 列位置上的B 通道、G 通道、 R通道三个通道上的像素值;接着,使用 itemset函数对该值进行了修改:最后,使用嵌套循环语句将位于“第0 行到第 49行”和“第0 列到第9列”的交叉区域内的像素值设置为了 255 即让该区域显示为白色
运行上述程序,得到如图 215 所示结果,其中左图是读取的原始图像,右图是修改后的图像。由于本书为黑白印刷,所以为了更好地观察运行效果,请大家亲自上机运行程序
访问img.item(0,0,0)= 125
访问img.item(0,0,1)= 137
访问img.item(0,0,2)= 226
修改后img.item(0,0,0)= 255
修改后img.item(0,0,1)= 255
修改后img.item(0,0,2)= 255