使用opnecv给证件照换底色!
思路
换底色,比较直接的思路就是把人和背景分离,人保持不变,对背景颜色进行替换。
简单来说就两步:
- 分离人物和背景
- 换背景颜色
RGB颜色空间的局限与HSV颜色空间
RGB颜色空间的局限
RGB 分别为红色®,绿色(G)和蓝色(B)。利用三个颜色分量的线性组合来表示颜色,任何颜色都与这三个分量有关,而且这三个分量是高度相关的,所以连续变换颜色时并不直观,想对图像的颜色进行调整需要更改这三个分量才行。对于某一种颜色,我们很难推测出较为精确的三个分量数值来表示。
HSV颜色空间
HSV 表达彩色图像的方式由三个部分组成:
Hue(色调、色相)
Saturation(饱和度、色彩纯净度)
Value(明度)
色调就是颜色类型,红色、蓝色这种
饱和度可以看做色彩的深浅,例如浅红色和深红色
明度可以看做色彩所占的比例,明度为0时,色彩所占比例为0,整个颜色最后呈现黑色
大多数做图像识别这一块的都会运用HSV颜色空间,因为HSV颜色空间表达起来更加直观
常用底色(红色、白色、蓝色)HSV上下限
颜色 | 下限 | 上限 |
---|---|---|
红色 | [0, 100, 0] | [255, 255, 255] |
蓝色 | [90, 70, 70] | [110, 255, 255] |
白色 | [0, 0, 200] | [180, 30, 255] |
程序过程图片
原图
转化成HSV颜色空间后
把背景填为白色,人像区域填为黑色
进行红色填充
代码
import cv2
import numpy as np
img = cv2.imread("blue_img.jpg")
cv2.imshow("blue", img)
rows, cols, channels = img.shape
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
cv2.imshow("blue_to_red_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("blue_to_red_mask", mask)
# 腐蚀膨胀
erode = cv2.erode(mask, None, iterations=1)
dilate = cv2.dilate(erode, None, iterations=1)
for i in range(rows):
for j in range(cols):
if dilate[i, j] == 255: # 像素点为255表示的是白色,我们就是要将白色处的像素点,替换为红色
img[i, j] = (0, 0, 255) # 此处替换颜色,为BGR通道,不是RGB通道
# 窗口等待的命令,0表示无限等待
cv2.imshow("red", img)
cv2.waitKey(0)