OpenCV最初由英特尔开发,是一个用于实时图像处理的开源计算机视觉跨平台库,它已经成为与计算机视觉应用有关的所有东西的标准工具。2000年,OpenCV的第一个版本被发布;从那时起,它的功能被科学界大大地丰富和简化。后来在2012年,一个非营利性的基金会OpenCV.org 主动为开发者和用户维护了一个支持网站。
它可以在大多数操作系统上使用,如Linux、Windows、Android、iOS和其他一些系统。第一个实现是用C语言编程。然而,该库有一个完整的接口用于其他编程语言,如Python、Java、MATLAB/Octave。此外,其他语言的封装器也被开发出来,以鼓励程序员的采用。
OpenCV的应用涵盖了诸如分割和识别、物体识别、面部识别、运动跟踪、手势识别、图像拼接、高动态范围(HDR)成像、增强现实等领域。此外,它还支持统计机器学习功能等应用领域。今天在这篇文章中,我们将看到使用OpenCV的基本图像处理,我们将使用Python编程语言实现一些过滤器。
使用OpenCV实现各种过滤器
导入所有的依赖性。
要开始使用OpenCV,你需要用以下命令来安装它。在终端窗口或感叹号前的Jupyter笔记本中运行此命令。
! pip install opencv-python
import cv2
import numpy as np
import matplotlib.pyplot as plt
帮助函数。
辅助函数由matplotlib功能组成,用于比较图像。
def compare_image(image1, image2):
plt.figure(figsize=(9,9))
plt.subplot(1,2,1)
plt.imshow(image1)
plt.title('Orignal')
plt.axis('off')
plt.subplot(1,2,2)
plt.imshow(image2)
plt.title('Modified')
plt.axis('off')
plt.tight_layout()
加载图像。
默认情况下,OpenCV读取的是BGR格式的图像,为了看到原始格式的图像,即RGB,我们需要将其转换。
img = cv2.imread('/content/original.jpg')
img2 = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
compare_image(img2,img)
二维卷积。
cv2.filter2D()用于对二维图像进行卷积操作,并使用内核(N x M维矩阵)。用这样的内核进行过滤的结果是:假设你定义了一个10×10的内核,所有落在这个窗口下的像素首先被相乘并求和,结果被除以100,这只不过是像素的平均化,对所有的像素都进行同样的操作。
要了解更多关于卷积操作的信息,请阅读这篇文章。
让我们来实现上述卷积滤波器。
kernel = np.ones((10,10),np.float32)/100
cnv = cv2.filter2D(img2, -1, kernel)
compare_image(img2,cnv)
图像平滑。
图像平滑是通过用不同的滤波器对图像进行卷积来实现的。它对于去除图像中的高频内容如噪声和边缘是很有用的,当这些滤波器被应用时,会产生模糊的边缘。OpenCV有以下四个主要的过滤器。
- 平均法
平均化是通过简单地将图像与一个归一化的盒式滤波器进行卷积来完成的。它取核窗下所有像素的平均值,并用这个平均值替换中心元素。这可以通过以下方式实现。
## Average Filtering
blur = cv2.blur(img2,(10,10))
compare_image(img2,blur)
- 中位数过滤。
cv2.medianBlur()计算内核窗口下所有像素的中值,并用中值替换中心值。这个过滤器被高度用于去除图像中的噪音。为了演示这个滤波器的操作,我们通过使用skimage库在图像中引入了噪声;随后,中值滤波器被应用于噪声图像。
from skimage.util import random_noise
## adding noise
noise_img = random_noise(img2, mode='s&p',amount=0.3)
noise_img = np.array(255*noise_img, dtype = 'uint8')
## median filter
median = cv2.medianBlur(noise_img,5)
compare_image(noise_img,median)
- 双边过滤。
前面的滤波器使图像变得模糊,但双边滤波器倾向于模糊图像,保留物体之间的边缘。此外,在模糊图像的同时,双边滤波器考虑附近的像素强度值,并考虑该像素是否在边缘上;这使得该滤波器的操作有点慢。
在下面的例子中,我们可以看到该过滤器是如何通过保留手机的边缘来模糊图像的。
## bilateral filtering
img = cv2.imread('/content/history_of_mobile_phones.jpg')
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
blur = cv2.bilateralFilter(img,20,200,300)
compare_image(img,blur)
Canny 边缘检测。
Canny边缘检测器是边缘检测操作,它通过多阶段的算法来检测图像中的各种边缘。这个过程包括:将高斯滤波器应用于平滑图像,找到图像的强度梯度,应用梯度大小阈值来摆脱对边缘检测的虚假反应,应用双重阈值来确定潜在的边缘,并通过滞后追踪边缘。
cv2.canny()被用来检测边缘。
## edge detection
park = cv2.imread('/content/new-zealand-parks.jpg')
park = cv2.cvtColor(park,cv2.COLOR_BGR2RGB)
edge = cv2.Canny(park,100,200)
compare_image(park,edge)
等值线。
等高线是连接边界上所有具有相同颜色或强度的连续点的曲线。这是物体检测和形状分析的最有用的工具。
让我们为我们的移动电话寻找轮廓线。
from google.colab.patches import cv2_imshow
## Contours
im = cv2.imread('/content/history_of_mobile_phones.jpg',cv2.IMREAD_COLOR)
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,127,255,cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(im,contours,-1,(0,255,0),3)
cv2_imshow(im)
正如你所看到的,等高线也是为手机的阴影而画的,它甚至可以检测到像素的微小变化。
形态学过滤器。
形态学过滤器是一些基于图像形状的简单操作。这些过滤器需要两个输入:图像和内核,这决定了操作的性质。
- 侵蚀。
它就像土壤侵蚀一样,它侵蚀边界,它警告离开前景物体的边界,也就是说,试图保持前景的白色。因此,该操作是随着内核在图像上的滑动而进行的,只有当内核下的所有像素都是1时,图像的一个像素才被认为是1;否则,它就被侵蚀。
# erosion
img = cv2.imread('/content/kama_ingredients_updated_600x400_0071_banyan_leaf.jpg',0)
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
kernel = np.ones((5,5),np.uint8)
erosion = cv2.erode(img,kernel,iterations=1)
compare_image(img,erosion)
通过执行侵蚀操作,我们可以清楚地看到叶子的所有叶片。
- 扩张。
它与侵蚀正好相反;在这里,如果内核下至少有一个像素是1,则该像素被认为是1,所以在这种情况下,它增加了图像中的白色区域。扩张也有助于连接物体的破碎部分。
# Dilation
dia = cv2.dilate(img,kernel,iterations=1)
compare_image(img,dia)
- 形态学梯度。
它是扩张和侵蚀的区别,其结果看起来像物体的轮廓。
# gradient
grad = cv2.morphologyEx(img,cv2.MORPH_GRADIENT, kernel)
compare_image(img,grad)
结语。
从这篇文章中,我们已经看到了如何加载一个图像。OpenCV以默认的方式读取图像,即以BGR格式读取图像,随后有不同的过滤器,如图像平滑、基本卷积操作、等值线映射、边缘检测、形态学变换。人们可以在现实世界的应用中利用这些过滤器的力量,如侵蚀过滤器可用于以更详细的方式对物体进行可视化。
参考资料。
The postComplete Tutorial on Linear And Non-Linear Filters using OpenCVappeared first onAnalytics India Magazine.