【计算机视觉处理二】图像的基础知识

2020-11-25 12:52:48 浏览数 (1)

图像的基础知识

1、计算机中的图像

在计算机中,图像是以二进制形式存储的。但是我们通常不会以二进制方式操作图像,在处理图像时我们更乐意把图像看作是一个点集。这个集合是以二维的方式分布的,每个点都有自己的颜色,每个点都不可再分割。这样的点我们称它为像素。比如下面这张图片:

我们可以把它看作是一个5*5的图像,其中每个点都是黑色的。

早期的计算机只能显示简单的图像,比如二值图像。这种图像非黑即白,不容许第三种颜色存在。比如下面:

对于这种图片,我们每个像素只需要一位二进制(0,1)就可以表示。但是这种图像不能满足人的需求,于是又有了细节更加丰富,但依旧没有颜色的图像,也就是我们后面会接触到的灰度图像。比如下面:

上面的图像保留了真实场景中的大多数细节。如果再用一位二进制表示灰度图的像素就显得有些不足了,因此灰度图需要用8位二进制来表示,也就是0-255。因为现在硬盘不再是稀缺资源,所以二值图像我们通常也用8位二进制表示。用0表示0(黑色),用255表示1(白色)。

如果要表示彩色图像就更加复杂了,下面是一直图片的RGB图像:

所谓的RGB图像就是一张像素由三个值来表示的图片。三个值分别表示红、绿、蓝三种颜色的程度。比如如果一个像素的红色程度是255,其它两个颜色程度是0,那么这个像素在我们看来就是红色的。通过这三种颜色的搭配,我们可以配出4294967296种不同的颜色。

当然,我们生活中的图像还要丰富得多,比如透明图像、动态图像等。这里就不再详细说了。

2、OpenCV中的图像

在上面说到的对不同图像的理解在OpenCV中是一样适用的。

在OpenCV中,图像以ndarray类型存储。ndarray是numpy中的数组,它具有多个维度,它可以表示图像的完整信息。包括图片的宽高、像素的值等。我们可以尝试看看下面这张图片的ndarray数组:

因为比较长,我们截取一部分查看,下面是输出结果:

代码语言:javascript复制
[[[245 225 190]
  [245 225 190]
  [245 225 190]
  ...
  [214 195 184]
  [214 195 184]
  [214 195 184]]

 [[245 225 190]
  [245 225 190]
  [245 225 190]

现阶段我们还不需要太在意数组的内容,OpenCV提供了简单的API供我们获取图片的关键信息。下面我们来简单看一下。

3、获取图像信息

在获取图像信息之前,我们需要使用imread函数读取图片。我们看下面这段代码:

代码语言:javascript复制
import cv2
im = cv2.imread('xscn.jpg')
print("图像的形状:", im.shape)
print("图像的大小:", im.size)
print("图像的数据类型:", im.dtype)

我们先看一下输出的结果,

代码语言:javascript复制
图像的形状:(1080, 1920, 3)
图像的大小:6220800
图像的数据类型:uint8

再来解释一下各个参数:

•shape:图片的形状,包含高、宽、图层数的信息•size:高*宽*图层数的值•dtype:每个数据的类型。对于灰度图,一个数据就是一个像素。对于RGB图像,一个数据就是一个像素中一种颜色的值。unit8表示8位二进制的正整数(0-255)

其中图层数表示一个像素由几个数据组成。比如灰度图的图层数是1,而RGB图像的图层数是3。

4、图像坐标

为了方便,我们可以为图像构建一个坐标系,这个坐标系不需要实际构造,而只是为了方便我们理解。

我们来看下面这张图片:

我们构建了一个坐标系,然后把图片的左上角对应原点。这样我们可以用(x,y)形式定义一个像素点,比如图中的点A的坐标为(500,300)。

5、获取像素值

获取像素值同样需要先读取图像,然后我们可以通过下面的方式来访问指定位置的像素:

代码语言:javascript复制
im[y][x]

其中im是我们的图片对象。x、y对应坐标中的x、y。比如下面这段代码:

代码语言:javascript复制
import cv2
im = cv2.imread('xscn.jpg')
pixel = im[0][0]
print(pixel)

输出结果如下:

代码语言:javascript复制
[245 225 190]

因为读取的是RGB图像,所以单个像素由三个数据组成。我们还可以进一步获取某个颜色的值,比如我想获取坐标为(100,100)的像素中红色的值,我们可以这样获取:

代码语言:javascript复制
red = im[100][100][0]

但是其实这样是错误的。因为在OpenCV中,图像默认表示为GBR模式,而上面我们获取的应该是绿色的值。正确获取红色的操作应该如下:

代码语言:javascript复制
red = im[100][100][2]

6、修改像素值

像素值的修改非常简单,我们只需要找到某个像素,然后对其赋值即可。比如我们对下面这张图片进行操作:

上面为了方便观看,把一张3*3的图片放大后的效果。我们用代码对图片像素进行修改:

代码语言:javascript复制
import numpy as np
im = np.zeros((3, 3, 1), dtype=np.uint8)
im[0][2] = 255

其中np.zeros的作用是创建一个多维数组。我们直接把它理解为创建了上面的图像,后续我们会有更详细的讲解。

创建图像后我们把(2,0)处的像素修改为255,下面是修改后的图片:

可以看到指定像素被修改了。

0 人点赞