【Python3-OpenCV】实现图像处理—证件照背景更换篇

2,142 阅读3分钟

这是我参与更文挑战的第5天,活动详情查看: 更文挑战

OpenCV是一个C++库,目前流行的计算机视觉编程库,用于实时处理计算机视觉方面的问题,它涵盖了很多计算机视觉领域的模块。在Python中常使用OpenCV库实现图像处理。

image.png

本文将介绍如何在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)

输出为:

image.png

图片转换为HSV灰度图

  • H-色调(主波长):色调是指图像的相对明暗程度,在彩色图像上表现为颜色。
  • S-饱和度(纯度/颜色的阴影):饱和度是指色彩的鲜艳程度,也称色彩的纯度。
  • V值(强度):就是每个通道的图像的像素灰度值。

原图转换为hsv灰度图更利于背景的识别。

具体实现代码如下:

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
cv2.imshow('hsv', hsv)

输出为:

image.png

图片二值化处理

图片的二值化处理,可能会出现噪声(白点),有的图片显示的很明显,这就需要我们进行腐蚀或膨胀。

具体代码如下:

lower_blue = np.array([90, 70, 70])
upper_blue = np.array([110, 255, 255])
mask = cv2.inRange(hsv, lower_blue, upper_blue)  # 蓝色范围内变白,其余之外全部变黑

输出为:

image.png

腐蚀膨胀

去除图片中的噪点。

具体代码如下:

erode = cv2.erode(mask, None, iterations=1)
dilate = cv2.dilate(mask, None, iterations=1)
cv2.imshow('dilate', dilate)

输出为:

image.png

背景变换

遍历每个像素点,进行颜色的替换。

具体代码如下:

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)

输出为:

image.png

纯白色背景代码:

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)

输出为:

image.png

全部代码

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()

本月将陆续推出相关系列文章,

篇篇精彩,尽请关注。