这是我参与更文挑战的第5天,活动详情查看: 更文挑战
OpenCV是一个C++库,目前流行的计算机视觉编程库,用于实时处理计算机视觉方面的问题,它涵盖了很多计算机视觉领域的模块。在Python中常使用OpenCV库实现图像处理。
本文将介绍如何在Python3中使用OpenCV实现对证件照的背景更换:
参考: Opencv4 官方文档 : docs.opencv.org/4.2.0/
生活中,我们常需要各种背景的证件照满足各种场合的需求,如蓝底,白底,红底等,但是大部分情况我们只有其中一种,所以作为一名技术人,我们可以通过使用技术手段进行背景替换。
证件照背景更换过程如下:
- 图像缩放
- 图片转换为HSV灰度图
- 图片二值化处理
- 腐蚀膨胀
- 背景变换
- 图像缩放
图像缩放
适当缩放图片可以有效减少代码程序计算量。
具体实现代码如下:
img = cv2.imread('E:\\demo\\linda.png')
img = cv2.resize(img, None, fx=0.3, fy=0.3)
rows, cols, channels = img.shape
cv2.imshow('input', img)
输出为:
图片转换为HSV灰度图
H-色调(主波长):色调是指图像的相对明暗程度,在彩色图像上表现为颜色。S-饱和度(纯度/颜色的阴影):饱和度是指色彩的鲜艳程度,也称色彩的纯度。V值(强度):就是每个通道的图像的像素灰度值。
原图转换为hsv灰度图更利于背景的识别。
具体实现代码如下:
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
cv2.imshow('hsv', hsv)
输出为:
图片二值化处理
图片的二值化处理,可能会出现噪声(白点),有的图片显示的很明显,这就需要我们进行腐蚀或膨胀。
具体代码如下:
lower_blue = np.array([90, 70, 70])
upper_blue = np.array([110, 255, 255])
mask = cv2.inRange(hsv, lower_blue, upper_blue) # 蓝色范围内变白,其余之外全部变黑
输出为:
腐蚀膨胀
去除图片中的噪点。
具体代码如下:
erode = cv2.erode(mask, None, iterations=1)
dilate = cv2.dilate(mask, None, iterations=1)
cv2.imshow('dilate', dilate)
输出为:
背景变换
遍历每个像素点,进行颜色的替换。
具体代码如下:
for i in range(rows):
for j in range(cols):
if dilate[i, j] == 255: # 像素点为255表示的是白色,此处将白色处的像素点替换为红色
img[i, j] = (0, 0, 255)
cv2.imshow('output', img)
输出为:
纯白色背景代码:
for i in range(rows):
for j in range(cols):
if dilate[i, j] == 255: # 像素点为255表示的是白色,此处将白色处的像素点替换为红色
img[i, j] = (255, 255, 255)
cv2.imshow('output', img)
输出为:
全部代码
import cv2
import numpy as np
img = cv2.imread('E:\\demo\\linda.png')
img = cv2.resize(img, None, fx=0.3, fy=0.3)
rows, cols, channels = img.shape
#print(rows, cols, channels)
cv2.imshow('input', img)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
cv2.imshow('hsv', hsv)
lower_blue = np.array([90, 70, 70])
upper_blue = np.array([110, 255, 255])
mask = cv2.inRange(hsv, lower_blue, upper_blue) # 蓝色范围内变白,其余之外全部变黑
cv2.imshow('mask', mask)
erode = cv2.erode(mask, None, iterations=1)
dilate = cv2.dilate(mask, None, iterations=1)
cv2.imshow('dilate', dilate)
for i in range(rows):
for j in range(cols):
if dilate[i, j] == 255: # 像素点为255表示的是白色,此处将白色处的像素点替换为红色
img[i, j] = (135,206,250)
cv2.imshow('output', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
本月将陆续推出相关系列文章,
篇篇精彩,尽请关注。