动机
我们人类通过我们的视觉系统感知环境和周围的事物。人眼、大脑和肢体共同工作,以感知环境并相应地行动。一个智能系统可以执行那些需要一定智力水平的任务,如果由人类执行的话。因此,对于执行智能任务,人工视觉系统对于计算机来说是重要的事物之一。通常,摄像头和图像用于收集执行工作所需的信息。计算机视觉和图像处理技术帮助我们执行类似于人类完成的任务,如图像识别、目标跟踪等。
在计算机视觉中,摄像头充当人眼来捕捉图像,处理器充当大脑来处理捕捉的图像并生成重要的结果。但是人类和计算机之间存在基本差异。人脑自动工作,智力是天生获得的。相反,计算机没有智能,没有人类的指导(程序)就无法进行。计算机视觉是提供适当指令的方式,以便它可以与人类视觉系统兼容工作。但能力是有限的。
在接下来的部分中,我们将讨论图像是如何形成并如何使用Python进行操作的基本概念。
目录
图像是如何形成并显示的
计算机如何将图像存储在内存中
灰度和彩色图像
使用NumPy处理图像的基础知识
OpenCV基础知识
与NumPy一起玩耍
图像是如何形成并显示的
图像只是由具有不同颜色强度的像素组合而成。术语“像素”和“颜色强度”可能对你来说是陌生的。别担心,阅读本文直到最后,一切将变得清晰。
像素是数字图像的最小单元/元素。详细信息请参见下图。
显示是由像素形成的。在上图中,有25列和25行。每个小正方形被认为是一个像素。该设置可以容纳625个像素。它代表一个具有625个像素的显示屏。如果我们用不同颜色强度(亮度)照亮像素,它将形成一幅数字图像。
计算机如何将图像存储在内存中?
如果我们仔细看图像,我们可以将其与2D矩阵进行比较。矩阵具有行和列,其元素可以通过其索引进行寻址。矩阵结构类似于数组。计算机将图像存储在计算机内存的数组中。
每个数组元素保存颜色的强度值。通常,强度值范围从0到255。出于演示目的,我已包含了图像的数组表示。
灰度和彩色图像
灰度图像是一幅黑白图像。它只由一种颜色形成。接近0的像素值代表黑暗,随着强度值的增加变得更亮。最大值是255,代表白色。一个2D数组足以保存灰度图像,就像上图所示。
彩色图像不能只由一种颜色形成;可能有数十万种颜色组合。主要有三个主要的颜色通道红(R)、绿(G)和蓝(B)。每个颜色通道都存储在一个2D数组中,并保存其强度值,最终图像是这三个颜色通道的组合。
这种颜色模型有(256 x 256 x 256)= 16,777,216种可能的颜色组合。你可以在这里可视化组合。
但在计算机内存中,图像存储方式不同。
计算机不知道RGB通道。它知道强度值。红色通道存储在高强度中,绿色和蓝色通道分别存储在中等和低强度值中。
使用NumPy处理Python的基础知识
NumPy是进行科学计算的基本Python包。它主要作为一个数组对象工作,但它的操作不仅限于数组。然而,该库可以处理各种数字和逻辑运算[1]。你可以在这里找到NumPy的官方文档。
让我们开始我们的旅程。首要之事。
导入NumPy库。
import numpy as np
现在是时候使用NumPy了。正如我们所知,NumPy与数组一起工作。因此,让我们尝试创建我们的第一个全零2D数组。
创建NumPy数组
np.zeros((5,5))
array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])
就是这么简单。我们也可以创建一个所有元素都是1的NumPy数组,就像下面这样。
b=np.ones((4,4))
print(b)
[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]]
有趣的是,NumPy还提供了一种用任何值填充数组的方法。简单的语法array.fill(value)可以完成任务。
b.fill(3)
print(b)
[[3. 3. 3. 3.]
[3. 3. 3. 3.]
[3. 3. 3. 3.]
[3. 3. 3. 3.]]
数组'b'中所有元素现在都填充为3。
在随机数生成的情况下种子的功能
只需查看以下编码示例。
#with random seed
np.random.seed(10)
sample_arr = np.random.randint(0,50,10)
sample_arr
array([ 9, 36, 15, 0, 49, 28, 25, 29, 48, 29])
#without random seed-1
no_rand_seed=np.random.randint(0,50,10)
no_rand_seed
array([49, 8, 9, 0, 42, 40, 36, 16, 36, 47])
#without random seed-2
no_rand_seed=np.random.randint(0,50,10)
no_rand_seed
array([11, 24, 43, 33, 8, 36, 14, 49, 13, 5])
在第一个代码单元格中,我们使用了np.random.seed(seed_value),但是对于另外两个代码单元格,我们没有使用任何种子。有一个在有种子和没有种子的情况下生成随机数的主要区别。在有种子的情况下,生成的随机数对于特定的种子值保持不变。另一方面,在没有种子值的情况下,每次执行都会产生不同的随机数。
NumPy的基本操作(max、min、mean、reshape等)
NumPy通过提供大量函数来执行数学运算,使我们的生活更加轻松。array_name.min()、array_name.max()、array_name.mean()这些语法帮助我们找到数组的最小值、最大值和平均值。编码示例 —
sample_arr.max()
49
sample_arr.min()
0
sample_arr.mean()
26.8
最小值和最大值的索引可以使用语法array_name.argmax()、array_name.argmin()提取。示例 —
sample_arr.argmin()
3
sample_arr.argmax()
4
数组重塑是NumPy的重要操作之一。array_name.reshape(row_no, column_no)是重塑数组的语法。在重塑数组时,我们必须注意重塑前后的数组元素数量。在两种情况下,总元素数量必须相同。
sample_arr.reshape(5,2)
array([[ 9, 36],
[15, 0],
[49, 28],
[25, 29],
[48, 29]])
数组索引和切片
每个数组元素都可以通过其列和行号来寻址。让我们生成另一个具有10行和10列的数组。
new_array = np.arange(0,100).reshape(10,10)
print(new_array)
[[ 0 1 2 3 4 5 6 7 8 9]
[10 11 12 13 14 15 16 17 18 19]
[20 21 22 23 24 25 26 27 28 29]
[30 31 32 33 34 35 36 37 38 39]
[40 41 42 43 44 45 46 47 48 49]
[50 51 52 53 54 55 56 57 58 59]
[60 61 62 63 64 65 66 67 68 69]
[70 71 72 73 74 75 76 77 78 79]
[80 81 82 83 84 85 86 87 88 89]
[90 91 92 93 94 95 96 97 98 99]]
假设我们想要找到数组的第一个值。可以通过传递行和列索引(0,0)来提取。
row=0
column=0
new_array[row,column]
0
特定行和列的值可以使用语法array_name[row_no,:]、array_name[:,column_no]进行切片。
# Column slicing
new_array[:,column]
array([ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
#Row slicing
new_array[row,:]
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
让我们尝试切片数组的中心元素。
new_array[3:7,3:7]
array([[33, 34, 35, 36],
[43, 44, 45, 46],
[53, 54, 55, 56],
[63, 64, 65, 66]])
OpenCV基础知识
OpenCV是由Intel开发的计算机视觉的开源Python库[2]。尽管其范围广泛,我将讨论一些OpvenCv的用法。你可以在这里找到官方文档。
我使用了以下图像进行演示。
导入OpenCV和Matplotlib库
import cv2
import matplotlib.pyplot as plt
Matplotlib是一个可视化库,它帮助可视化图像。
使用OpenCV读取图像并用Matplotlib可视化
image=cv2.imread('sunflower.jpg')
plt.imshow(image)
<matplotlib.image.AxesImage at 0x232abb93b50>
我们用OpenCV读取了图像,并用Matplotlib库可视化了它。颜色发生变化,因为OpenCV以BGR格式读取图像,而Matplotlib期望以RGB格式读取图像。因此,我们需要将图像从BGR转换为RGB。
将图像从BGR格式转换为RGB格式
RGB = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
plt.imshow(RGB)
<matplotlib.image.AxesImage at 0x232ad2606d0>
现在,图像看起来正常了。
将图像转换为灰度
我们可以使用cv2.COLOR_BGR2GRAY轻松将图像从BGR转换为灰度,如下所示。
gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
plt.imshow(gray)
<matplotlib.image.AxesImage at 0x232adc51370>
尽管已将其转换为灰度,但上述图像并不是真正的灰度图。它已在Matplotlib中进行了可视化。默认情况下,Matplotlib使用灰度以外的颜色映射。为了正确可视化它,我们需要在Matplotlib中指定灰度颜色映射。让我们来做这个。
plt.imshow(gray,cmap='gray')
<matplotlib.image.AxesImage at 0x232adf19850>
旋转图像
使用OpenCV旋转也是一项简单的任务。cv2.rotate()函数帮助我们实现这一点。顺时针和逆时针90度和180度旋转如下所示。
rotate_90 = cv2.rotate(RGB,cv2.ROTATE_90_CLOCKWISE)
plt.imshow(rotate_90)
<matplotlib.image.AxesImage at 0x232ae9126d0>
rotate_90 = cv2.rotate(RGB,cv2.ROTATE_90_COUNTERCLOCKWISE)
plt.imshow(rotate_90)
<matplotlib.image.AxesImage at 0x232ae1d9460>
rotate_180 = cv2.rotate(RGB,cv2.ROTATE_180)
plt.imshow(rotate_180)
<matplotlib.image.AxesImage at 0x232ae244100>
调整图像大小
我们可以通过将宽度和高度像素值传递给cv2.resize()函数来调整图像的大小。
resized=cv2.resize(RGB, (800,1400))
plt.imshow(resized)
<matplotlib.image.AxesImage at 0x232ae5e2460>
在图像上绘制
有时我们需要在现有图像上绘制。例如,我们需要在图像对象上绘制一个边界框以识别它。让我们在花朵上绘制一个矩形。cv2.rectangle()函数帮助我们进行绘制。它接受一些参数,例如我们要在其上绘制矩形的图像、左上角的坐标点(pt1)和右下角的坐标点(pt2),以及边界线的厚度。以下是一个编码示例。
cv2.rectangle(RGB,pt1=(500,200),pt2=(1250,1000),color=(255,0,0),thickness=15)
plt.imshow(RGB)
<matplotlib.image.AxesImage at 0x232b1305f70>
还有其他的绘图函数,如cv.line()、cv.circle()、cv.ellipse()、cv.putText()等。完整的官方文档可以在这里找到[3]。
与NumPy一起玩耍
我们将更改图像的强度值。我将尽量保持简单。所以,请考虑前面显示的灰度图像。查找图像的形状。
gray.shape
(1280, 1920)
它显示为一个大小为1200 x 1920的2D数组。在基本的NumPy操作中,我们学习了如何切片一个数组。
gray[400:800,750:1350]=255
plt.imshow(gray,cmap='gray')
<matplotlib.image.AxesImage at 0x232aba7dc10>
利用这个概念,我们取了灰度图像数组切片[400:800, 750:1350]并将强度值替换为255。最后,我们对其进行可视化并得到上述图像。
结论
计算机视觉是现代计算机科学技术中一个有前途的领域。我总是强调对任何领域的基本知识的重要性。我仅讨论了计算机视觉的基本知识并展示了一些实际编码。这些概念非常简单,但对于计算机视觉的初学者可能起着重要作用。
完整的代码可以在这里找到。
https://github.com/Zubair063/ML_articles/tree/main/Getting%20Started%20with%20NumPy%20and%20OpenCV
这是计算机视觉系列的第一篇文章。请关注以阅读即将发布的文章。
[注:教练Jose Portilla的课程帮助我收集知识。]
参考文献
https://numpy.org/devdocs/
https://en.wikipedia.org/wiki/OpenCV
https://docs.opencv.org/4.x/dc/da5/tutorial_py_drawing_functions.html
☆ END ☆
如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 woshicver」,每日朋友圈更新一篇高质量博文。
↓扫描二维码添加小编↓