基于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个步骤,便可以成功进行图片的颜色转换,首先来一直效果图