![OpenCV轻松入门:面向Python(第2版)](https://wfqqreader-1252317822.image.myqcloud.com/cover/266/47382266/b_47382266.jpg)
2.3 使用numpy.array访问像素
numpy.array提供了item()和itemset()函数来访问和修改像素值,而且这两个函数都是经过优化处理的,能够更大幅度地提高处理效率。在访问及修改像素点的值时,利用numpy.array提供的函数比直接使用索引要快得多,同时,这两个函数的可读性也更好。
1.二值图像及灰度图像
可以将二值图像理解为特殊的灰度图像,所以这里仅以灰度图像为例讨论像素点值的读取和修改。
函数item()能够更加高效地访问图像的像素点,该函数的语法格式为
![](https://epubservercos.yuewen.com/D41D8C/26766203101053706/epubprivate/OEBPS/Images/txt002_27.jpg?sign=1739623426-dPcprqWAG1YAJELklPlhGNpgEXO3m4F3-0-2f4fc5c75de173449f89f81d0d744fea)
函数itemset()可以用来修改像素值,其语法格式为
![](https://epubservercos.yuewen.com/D41D8C/26766203101053706/epubprivate/OEBPS/Images/txt002_28.jpg?sign=1739623426-a6YRLvz5iW4nAfbNtGNDFnSiF5zVUnRA-0-ddbac62fa3e1f3bd8a795201d88769d9)
为了便于理解,我们首先使用Numpy库生成一个5×5大小的随机数组,用来模拟一幅灰度图像,并对其进行简单的处理。
【例2.7】使用Numpy生成一个二维随机数组,用来模拟一幅灰度图像,并对其像素进行访问、修改。
分析:使用Numpy中的random.randint可以生成一个随机数组,该随机数组对应一幅灰度图像。然后分别使用函数item()及函数itemset()对其像素进行访问、修改。
根据题目要求及分析,编写代码如下:
![](https://epubservercos.yuewen.com/D41D8C/26766203101053706/epubprivate/OEBPS/Images/txt002_29.jpg?sign=1739623426-Lao5NkmXfmP9w6XGPLh66qTtFh3GruUX-0-65b4a5aac978076f042a3e4e3a3c5716)
式中,语句“img=np.random.randint(10,99,size=[5,5],dtype=np.uint8)”表示生成一个大小为5×5,类型为“np.uint8”(数值范围[0,255]),值在[10,99]范围内的数组img。函数np.random.randint的语法为
![](https://epubservercos.yuewen.com/D41D8C/26766203101053706/epubprivate/OEBPS/Images/txt002_30.jpg?sign=1739623426-fjjuq0IFSvm20cFNIIEAXQGP4nwBdBjV-0-8f4a1be441779ecad25f7021bcc9b081)
使用时在对应的参数位置填入相应的值即可。
运行程序,控制台输出结果如下:
![](https://epubservercos.yuewen.com/D41D8C/26766203101053706/epubprivate/OEBPS/Images/txt002_31.jpg?sign=1739623426-fIX3tJQDjQvtjBsbwrMt2GwrK5n38gIA-0-690fd6b9ed4fe97b0058fa48b5faffd3)
通过观察输出结果可以发现,语句img.itemset((3,2),255)将图像第3行第2列位置上的像素值修改为255了。
在例2.7中,为方便大家能够清晰地观察数组内的每一个值,生成的数组规模(尺寸)较小。在实际使用中,可以利用随机函数生成更大尺寸的随机数组,并使用函数imshow()观察随机数组对应的灰度图像。
【例2.8】生成一个灰度图像,让其中的像素值均为随机数。
根据题目要求,编写代码如下:
![](https://epubservercos.yuewen.com/D41D8C/26766203101053706/epubprivate/OEBPS/Images/txt002_32.jpg?sign=1739623426-jEXyRsCjF0BsHj5w8lan7ZtqmpsfcVxv-0-67e82cfa4948a0f1d2a22b8826311458)
运行上述程序,可以生成一幅256像素×256像素大小的灰度图像,如图2-12所示。
![](https://epubservercos.yuewen.com/D41D8C/26766203101053706/epubprivate/OEBPS/Images/txt002_33.jpg?sign=1739623426-02l7t0tN9L4K6Yj2WFoTxENNr4wFj823-0-83ef044ec2c18e4aa945f0706ebba3b1)
图2-12 随机灰度图像
【例2.9】读取一幅灰度图像,并对其像素值进行访问、修改。
根据题目要求,编写代码如下:
![](https://epubservercos.yuewen.com/D41D8C/26766203101053706/epubprivate/OEBPS/Images/txt002_34.jpg?sign=1739623426-KFV4lENWltQ81QnnkpsV7lpWeken0Vn8-0-f2856a4227ff9a0fedc8969734a30964)
本程序首先修改了一个像素点的像素值:使用item()函数读取了第3行第2列位置上的像素值;接下来使用itemset()函数对该像素值进行了修改。
接下来使用嵌套循环语句修改了一个区域的像素值,将位于“第10行到第99行”和“第80列到第99列”的行列交叉区域的像素值设置(修改)为255,即让该区域显示为白色。
运行上述程序,显示如图2-13所示图像,其中,图2-13(a)是读取的原始图像,图2-13(b)是修改部分像素后得到的图像。
![](https://epubservercos.yuewen.com/D41D8C/26766203101053706/epubprivate/OEBPS/Images/txt002_35.jpg?sign=1739623426-La5sZHGDcY0qXThwL45tDUcVOdiCMDC3-0-444ec457db8ecdf2a11b0f3e564a5ef1)
图2-13 【例2.9】程序的运行结果
同时,在控制台得到如下结果:
![](https://epubservercos.yuewen.com/D41D8C/26766203101053706/epubprivate/OEBPS/Images/txt002_36.jpg?sign=1739623426-k7Z761UFtvg5ZhQRwIJDMer8Ls9wsHSt-0-a8e2c474bfce72ababcd2dbad3507c53)
2.彩色图像
我们也可以使用函数item()和函数itemset()来访问和修改彩色图像的像素值,过程与操作灰度图像相似,不同之处在于需要补充通道信息。
函数item()访问RGB模式图像的像素值时,其语法格式为
![](https://epubservercos.yuewen.com/D41D8C/26766203101053706/epubprivate/OEBPS/Images/txt002_37.jpg?sign=1739623426-iSJYa2lhDl0PgagWczHWVAWxORflD1SZ-0-dacb6dec8fbfa957cf35a0f5e6d6c16c)
函数itemset()修改(设置)RGB模式图像的像素值时,其语法格式为
![](https://epubservercos.yuewen.com/D41D8C/26766203101053706/epubprivate/OEBPS/Images/txt002_38.jpg?sign=1739623426-4vypn2Rr83MSk3PdGkJPWPvZ0eX4uYIc-0-fd8bdfab42f181f8dfcbeb05faaae252)
需要注意,针对RGB图像的访问,必须同时指定行、列及行列索引(通道),例如img.item(a,b,c)。仅仅指定行和列是不可以的。
【例2.10】使用Numpy生成一个由随机数构成的三维数组,用来模拟一幅RGB色彩空间的彩色图像,并使用函数item()和itemset()来访问和修改它。
根据题目要求,编写代码如下:
![](https://epubservercos.yuewen.com/D41D8C/26766203101053706/epubprivate/OEBPS/Images/txt002_39.jpg?sign=1739623426-vWeU4AMVNOWp5FGZpwLvuKqnfJ95rCc5-0-27ef5dd26951bc889ea38e03ffd66a0c)
运行上述程序,在控制台得到如下输出结果:
![](https://epubservercos.yuewen.com/D41D8C/26766203101053706/epubprivate/OEBPS/Images/txt002_40.jpg?sign=1739623426-v06ySLEUP254l9j3N9p6uZBpolLuwOSQ-0-5b125838442a75d05bf576cc97b0022b)
在本例中,为了方便大家细致地观察数组内的值,生成的数组尺寸较小。在实际使用中,大家可以利用随机函数生成更大尺寸的随机数组,并使用函数cv2.imshow()观察随机数组对应的彩色图像。
【例2.11】生成一幅彩色图像,让其中的像素值均为随机数。
根据题目要求,编写代码如下:
![](https://epubservercos.yuewen.com/D41D8C/26766203101053706/epubprivate/OEBPS/Images/txt002_41.jpg?sign=1739623426-TRyTWSBHjRKaecQCXV9qhoAMJ9ai6yx9-0-7b4dfdeca1829cd1385c42c3078ed05e)
上述程序可以生成一幅256像素×256像素×3像素的彩色图像,显示的图像如图2-14所示。
![](https://epubservercos.yuewen.com/D41D8C/26766203101053706/epubprivate/OEBPS/Images/txt002_42.jpg?sign=1739623426-0bc7GsDzcylwK7coYQi2XkT4PbGNdYBL-0-2536ce5c413506cbdf2e8f712a9b969c)
图2-14 随机图像
【例2.12】读取一幅彩色图像,并对其像素进行访问、修改。
根据题目要求,编写代码如下:
![](https://epubservercos.yuewen.com/D41D8C/26766203101053706/epubprivate/OEBPS/Images/txt002_43.jpg?sign=1739623426-tepb1lkOgvwxbQv31maHkaERrwkClVrB-0-5daa62a310ba663fc3b09628e4f17eb5)
在本程序中,首先,使用item()函数读取了第0行第0列位置上的B通道、G通道、R通道三个通道上的像素值。
接下来,借助itemset()函数将左上角设置为白色。在嵌套循环语句中,使用itemset()函数,将位于“第0行到第49行”和“第0列到第99列”的交叉区域内的像素值设置为255。
运行上述程序,得到如图2-15所示结果,其中图2-15(a)是读取的原始图像,图2-15(b)是修改后的图像。
![](https://epubservercos.yuewen.com/D41D8C/26766203101053706/epubprivate/OEBPS/Images/txt002_44.jpg?sign=1739623426-x2XZjnNhxe02rkiyzSK3CskWHN3iQz5j-0-5dd72a7dad56dd11ce94635387fc0ed7)
图2-15 【例2.12】程序的运行结果
同时,会在控制台显示如下结果:
![](https://epubservercos.yuewen.com/D41D8C/26766203101053706/epubprivate/OEBPS/Images/txt002_45.jpg?sign=1739623426-6hDtreYF3gmM89g7LLaXVqnjARd1Yhyw-0-955206e2b53744a41a131dd0c36b3cd1)
![](https://epubservercos.yuewen.com/D41D8C/26766203101053706/epubprivate/OEBPS/Images/txt002_46.jpg?sign=1739623426-erTzMaH7kiqsoWuORnwZhmddXHT7GjYM-0-c2cef935a85cddbd8a7d308a4f48e074)