是否厌倦了千篇一律的图片效果?想要给照片添加一些酷炫的特效和有趣的滤镜吗?无论是滑稽的狗脸滤镜、巨大的胡子,还是牛仔帽或酷炫的护目镜,正确的滤镜和贴纸都能让最无聊的照片变得有趣。从Snapchat和Instagram滤镜在网民中的日益流行可以看出人们对滤镜的热爱!
如果能完全自己构建一个这样的滤镜,那会怎样?是的,可以轻松构建并根据选择定制它!听起来很有趣,对吧!那么让开始吧。将借助OpenCV来制作自己的滤镜,给赫敏·格兰杰小姐戴上一副酷炫的太阳镜!
OpenCV是什么?在深入代码之前,让了解什么是OpenCV。OpenCV是一个非常有用的开源Python库,主要处理实时计算机视觉、机器学习和图像处理。OpenCV拥有众多功能,可以用来识别对象、识别面部特征、处理图像和视频,甚至修改它们。
OpenCV的应用领域众多,包括面部检测、图像/视频搜索和检索、无人驾驶汽车导航、医学图像分析、互动艺术装置等。现在已经用OpenCV解锁了计算机视觉的大门!是时候进一步探索了。为了构建Snapchat滤镜,将专注于使用Haar Cascade分类器进行面部特征检测。
让开始编码。将需要三个主要的库:Numpy、Matplotlib和OpenCV。
import numpy as np
import matplotlib.pyplot as plt
import cv2
现在将使用一些Haar Cascades。Haar Cascades是最受欢迎的对象检测算法之一。它利用各种特征,如边缘特征、线特征和中心-环绕特征,在图像中定位相似的模式,从而识别对象。例如,嘴唇的边缘通常与嘴唇的侧面相比更为明显,因此可以使用水平边缘特征。类似地,可以使用垂直边缘特征来检测鼻子的鼻梁。
现在知道了Haar Cascades是什么,让使用一个cascade来帮助检测图像中的前向眼睛。需要先下载Haar cascades。可以从下载。
eye_cascade = cv2.CascadeClassifier("frontalEyes35x16.xml")
现在让读取图像。将读取赫敏·格兰杰的图片并给她戴上一副酷炫的护目镜!在使用OpenCVPython时,以numpy ndarray的形式存储图像。
img = plt.imread("Hermione1.jpg")
plt.imshow(img)
现在得到了上面的输出。现在让显示原始图像的图像形状。由于图像已经以numpy ndarray的形式存储,现在可以使用ndarray.shape来获取图像的尺寸。这可以通过以下代码完成:
img.shape
输出:(487, 586, 3)。输出(487, 586, 3)分别代表图像的高度、宽度和通道数。
还必须创建原始图像的副本并将其存储为img1以显示最终结果。
img1 = img.copy()
现在,将使用前面定义的eye_cascade对象和detectMultiScale()方法来识别图像中的眼睛。将输入图像作为参数。这将帮助在图像中定位眼睛对。
eye = eye_cascade.detectMultiScale(img)[0]
print(eye)
输出:[221, 130, 134, 61]。这以(x,y,w,h)的格式返回眼睛的位置。这里x代表左下角的X坐标,y代表左下角的Y坐标,w代表眼睛区域的宽度,h代表眼睛区域的高度。
然后将获得的数据存储在四个不同的变量中,如下所示。一旦检测到眼睛的位置,将在初始图像上绘制一个矩形以可视化结果。这可以通过调用cv2.rectangle方法并传递眼睛的坐标、矩形的颜色和宽度作为参数来完成。
eye_x, eye_y, eye_w, eye_h = eye
img = cv2.rectangle(img, (eye_x, eye_y), (eye_x + eye_w, eye_y + eye_h), (255, 255, 255), 5)
plt.imshow(img)
现在将读取眼镜的图像并将其存储在一个变量中。然后检查输入图像的大小,如下所示。
glasses = plt.imread("sample1.png")
glasses.shape
输出:(200, 200, 4)。观察到眼镜的大小和赫敏的图像是成比例的,因此必须调整眼镜的大小以使其完美适合赫敏!让这样做并根据之前获得的眼睛坐标调整图像的大小。
可能需要一些试错来调整值以适应图像。这些是为图像提供最佳结果的值。
glasses = cv2.resize(glasses, (eye_w + 50, eye_h + 55))
glasses.shape
输出:(116, 184, 4)。
现在是最后一步!由于不希望在最终图像上检测到眼睛的矩形,将处理之前创建的副本图像‘img1’。现在已经获得了眼镜的坐标,只需要用眼镜的像素替换赫敏图像的像素。为此使用2个for循环。如果眼镜图像上的像素是0,这意味着希望该部分是透明的,所以不替换那个像素。在所有其他情况下,只需在所需位置用眼镜的像素替换图像的像素。
for i in range(glasses.shape[0]):
for j in range(glasses.shape[1]):
if (glasses[i, j, 3] > 0):
img1[eye_y + i - 20, eye_x + j - 23, :] = glasses[i, j, :-1]
plt.imshow(img1)
瞧!成功地给格兰杰小姐戴上了一副酷炫的眼镜!