Practical Python and OpenCV,3rd Edition 02

基础说明

什么是像素

每个图像都由一组像素组成。 像素是图像的原始构建块。没有比像素更小的单位了。

通常,我们将像素视为出现在图像中给定位置的光的“颜色”或“强度”。

如果我们将图像视为网格,则网格中的每个方块都包含一个像素。

例如,假设我们有一个分辨率为500×300的图像。这意味着我们的图像表示为像素网格,有500行和300列。总体而言,我们的图像总共有 500×300 = 150,000像素。

大多数像素以两种方式表示:灰度(grayscale)和彩色(color)。在灰度图像中,每个像素具有0到255之间的值,其中0对应于“黑色”而255对应于“白色”。 0到255之间的值是不同的灰色阴影,其中,接近0的更加的darker,接近于255更加的lighter。

彩色通常以RGB颜色空间表示,one value for the Red component,one for Green,and one for Blue。

RGB中的每一种都由0到255范围内的整数表示,这表示颜色的“多少”。像素值只需要在[0,255]范围内,我们通常使用8位无符号整数来表示每种颜色强度。

然后,我们将这些值组合成图形中的RGB(红色,绿色,蓝色)元组(tuple)。 这个元组就代表我们的颜色。

为了构建一个白色,我们将完全填充每个红色,绿色和蓝色 buckets,如下所示:(255,255,255)。为了创建一个黑色,我们将每个bucket都清空:(0,0,0) ,为了创造一种纯红色,我们将完全填满红色的bucket:(255,0,0)。

coordinate system(坐标系统)

如上所述,图像表示为像素网格。 想象一下我们的网格作为一张方格纸。 使用该方格纸,点(0,0)对应于图像的左上角。 当我们向下和向右移动时,x和y值都会增加。(Python语言是零索引的,这意味着我们总是从零开始计数。),看下图:

Practical Python and OpenCV,3rd Edition 02

字母“I”放在一张图纸上.像素是通过他们的(x,y)坐标访问的,我们向右走x列,向下走y行(因为x是横坐标,y是纵坐标),记住Python是零索引的:我们从零而不是一开始计数。

代码

from __future__ import print_function
import argparse
import cv2
ap = argparse.ArgumentParser()
ap.add_argument('-i',"--image",required=True,
help="Path to the image")
args = vars(ap.parse_args())
image = cv2.imread(args["image"])
cv2.imshow("Original",image)

请记住,OpenCV将图像表示为NumPy数组。概念上,我们可以将此表示视为一个矩阵。为了访问像素值,我们只需要提供我们感兴趣的像素的x和y坐标。但是,重要的是要注意OpenCV以相反的顺序存储RGB channels。 虽然我们通常用Red,Green和Blue(RGB)来思考,但OpenCV实际上按Blue,Green和Red的顺序存储它们(BGR)。如下面的代码:

(b,g,r) = image[0,0]
print("Pixel at (0,0) - Red:{}, Green: {}, Blue: {}".format(
r,g,b))
image[0,0] = (0,0,255)
(b,g,r) = image[0,0]
print("Pixel at (0,0) - Red: {} , Green: {}, Blue: {}".format(r,
g,b))

解释

我们首先抓取图像的左上角的像素,即(0,0)的位置。 这个像素表示为元组.同时,OpenCV以相反的顺序存储RGB像素,因此当我们解包并访问元组中的每个元素时,我们实际上是以BGR顺序查看它们。然后我们将像素RGB颜色打印出来。

接下来,我们操纵图像中的左上角像素,该像素位于坐标(0,0)处,并将其设置为(0,0,255)。 如果我们以RGB格式读取这个像素值,我们的红色值为0,绿色值为0,蓝色值为255,因此使其成为纯蓝色。但是,正如我上面提到的,在使用OpenCV时我们需要特别注意。 我们的像素实际上以BGR格式存储,而不是RGB格式。我们实际上将这个像素读为255为红色,0为绿色,0为蓝色,使其成为红色,而不是蓝色。

corner = image[0:100,0:100]
cv2.imshow("Corner",corner)
image[0:100,0:100] = (0,255,0)
cv2.imshow("Updated",image)
cv2.waitKey(0)

解释

接下来我们使用NumPy的数组切片功能来访问图像的较大矩形部分。为了访问图像较大的部分,Numpy希望我们提供四个索引值,分别是Start y,End y,Start x以及End x。

最后,运行程序即可。

Practical Python and OpenCV,3rd Edition 02

效果图:

Practical Python and OpenCV,3rd Edition 02

点击图片部分,按键盘任意键结束脚本。

完整的代码

from __future__ import print_function
import argparse
import cv2
ap = argparse.ArgumentParser()
ap.add_argument('-i',"--image",required=True,
help="Path to the image")
args = vars(ap.parse_args())
image = cv2.imread(args["image"])
cv2.imshow("Original",image)

(b,g,r) = image[0,0]
print("Pixel at (0,0) - Red:{}, Green: {}, Blue: {}".format(
r,g,b))
image[0,0] = (0,0,255)
(b,g,r) = image[0,0]
print("Pixel at (0,0) - Red: {} , Green: {}, Blue: {}".format(r,
g,b))
corner = image[0:100,0:100]
cv2.imshow("Corner",corner)
image[0:100,0:100] = (0,255,0)
cv2.imshow("Updated",image)
cv2.waitKey(0)

更多参考我的博客:https://0leo0.github.io/2018/OpenCV_python3_02.html


分享到:


相關文章: