opencv 应用线性透明渐变到图像的一部分与透明的背景在python

6bc51xsx  于 2022-12-23  发布在  Python
关注(0)|答案(3)|浏览(604)

我需要应用线性透明渐变到只有底部的5%的图像。我有一些想法,首先我需要创建阿尔法通道上的蒙版。但我不知道我如何才能做到这一点,只影响底部的5%的图像。我已经尝试了不同的方法芽没有运气到目前为止。梯度应该开始在5%的图像高度在100%阿尔法和0%阿尔法结束。此外,图片可以是非矩形PNG与透明背景。我真的很感激任何帮助。谢谢。Here是我需要的一个例子。但它可以是一个矩形或非矩形的图像。

k75qkfdt

k75qkfdt1#

下面是如何在ImageMagick 7中实现这一点,无论你是否在输入中有一个现有的alpha通道。它略有不同。你基本上是从输入中提取alpha通道,并将其与包含梯度的通道相乘。然后将新的通道放入原始图像中,替换现有的alpha通道。
输入:

magick lena_circle.png \
-alpha set \
-set option:wd "%w" \
-set option:ht "%h" \
-set option:ht2 "%[fx:round(0.25*ht)]" \
-set option:ht3 "%[fx:ht-ht2]" \
\( -size "%[wd]x%[ht3]" xc:white \) \
\( -size "%[wd]x%[ht2]" gradient:white-black \) \
\( -clone 1,2 -append \) \
-delete 1,2 \
\( -clone 0 -alpha extract \) \
\( -clone 1,2 -compose multiply -composite \) \
-delete 1,2 \
-alpha off -compose copy_opacity -composite \
lena_circle_fade3.png

生成图像:

q35jwt9p

q35jwt9p2#

下面是在Python/OpenCV/Numpy中对不透明图像执行此操作的一种方法。

- Read the input
 - Compute top and bottom heights for the alpha channel
 - Create a constant white image for top
 - Create a vertical gradient going from 255 to 0 for the bottom
 - Stack the top and bottom parts
 - Convert the image to 4 channels BGRA
 - Replace the alpha in the BGRA image with the stacked alpha
 - Save the result

输入:

import cv2
import numpy as np

# read image
img = cv2.imread("lena.png")
ht, wd = img.shape[:2]

# compute 5% of ht and 95% of ht
# pct = 5
pct = 25    # temparily set pct to 25 percent for demonstration
ht2 = int(ht*pct/100)
ht3 = ht - ht2

# create opaque white image for top
top = np.full((ht3,wd), 255, dtype=np.uint8)

# create vertical gradient for bottom
btm = np.linspace(255, 0, ht2, endpoint=True, dtype=np.uint8)
btm = np.tile(btm, (wd,1))
btm = np.transpose(btm)

# stack top and bottom
alpha = np.vstack((top,btm))

# put alpha channel into image
result = img.copy()
result = cv2.cvtColor(result, cv2.COLOR_BGR2BGRA)
result[:,:,3] = alpha

# save result
cv2.imwrite('lena_fade.png', result)

# display results
# (note: display does not show transparency)
cv2.imshow('btm', btm)
cv2.imshow('alpha', alpha)
cv2.imshow('result', result)
cv2.waitKey(0)

结果:

    • 增补**

下面是如何在ImageMagick 7中实现这一点。

magick lena.png \
-set option:wd "%w" \
-set option:ht "%h" \
-set option:ht2 "%[fx:round(25*ht/100)]" \
-set option:ht3 "%[fx:ht-ht2]" \
\( -size "%[wd]x%[ht3]" xc:white \) \
\( -size "%[wd]x%[ht2]" gradient:white-black \) \
\( -clone 1,2 -append \) \
-delete 1,2 \
-alpha off -compose copy_opacity -composite \
lena_fade2.png

生成图像:

e5nqia27

e5nqia273#

如果图像已经具有透明度,下面是如何在Python/OpenCV中实现这一点。需要提取图像alpha,为渐变创建一个新的alpha,然后将两个alpha通道相乘。最后将新的alpha放入原始图像中,替换旧的alpha。
输入:

import cv2
import numpy as np

# read image
img = cv2.imread("lena_circ.png", cv2.IMREAD_UNCHANGED)
ht, wd = img.shape[:2]

# extract the BGR component and the alpha component
bgr_circ = img[:,:,0:3]
alpha_circ = img[:,:,3]

# compute 5% of ht and 95% of ht
# pct = 5
pct = 50    # temparily set pct to 50 percent for demonstration
ht2 = int(ht*pct/100)
ht3 = ht - ht2

# create opaque white image for top
top = np.full((ht3,wd), 255, dtype=np.uint8)

# create vertical gradient for bottom
btm = np.linspace(255, 0, ht2, endpoint=True, dtype=np.uint8)
btm = np.tile(btm, (wd,1))
btm = np.transpose(btm)

# stack top and bottom
alpha = np.vstack((top,btm))

# multiply alpha and alpha_circ
alpha_new = (alpha * alpha_circ.astype(np.float64) / 255).clip(0,255).astype(np.uint8)

# put alpha channel into image
result = bgr_circ.copy()
result = cv2.cvtColor(result, cv2.COLOR_BGR2BGRA)
result[:,:,3] = alpha_new

# save result
cv2.imwrite('lena_circ_fade.png', result)

# display results
# (note: display does not show transparency)
cv2.imshow('btm', btm)
cv2.imshow('alpha', alpha)
cv2.imshow('alpha_circ', alpha_circ)
cv2.imshow('alpha_new', alpha_new)
cv2.imshow('result', result)
cv2.waitKey(0)

结果:

相关问题