基于OpenCv的快速图片颜色交换,轻松实现图片背景更换
图片颜色更换
图片颜色转换
当我们有2张图片,很喜欢第一张图片的颜色,第2张图片的前景照片,很多时候我们需要PS进行图片的颜色转换,这当然需要我们有强大的PS功底,当然小编这里不是介绍PS的,我们使用代码完全可以代替PS 进行图片的颜色转换
图片颜色转换步骤:
· 步骤1: 输入source和target 2张图片
· 步骤2: 将source和target图像都转换为L * a * b *颜色空间什么是LAB 颜色空间,我们在讨论物体颜色追踪时有讨论,可以参考此部分的文章分享
· 步骤3: 为source和target图像计算每个L * a * b *通道的平均值和标准差。
· 步骤4:从target通道中 减去target图像的L * a * b *通道的平均值。
· 第5步:按标准偏差target除以source的标准偏差乘以LAB通道 缩放target 通道。
· 步骤6: 加上source图片L * a * b *通道的均值。
· 步骤7: 裁剪掉[0,255]范围之外的所有值。
· 步骤8: 合并LAB空间。
· 步骤9: 从L * a * b *空间转换回RGB颜色空间。
· 步骤10:显示图片
python代码实现图片颜色更换
有了以上步骤,我们采用python代码进行实现:
在正式进入主函数前,我们首先建立2个函数,一个用来计算图片在LAB空间内的均值与方差
一个用来显示图片(这里主要是resize图片,避免有些图片太大无法在屏幕上完全显示,当然,这个函数你可以完全不用,直接使用imshow函数来显示图片即可)
import numpy as np
import cv2
# 建立图片LAB空间均值与方差计算函数
def image_info(image):
(l, a, b) = cv2.split(image)
(lMean, lStd) = (l.mean(), l.std())
(aMean, aStd) = (a.mean(), a.std())
(bMean, bStd) = (b.mean(), b.std())
return (lMean, lStd, aMean, aStd, bMean, bStd)
# resize 图片并显示
def show_image(title, image, width = 300):
r = width / float(image.shape[1])
dim = (width, int(image.shape[0] * r))
resized = cv2.resize(image, dim, interpolation = cv2.INTER_AREA)
cv2.imshow(title, resized)
代码截图
按照步骤
# 1 加载图片
source_img = cv2.imread('11.png')
target_img = cv2.imread('13.png')
# 2 转换颜色空间到LAB
source = cv2.cvtColor(source_img, cv2.COLOR_BGR2LAB).astype("float32")
target = cv2.cvtColor(target_img, cv2.COLOR_BGR2LAB).astype("float32")
# 3计算图片LAB空间的均值与方差
(lMeanSrc, lStdSrc, aMeanSrc, aStdSrc, bMeanSrc, bStdSrc) = image_info(source)
(lMeanTar, lStdTar, aMeanTar, aStdTar, bMeanTar, bStdTar) = image_info(target)
# 4 从target LAB通道中 减去target图像的L * a * b *通道的平均值
(l, a, b) = cv2.split(target)
l -= lMeanTar
a -= aMeanTar
b -= bMeanTar
# 5 按标准偏差target图片除以source图片的标准偏差乘以LAB通道 缩放target 通道
l = (lStdTar / lStdSrc) * l
a = (aStdTar / aStdSrc) * a
b = (bStdTar / bStdSrc) * b
# 6 加上source图片L * a * b *通道的均值
l += lMeanSrc
a += aMeanSrc
b += bMeanSrc
代码截图
# 7 裁剪掉[0,255]范围之外的所有值
l = np.clip(l, 0, 255)
a = np.clip(a, 0, 255)
b = np.clip(b, 0, 255)
# 8 合并LAB空间
transfer = cv2.merge([l, a, b])
# 9 转换颜色空间到BGR
transfer = cv2.cvtColor(transfer.astype("uint8"), cv2.COLOR_LAB2BGR)
# 10 显示图片
show_image("Source", source_img)
show_image("Target", target_img)
show_image("Transfer", transfer)
cv2.waitKey(0)
代码截图
按照以上10个步骤,便可以成功进行图片的颜色转换,首先来一直效果图