传统图像处理——颜色迁移

转自知乎:https://zhuanlan.zhihu.com/p/267832794,仅供学习。

利用一张图片的颜色去修改另一张图片的颜色风格。

原理是利用颜色空间的正交化,即更改某个颜色,不会影响到其它属性。这里的色彩迁移的论文则是使用了LAB空间RGB颜色空间是非正交化空间)。

这里使用python3.7.6+opencv4.4.0实现。

选用优化后的算法效率提升很大。

颜色迁移

  • 1.先将图像转换为LAB格式:
img=cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
  • 2.再将源图像的均值和方差变换到目标颜色图像的均值和方差

(1) : 源图像的LAB分别进行零均值和单位方差化

x_mean, x_std = cv2.meanStdDev(img)
x_mean = np.hstack(np.around(x_mean, 2))
x_std = np.hstack(np.around(x_std, 2))

(2) 然后归一化后的原图像各通道乘以目标色图像的LAB各通道方差,再加上目标色图像的LAB各通道均值

height, width, channel = img.shape
for i in range(0, height):
	for j in range(0, width):
		for k in range(0, channel):
			x = sc[i, j, k]
			x = ((x - s_mean[k]) * (t_std[k] / s_std[k])) + t_mean[k]
			# round or +0.5
			x = round(x)
			# boundary check
			x = 0 if x < 0 else x
			x = 255 if x > 255 else x
			sc[i, j, k] = x

(3).最后再将图像转换为RGB格式:

cv2.cvtColor(res, cv2.COLOR_LAB2BGR)

下面演示颜色迁移效果:

传统图像处理——颜色迁移_第1张图片
4种待借鉴的颜色风格
传统图像处理——颜色迁移_第2张图片
4种迁移的效果图像
传统图像处理——颜色迁移_第3张图片
速度慢源码:

def get_mean_and_std(img):
   x_mean, x_std = cv2.meanStdDev(img)
   x_mean = np.hstack(np.around(x_mean, 2))
   x_std = np.hstack(np.around(x_std, 2))
   return x_mean, x_std

def color_transfer(sc, dc):
   sc = cv2.cvtColor(sc, cv2.COLOR_BGR2LAB)
   s_mean, s_std = get_mean_and_std(sc)
   dc = cv2.cvtColor(dc, cv2.COLOR_BGR2LAB)
   t_mean, t_std = get_mean_and_std(dc)
   height, width, channel = sc.shape
   for i in range(0, height):
      for j in range(0, width):
         for k in range(0, channel):
            x = sc[i, j, k]
            x = ((x - s_mean[k]) * (t_std[k] / s_std[k])) + t_mean[k]
            # round or +0.5
            x = round(x)
            # boundary check
            x = 0 if x < 0 else x
            x = 255 if x > 255 else x
            sc[i, j, k] = x
   dst = cv2.cvtColor(sc, cv2.COLOR_LAB2BGR)
   return dst

sc = cv2.imread("sc.bmp", 1)
dc = cv2.imread("sc.bmp", 1)
dst = color_transfer(sc, dc)
cv2.imshow("dst", dst)
cv2.waitKey()

后由小伙伴优化了算法,经测试速度灰常快,感谢这位小伙伴:

import cv2
import numpy as np
import time


def get_mean_and_std(img):
	x_mean, x_std = cv2.meanStdDev(img)
	x_mean = np.hstack(np.around(x_mean, 2))
	x_std = np.hstack(np.around(x_std, 2))
	return x_mean, x_std

def color_transfer(sc, dc):
	sc = cv2.cvtColor(sc, cv2.COLOR_BGR2LAB)
	s_mean, s_std = get_mean_and_std(sc)
	dc = cv2.cvtColor(dc, cv2.COLOR_BGR2LAB)
	t_mean, t_std = get_mean_and_std(dc)
	img_n = ((sc-s_mean)*(t_std/s_std))+t_mean
	np.putmask(img_n, img_n > 255, 255)
	np.putmask(img_n, img_n < 0, 0)
	dst = cv2.cvtColor(cv2.convertScaleAbs(img_n), cv2.COLOR_LAB2BGR)
	return dst

sc = cv2.imread("s1.bmp", 1)
dc = cv2.imread("t1.jpg", 1)
dst = color_transfer(sc, dc)
cv2.imshow("dst", dst)
cv2.waitKey()

参考大佬的python源代码:https://github.com/chia56028/Co

你可能感兴趣的:(深度学习,图像分类,图像处理,计算机视觉,python)