cv2 像素

发布时间 2023-12-15 22:17:52作者: freedragon

像素是构成数字图像的基本单位。现有一幅显示花朵的图像(如图1所示),提取并放大图1中被蓝色圆环圈住的区域,将得到一幅如图2所示的图像。

1  一幅显示花朵的图像

2  提取并放大图1中被蓝色圆环圈住的区域

不难发现,图2所示的图像是由许多个小方块组成的,通常把一个小方块称作一个像素。因此,一个像素是具有一定面积的一个块,而不是一个点。需要注意的是,像素的形状是不固定的;大多数情况下,像素被认为是方形的,但有时也可能是圆形的或者是其他形状的。

1  确定像素的位置

以图1为例,在访问图1中的某个像素之前,要确定这个像素在图1中的位置。那么,这个位置应该如何确定呢?

首先,确定图1在水平方向上和垂直方向上的像素个数。图1的“水平方向”和“垂直方向”如图3所示。

3  图1的“水平方向”和“垂直方向”

Windows 10系统的“画图”工具中打开图1,将得到如图4所示的界面。在这个界面中,就会得到图1在水平方向上的像素个数是219个,在垂直方向上的像素个数是292个。

 

4  把图2在“画图”工具中打开

然后,根据图1中在水平方向上和垂直方向上的像素个数,绘制如图5所示的坐标系。

5  根据图2.1在水平方向和垂直方向上的像素个数绘制坐标系

说明:图1在水平方向上的像素个数是219个,与其对应的是x轴的取值范围,即0~218;同理,图1在垂直方向上的像素个数是292个,与其对应的是y轴的取值范围,即0~291。

这样,就能够通过坐标来确定某个像素在图1中的位置。在OpenCV中,正确表示图1中某个像素坐标的方式是(y, x)。例如,在如图5所示的坐标系中,图1右下角的像素坐标是(291, 218)。

实例1  表示图1中的指定像素

编写一段代码,先读取D盘根目录下的2.1.jpg,再表示坐标(291, 218)上的像素。代码如下:

import cv2

 

image = cv2.imread("D:/2.1.jpg") # 读取D盘根目录下的2.1.jpg

px = image[291, 218] # 坐标(291, 218)上的像素

2  获取像素的BGR值

前面已经得到了坐标为(291, 218)上的像素px。现使用print()方法打印这个像素,将得到这个像素的RGB值。代码如下:

print("坐标(291, 218)上的像素的RGB值是", px)

上述代码的运行结果如下:

坐标(291, 218)上的像素的RGB值是 [36 42 49]

不难发现,坐标(291, 218)上的像素的RGB值是由36、42和49这3个数值组成的。在讲解这3个数值各自代表的含义之前,先了解下什么是三基色。

如图6所示,人眼能够感知红色、绿色和蓝色这3种不同的颜色,因此把这3种颜色称作三基色。如果将这3种颜色以不同的比例进行混合,人眼就会感知到丰富多彩的颜色。

6  三基色

那么,对于计算机而言,是如何对这些颜色进行编码的呢?答案就是利用色彩空间。也就是说,色彩空间是计算机对颜色进行编码的模型。

以较为常用的RGB色彩空间为例,在RGB色彩空间中,存在3个通道,即R通道、G通道和B通道。其中,R通道指的是红色(Red)通道;G通道指的是绿色(Green)通道;B通道指的是蓝色(Blue)通道;并且每个色彩通道都在区间[0, 255]内进行取值。

这样,计算机将会利用这3个色彩通道的不同组合来表示不同的颜色。如图7所示,通过截图工具,能够得到坐标(291, 218)上的像素的RGB值为(49, 42, 36)。

7  坐标为(291, 218)上的像素的RGB值

说明:通常使用一个三维数组来表示一幅图像中某一个像素的RGB值。例如,图1中坐标(291, 218)上的像素的RGB值为(49, 42, 36)。

使用print()方法打印图1中坐标(291, 218)上的像素px,其结果是(36, 42, 49)。而图7中这个坐标上的像素的RGB值为(49, 42, 36)。这时会发现这两个结果中的数值是相同的,但顺序是相反的,这是为什么呢?

原因是OpenCV对图像的通道顺序进行了转换,即把RGB图像的通道顺序由R(49)→G(42)→B(36)转换为BGR图像的通道顺序,即B(36)→G(42)→R(36)。

说明:RGB图像是指用RGB色彩空间显示的图像,BGR图像是指用BGR色彩空间显示的图像;RGB色彩空间和BGR色彩空间的区别是图像在RGB色彩空间中的通道顺序是R→G→B,在BGR的色彩空间中的通道顺序是B→G→R。

OpenCV中,获取坐标(291, 218)上的像素px的BGR值有如下两种方式:

1)同时获取坐标(291, 218)上的像素的B通道、G通道和R通道的值。代码如下:

import cv2

 

image = cv2.imread("D:/2.1.jpg")

px = image[291, 218] # 坐标(291, 218)上的像素

print(px)

上述代码的运行结果如下:

[36 42 49]

2)分别获取坐标(291, 218)上的像素的B通道、G通道和R通道的值。代码如下:

import cv2

 

image = cv2.imread("D:/2.1.jpg")

blue = image[291, 218, 0] # 坐标(291, 218)上的像素的B通道的值

green = image[291, 218, 1] # 坐标(291, 218)上的像素的G通道的值

red = image[291, 218, 2] # 坐标(291, 218)上的像素的R通道的值

print(blue, green, red)

上述代码的运行结果如下:

36 42 49

说明:(1)image[291, 218, 0]中的最后一个数值0表示B通道;

        (2)image[291, 218, 1]中的最后一个数值1表示G通道;

        (3)image[291, 218, 2]中的最后一个数值2表示R通道。

3  修改像素的BGR值

已经获取了图1中坐标(291, 218)上的像素px的BGR值,即(36, 42, 49)。现要将像素px的BGR值由原来的(36, 42, 49)修改(255, 255, 255),代码如下:

import cv2

 

image = cv2.imread("D:/2.1.jpg")

px = image[291, 218]

print("坐标(291, 218)上的像素的初始RGB值是", px)

px = [255, 255, 255] # 把坐标(291, 218)上的像素的值修改为[255, 255, 255]

print("坐标(291, 218)上的像素修改后的RGB值是", px)

上述代码的运行结果如下:

坐标(291, 218)上的像素的初始RGB值是 [36 42 49]

坐标(291, 218)上的像素修改后的RGB值是 [255, 255, 255]

说明:对于RGB/BGR图像,当每个像素的R、G、B这3个数值相等时,就可以得到灰度图像。其中,R = G = B = 0(B = G = R = 0)为纯黑色;R = G = B = 255(B = G = R = 255)为纯白色。

实例2  修改图1中的指定区域内的所有像素

编写一个程序,将图1中的坐标(241, 168)、(241, 218)、(291, 168)和(291, 218)这4个点所围成的区域内的所有像素都修改为纯白色。代码如下:

import cv2

 

image = cv2.imread("D:/2.1.jpg")

cv2.imshow("2.1", image) # 显示图1

for i in range(241, 292): # i表示横坐标,在区间[241, 291]内取值

    for j in range(168, 219): # j表示纵坐标,在区间[168, 218]内取值

        image[i, j] = [255, 255, 255] # 把区域内的所有像素都修改为白色

cv2.imshow("2.8", image) # 显示图8

cv2.waitKey()

cv2.destroyAllWindows() # 关闭所有的窗口时,销毁所有窗口

上述代码的运行结果如图8所示(左侧的图片是原图)。

8  把指定区域内的所有像素都修改为白色