不过,这三个人最近确实在我的机器上走到了一起,创造了一些魔力,每个人都用自己的力量做了一些令人着迷的图像处理。这就是这一切是如何发生的故事。
但首先是…
引言
OpenCV(开放源码计算机视觉)是一个库,旨在为计算机视觉应用程序提供通用基础设施,并加速机器感知在商业产品中的使用(来自OpenCV网站)。OpenCV website
它有相当多的计算机视觉和机器学习算法,使用户能够执行各种与图像相关的任务,例如
- 检测和识别人脸
- 标识对象
- 跟踪视频中的人类行为
- 跟踪摄像机移动
- 提取对象3D模型
- 等
在本文中,我们将使用Linux上OpenCV的Python接口。我们将探究该库的一些基础知识,包括
- 读取图像文件
- 显示图像
- 调整图像大小
- 将图像写入文件
后续文章将探讨OpenCV库的一些更高级的方面。
NumPy(Numerical Python)是一个开源库,它构成了Python中科学计算的核心。它的基本对象是数组,在这个对象上可以执行各种操作(排序、切片、数学、逻辑、形状处理等)。
我们将在描述我们将使用OpenCV读取的图像的数组对象的一些操作中使用NumPy。
Streamlight是一个开源的Python库,用他们的话说,它是“构建和共享数据应用程序的最快方式”。这是一个很棒的工具,人们可以用几行代码快速构建一个Web应用程序。然后可以部署此应用程序,然后用户可以访问它与其进行交互。
我们将使用Streamlight部署一个应用程序,该应用程序将允许用户与我们将构建的一些图像处理工具进行交互。
安装
如前所述,OpenCV有许多接口。要使用Python接口,您需要安装openCV-python。我们还将在本文中使用Matplotlib。mentioned earlier opencv-python Matplotlib
对于所有四种工具,只需使用pip…即可完成安装。
使用的版本包括:
- OpenCV 4.5.2
- NumPy 1.21.0
- Streamlight 0.84.0
- Matplotlib 3.4.2
我们现在准备好去探索它们了。
利用OpenCV对图像进行基本操作
读取图像文件
要使用OpenCV读取图像,首先需要导入库,然后使用其cv2.imread()函数执行此操作。该函数接受一个参数(文件名)。它有一个可选第二个参数,该参数是一个确定如何打开文件的标志。默认情况下,使用的选项为cv2.IMREAD_COLOR。flag
在某些情况下,您将看到作为cv导入的库(例如,在本教程中)。有些保留原样导入(CV2)。我们将其保留为CV2。this tutorial
当我们打印图像文件的前几列和前几行时,我们会看到结果数组。
每列表示一个颜色通道。但是,OpenCV与其他工具不同,它颠倒了通道的顺序。通常,第一列为红色,第二列为绿色,第三列为蓝色(从左到右阅读)。OpenCV将其命名为蓝绿红。
要将图像转换为常规RGB格式,请使用下面的代码片段:
从print命令中,我们获得图像数组的以下前几个条目:
当我们在下一节中显示图像时,应该可以看到这种差异。
显示图像
现在我们已经读取了图像,是时候显示它了。为此,我们将使用cv2.imshow()函数。它有两个参数:将生成的窗口的名称和要显示的图像的名称。
但这还不是全部。我们还需要指示OpenCV保持窗口打开足够长的时间,以便我们可以看到图像。如果您不这样做,那么要运行的命令将立即执行并关闭窗口。
要保持窗口打开足够长的时间以查看图像,需要添加cv2.waitKey(),其参数是窗口应该保持打开的延迟时间。时间是以毫秒为单位测量的,因此值2000将使窗口保持打开2秒,然后将其关闭。如果延迟小于或等于0,cv2.waitKey()将无限保留窗口。要关闭窗口,请按键盘上的任意键。
最后,我们调用cv2.destroyAllWindows()来销毁所有生成的窗口。
如果我们想要与笔记本一起内联显示图像,而不是在单独的窗口中显示,那么我们需要使用Matplotlib。导入它,然后调用plt.imshow()函数来显示图像。
这就是我们遇到前面提到的问题的时候。
那是不对的!颜色看起来全错了!这是因为OpenCV的通道顺序颠倒了。
如果我们使用cv2.imshow()来显示颜色转换后的图像(IMAGE_Rgb),我们将得到与上面的…类似的结果
如果您比较两个不同窗口底部的颜色信息,您会注意到红色和蓝色通道的值已切换。
现在,让我们使用plt.imshow()并排显示两张图片:
认识到这一事实应该能保证我们的安全。如果要使用plt.show()显示图像,则需要记住将其从BGR转换为RGB。如果我们使用cv2.imshow()来显示图像,则不需要执行此转换。
如果您跟随代码并试图获取cv2.imshow()窗口的屏幕快照,但没有成功,请不要担心。您可以设置代码,以确保仅当您按下键盘上的特定键时窗口才会关闭。下面的代码片段允许您执行此操作。
基本上,它测试指定的键(在本例中为字母Q)是否已被按下。如果是这样,那么它将关闭窗口。
显示图像阵列信息
您可以使用以下内容获取有关图像阵列的更多信息:
- .Shape-显示图像数组的形状
- .size-显示阵列的大小
- .dtype-显示数组值的数据类型
裁剪图像
您可以使用NumPy数组索引来仅显示图像的一部分。NumPy array indexing
上面的代码将显示100行乘100列乘3通道的行200和300以及列750和850之间的图像阵列。
您还可以选择仅查看一个通道…的值
在上面,我们仅显示来自绿色通道的切片(由colstop右侧的1表示)。不出所料,我们仅从一个通道就获得了总共10,000个值,占显示所有三个通道时显示的30,000个值总数的三分之一。
让我们展示这两片,看看它们是什么样子。
替换部分图像中的颜色
假设我们的模特飞翔先生感到害羞,他不希望自己的眼睛出现在图像中。我们可以通过将他眼睛周围区域的像素颜色替换为不同的颜色来解决这一问题。使用与裁剪练习相同的索引操作,我们可以选择为图像的特定部分指定颜色,如下面的代码所示。我们应该先复印一份,这样才能保持原图完好无损。
调整图像大小
要调整图像大小,我们使用cv2.resize()函数。至少,它需要您想要调整大小的图像的名称,以及新图像所需的尺寸(作为元组传入的宽度和高度)。可选参数是宽度和高度的比例因子以及所需的插值类型。
如果要在保持纵横比的同时调整图像大小,请将尺寸作为无传递,然后将宽度和高度比例因子设置为相同的值。
在插值方面,有以下选择
- cv2.INTER_AREA(非常适合缩小图像)
- cv2.INTER_CUBUE(最适合放大图像,但速度较慢)
- cv2.INTER_LINEAR(可以快速放大图像)
当我们观察这三幅图像的形状和大小时,我们可以看到它们的不同之处。
将图像写入文件
最后,我们可以将图像写入文件。为此,我们使用cv2.imwrite()函数。只需指定具有所需扩展名的文件名,如.jpg、.png或.tiff。您可以在此处获得支持的格式列表。您还应该指定映像名称。formats here
这篇文章写得太长了!我真的以为现在已经完成了,但在我写这篇文章的时候,越来越多的关于如何处理它的想法不断涌入我的脑海。所以我决定把它变成一系列的帖子。
我将在这里结束第一部分。期待第2部分,在那里我们将深入研究使用OpenCV进行更高级的图像处理。
您可以在GitHub上访问本文中使用的Jupyter笔记本。here on github
这篇文章中使用的所有照片都是由我埃里克·吉通加(Eric Gitonga)拍摄的。
原创文章,作者:fendouai,如若转载,请注明出处:https://panchuang.net/2021/07/08/opencv%e3%80%81numpy%e5%92%8cstreamlight%e8%b5%b0%e8%bf%9b%e4%b8%80%e5%ae%b6-2/