【问题标题】:How can I make the gradient appearance of one image equal to the other?如何使一张图像的渐变外观与另一张图像相同?
【发布时间】:2019-12-27 18:22:37
【问题描述】:

我有一个 图像 A,其中有阴影外观,我有一个纯色的 图像 B。我想在 python 中将图像 A 的阴影从 OpenCV 复制到图像 B。 如果我没记错的话,这与图像的渐变有关吗?

【问题讨论】:

标签: python opencv gradient opencv3.0


【解决方案1】:

您可以使用 ImageMagick 或 Python Wand 轻松做到这一点,或者在 Python/OpenCV 中稍加努力。

注意 Python Wand 使用 ImageMagick。

ImageMagick 已在大多数 Linux 发行版上可用,并且可用于 Windows 和 Mac OSX。

过程是将图像B转换为灰度,然后使用强光合成方法将其与图像A合成。

图片A:

图片B:

使用 ImageMagick(Unix 语法),代码将是:

convert skirt_A.png \
\( skirt_B.png -colorspace gray -level 25x100% \) \
-compose hardlight -composite skirt_A_shaded.png

图像 A 与图像 B 的阴影:

在级别运算符中更改 0.25 以使阴影更暗或更亮。

使用 Python Wand 代码如下:

from wand.image import Image
from wand.display import display

with Image(filename='skirt_A.png') as bimg:
    with Image(filename='skirt_B.png') as fimg:
        fimg.transform_colorspace('gray')
        fimg.level(black=0.25,white=1,channel='all_channels')
        bimg.composite_channel('all_channels', fimg, 'hard_light', 0, 0)
        bimg.save(filename='skirt_A_shaded.png')
        display(bimg)

图像 A 与图像 B 的阴影:

使用 Python/OpenCV,代码将是:

import cv2
import numpy as np

# read image_A and convert to float in range 0 to 1
image_A = cv2.imread('skirt_A.png').astype("float32") / 255.0

# read image_B as grayscale and convert to float in range 0 to 1
image_B = cv2.imread('skirt_B.png',0).astype("float32") / 255.0

# convert image_B from grayscale to 3 equal channels as rgb so that the image multiplication in the hard light compositing will work properly
image_B = cv2.cvtColor(image_B,cv2.COLOR_GRAY2RGB) 

# apply linear transform to stretch image_B to make shading darker
# y = A*x+B
# x=1 -> y=1; x=0.25 -> y=0
# 1 = A + B
# 0 = 0.25*A + B
# Solve simultaneous equations to get:
# A = 1.33
# B = -0.33
image_B = 1.33 * image_B -0.33

# threshold image_B and invert
thresh = cv2.threshold(image_B,0.5,1,cv2.THRESH_BINARY)[1]
thresh_inv = 1-thresh

# do hard light composite and convert to uint8 in range 0 to 255
# see CSS specs at https://www.w3.org/TR/compositing-1/#blendinghardlight
low = 2.0 * image_A * image_B
high = 1 - 2.0 * (1-image_A) * (1-image_B)
result = ( 255 * (low * thresh_inv + high * thresh) ).clip(0, 255).astype(np.uint8)

# show results
cv2.imshow('Result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

# save results
cv2.imwrite('skirt_A_shaded.png', result)

图像 A 与图像 B 的阴影:

【讨论】:

  • 我们如何确定 x 和 y 的值?您在线性变换中选择了 (1,1) 和 (0,.25)。 @fmw42
  • 只需根据需要调整它并查看您的结果。找到适合您的合理价值。我尝试将它从 0 增加 0.05 增量,直到它看起来像你的 image_B。您需要做的就是将 0.25 更改为其他值,并同时进行求解以获得 A 和 B 常数。您也可以只编写方程式以使用值 0.25 或其他值,并让 Python 计算 A 和 B 常量。解决y=A*x+B with 1 = A + B (so that A = 1-B) and 0 = A*c + B. The solution is B=-c/(1-c) and A=1-B=1+c/(1-c) where c is between 0 and 1 and I had used c=0.25
  • 谢谢@fmw42。它运行良好。但它会稍微扭曲实心图像的颜色。我想我必须根据系数进行调整,即 A 和 B。
  • 问题是图像在任何地方都被修改后的 image_B 以灰度形式修改,其中不完全是 50% 灰度。需要进一步调整以使其大部分变为 50% 灰色,而阴影仅更暗。这并不容易。您可以尝试调整 A 和 B 常数,这可能会有所帮助。尝试使用 0.20 而不是 0.25 以使结果更轻一些。根据需要进行调整。
猜你喜欢
  • 2013-09-04
  • 1970-01-01
  • 2011-01-29
  • 1970-01-01
  • 1970-01-01
  • 2016-11-23
  • 2019-04-22
  • 2011-05-21
  • 1970-01-01
相关资源
最近更新 更多