OpenCV是一个开源的图像处理和计算机视觉库,它支持多种编程语言,包括Python、Java和C++。本文将重点介绍Python语言中的OpenCV应用。这个库提供了数百个有用的函数和算法,这些函数和算法都是免费提供的。其中一些函数非常常见,几乎在每个计算机视觉任务中都会用到,而许多其他函数尚未被充分探索和关注。
在开始之前,了解一些OpenCV的基础知识会很有帮助。这通常只需要十到十五分钟的时间。应该学会如何使用OpenCV读取和写入图像,了解OpenCV中存在的不同颜色空间以及如何将它们相互转换。此外,还需要知道如何创建NumPy数组,并熟悉NumPy的基本操作。虽然这些知识很有帮助,但即使不了解这些,也不妨碍理解本文的内容。
本文将介绍四个应用案例:去除图像中的水印、移除图像背景、创建图像滤镜和将任何图像卡通化。
水印可能非常烦人,每个人在生活中都可能需要从互联网上寻找去除水印的方法。幸运的是,使用OpenCV,可以轻松完成这项任务,而且代码行数不到10行。首先导入所需的库(OpenCV和NumPy),然后读取包含水印的图像。接着,将颜色空间从BGR转换为HSV。使用HSV颜色格式是因为它能更好地帮助获得掩模图像,这是下一步将要创建的。掩模图像是一个只有黑白两种值的图像。掩模的目的是只对图像的特定部分应用更改。对于目的,掩模图像应该在水印所在的位置显示白色值,其他地方则显示黑色。
为了创建掩模图像,将使用阈值处理,已经为这张图像完成了阈值处理。阈值处理的作用是判断一个值是否在给定的范围内。如果想使用其他图像,可以使用以下代码片段找到自己的阈值。现在,已经拥有了掩模图像,可以调用主要的函数来执行这项任务。将在掩模图像上使用cv2.inpaint()函数来去除水印。这个函数实际上允许使用一种称为图像修复的方法来移除图像中的小噪声。
import cv2
import numpy as np
img = cv2.imread('path') # 替换为图像路径
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
l_b = np.array([0,0,220])
u_b = np.array([255,255,255])
mask = cv2.inRange(hsv, l_b, u_b)
dst = cv2.inpaint(img, mask, 5, cv2.INPAINT_TELEA)
# dst = cv2.inpaint(img, mask, 5, cv2.INPAINT_NS)
可以检查上面的结果图像。图像修复函数工作得很好。如果认为需要更好的结果,可以尝试调整阈值。也可以使用高斯模糊等方法来提高掩模图像的质量。
在处理图像时,背景噪声非常常见。通过使用OpenCV的这个函数,可以从图像中提取有用信息并丢弃背景中的任何内容。一个好处是,它允许输入最终图像的输出形状,这样就不必猜测图像的大小。对于这项任务,将使用给定的图像。任务是移除背景并提取图像中的前景(例如笔记本)。将使用的函数需要两组点。第一组将包含4个点,这些点将覆盖前景区域。在上面的图像中,如果仔细观察,将能够看到4个点。第一组将是这些点的坐标。另一组点将是输出图像的边界点。之后,将使用cv2.getPerspective()函数,它将给输出矩阵,而cv2.warpPerspective函数将把这个矩阵转换成所需的形状。
import cv2
import numpy as np
img = cv2.imread('notebook.jpeg') # 替换为图像路径
pts1 = np.float32([[57, 49], [419, 45], [414, 477], [56, 475]])
pts2 = np.float32([[0,0], [img.shape[0],0], [img.shape[0],img.shape[1]], [0,img.shape[1]]])
matrix = cv2.getPerspectiveTransform(pts1, pts2)
result = cv2.warpPerspective(img, matrix, (512,512))
cv2.imshow("result", result)
cv2.waitKey(0)
可以检查上面的结果图像。
与文本数据不同,图像可以用来提取多个特征。这些特征突出了图像的属性。可以使用这些特征来模糊图像、锐化图像、从图像中提取边缘等。为了执行这项任务,将使用卷积的概念。卷积基本上是将核应用于图像上每个像素的过程。核?核是一个由数字组成的小矩阵,这些数字通常总和为1。根据核的值,可以从图像中提取多个特征。
在这项任务中,将简单地使用卷积来模糊图像。将使用下面的滤波器(核)来完成任务。这个核也被称为平均滤波器。顾名思义,它平均周围的像素并将值分配给中心像素。甚至可以选择喜欢的不同的值,只要确保所有值的总和为1。
import cv2
import numpy as np
img = cv2.imread('path') # 替换为图像路径
kernel = np.array([[1,1,1], [1,1,1], [1,1,1]])
kernel = kernel/9
res = cv2.filter2D(img, -1, kernel)
cv2.imshow("img", res)
cv2.waitKey(0)
可以通过这个找到更多惊人的滤镜,可以应用到最喜欢的图像上。
每个人都喜欢卡通,当可以用最喜欢的图片制作一个卡通时,这岂不是更好。使用OpenCV,可以轻松地使用一些非常基本的函数来完成这项任务。基本上,整个过程包括三个步骤:从图像中提取边缘、对输入图像应用图像平滑、将步骤1和2的结果相加。
首先读取图像并将其转换为灰度。可以使用这个灰度版本的图像,并将其输入到cv2.adaptiveThreshold函数中以获得图像的边缘。甚至可以使用前面的应用来从图像中提取边缘。然后需要对图像进行平滑处理。图像平滑是指制作一个像素较少的图像版本。用更简单的话说,只是在减少图像中不同像素的数量。这可以通过使用OpenCV中存在的双边滤波器函数来实现。然后只需将平滑后的图像和边缘使用OpenCV中的‘bitwise_and’操作符相加,就可以得到卡通图像。
import cv2
import numpy as np
img = cv2.imread("images/lena.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5,5), -1)
edges = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 9, 10)
color = cv2.bilateralFilter(img, 20, 245, 245)
cartoon = cv2.bitwise_and(color, color, mask=edges)
cv2.imshow("cartoon", cartoon)
cv2.waitKey(0)
可以在中间添加更多步骤来增强结果,比如改变颜色空间,使用不同的滤镜等。
OpenCV是计算机视觉社区的重要组成部分,使用它可以构建成千上万的惊人应用。可能已经认为其中一些应用是日常生活中使用的。最后一次使用Cam Scanner扫描作业副本是什么时候?认为第二个应用可能在其中扮演了角色吗?创建的卡通图像是否看起来有点像Snapchat版本的图像?通过这些应用,目的是鼓励使用像OpenCV这样的简单高效的工具来探索解决现实生活问题的方法。
本文介绍的应用只是冰山一角。当开始深入计算机视觉领域时,将了解到更多有趣和惊人的概念。将学习到解决复杂问题的深度学习方法。将学习到预训练模型,这些模型可以为大量问题提供出色的结果。将训练自己的模型,创建数据集,并找到解决最初看起来不切实际的问题的方案。