cv2.blur 中的深色边框
Dark borders in cv2.blur
我在 python 上有这段代码,我在我的游戏中使用它作为 Bloom 效果,但我注意到它在粒子周围有这个奇怪的黑色阴影
效果是这样的^
大家可以看到,颗粒上有一些阴影,白底很明显,灰底则很细微
我想知道有没有办法remove/reduce这个奇怪的效果
这是绽放的代码(阴影来自哪里):
def Bloom(canvas: pygame.Surface):
size = canvas.get_size()
canvas_color = pygame.surfarray.array2d(canvas)
canvas_rgba = canvas_color.view(dtype=np.uint8).reshape((*canvas_color.shape, 4))
newCanvas = pygame.Surface(size, pygame.SRCALPHA)
cv2.blur(canvas_rgba, ksize=(9, 9), dst=canvas_rgba)
pygame.surfarray.blit_array(newCanvas, canvas_color)
return newCanvas
任何帮助都会很棒:3
编辑:删除了黑色背景的图像(没有理由在那里)
问题不在于“绽放”算法,而在于你 blit
表面到目标的方式。
不仅 alpha 通道模糊,颜色通道也模糊。因此你必须 blit
带有特殊标志 BLEND_PREMULTIPLIED
:
的 Surface
bloom_surf = Bloom(source_surf)
screen.blit(bloom_surf, (x, y), pygame.BLEND_PREMULTIPLIED)
也可以在 Bloom
函数中通过将颜色通道除以 alpha 通道来取消此效果:
r' = r / a
g' = g / a
b' = b / a
a' = a
每个颜色通道都在 [0, 255] 范围内的一个字节中编码。这使得转换有点棘手:
def BloomNoPremultipliedAlpha(canvas: pygame.Surface):
size = canvas.get_size()
canvas_color = pygame.surfarray.array2d(canvas)
canvas_rgba = canvas_color.view(dtype=np.uint8).reshape((*canvas_color.shape, 4))
newCanvas = pygame.Surface(size, pygame.SRCALPHA)
cv2.blur(canvas_rgba, ksize=(25, 25), dst=canvas_rgba)
canvas_rgba[:,:,0:3] = canvas_rgba[:,:,0:3] * 255.0 / canvas_rgba[:,:,[3,3,3]]
pygame.surfarray.blit_array(newCanvas, canvas_color)
return newCanvas
请参阅以下演示差异的最小示例:
左:Bloom
;中心:Bloom
+ BLEND_PREMULTIPLIED
;右:BloomNoPremultipliedAlpha
import pygame, cv2
import numpy as np
def Bloom(canvas: pygame.Surface):
size = canvas.get_size()
canvas_color = pygame.surfarray.array2d(canvas)
canvas_rgba = canvas_color.view(dtype=np.uint8).reshape((*canvas_color.shape, 4))
newCanvas = pygame.Surface(size, pygame.SRCALPHA)
cv2.blur(canvas_rgba, ksize=(25, 25), dst=canvas_rgba)
pygame.surfarray.blit_array(newCanvas, canvas_color)
return newCanvas
def BloomNoPremultipliedAlpha(canvas: pygame.Surface):
size = canvas.get_size()
canvas_color = pygame.surfarray.array2d(canvas)
canvas_rgba = canvas_color.view(dtype=np.uint8).reshape((*canvas_color.shape, 4))
newCanvas = pygame.Surface(size, pygame.SRCALPHA)
cv2.blur(canvas_rgba, ksize=(25, 25), dst=canvas_rgba)
canvas_rgba[:,:,0:3] = canvas_rgba[:,:,0:3] * 255.0 / canvas_rgba[:,:,[3,3,3]]
pygame.surfarray.blit_array(newCanvas, canvas_color)
return newCanvas
pygame.init()
window = pygame.display.set_mode((800, 300))
clock = pygame.time.Clock()
background = pygame.Surface(window.get_size())
ts, w, h, c1, c2 = 100, *window.get_size(), (160, 160, 160), (96, 96, 96)
tiles = [((x*ts, y*ts, ts, ts), c1 if (x+y) % 2 == 0 else c2) for x in range((w+ts-1)//ts) for y in range((h+ts-1)//ts)]
[pygame.draw.rect(background, color, rect) for rect, color in tiles]
surface = pygame.Surface((250, 250), pygame.SRCALPHA)
pygame.draw.circle(surface, (255, 255, 255), surface.get_rect().center, 100)
surface1 = Bloom(surface)
surface2 = Bloom(surface)
surface3 = BloomNoPremultipliedAlpha(surface)
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window.blit(background, (0, 0))
window.blit(surface1, surface1.get_rect(center = (150, 150)))
window.blit(surface2, surface2.get_rect(center = (400, 150)), special_flags = pygame.BLEND_PREMULTIPLIED)
window.blit(surface3, surface1.get_rect(center = (650, 150)))
pygame.display.flip()
clock.tick(60)
pygame.quit()
exit()
我在 python 上有这段代码,我在我的游戏中使用它作为 Bloom 效果,但我注意到它在粒子周围有这个奇怪的黑色阴影
效果是这样的^
大家可以看到,颗粒上有一些阴影,白底很明显,灰底则很细微
我想知道有没有办法remove/reduce这个奇怪的效果
这是绽放的代码(阴影来自哪里):
def Bloom(canvas: pygame.Surface):
size = canvas.get_size()
canvas_color = pygame.surfarray.array2d(canvas)
canvas_rgba = canvas_color.view(dtype=np.uint8).reshape((*canvas_color.shape, 4))
newCanvas = pygame.Surface(size, pygame.SRCALPHA)
cv2.blur(canvas_rgba, ksize=(9, 9), dst=canvas_rgba)
pygame.surfarray.blit_array(newCanvas, canvas_color)
return newCanvas
任何帮助都会很棒:3
编辑:删除了黑色背景的图像(没有理由在那里)
问题不在于“绽放”算法,而在于你 blit
表面到目标的方式。
不仅 alpha 通道模糊,颜色通道也模糊。因此你必须 blit
带有特殊标志 BLEND_PREMULTIPLIED
:
bloom_surf = Bloom(source_surf)
screen.blit(bloom_surf, (x, y), pygame.BLEND_PREMULTIPLIED)
也可以在 Bloom
函数中通过将颜色通道除以 alpha 通道来取消此效果:
r' = r / a
g' = g / a
b' = b / a
a' = a
每个颜色通道都在 [0, 255] 范围内的一个字节中编码。这使得转换有点棘手:
def BloomNoPremultipliedAlpha(canvas: pygame.Surface):
size = canvas.get_size()
canvas_color = pygame.surfarray.array2d(canvas)
canvas_rgba = canvas_color.view(dtype=np.uint8).reshape((*canvas_color.shape, 4))
newCanvas = pygame.Surface(size, pygame.SRCALPHA)
cv2.blur(canvas_rgba, ksize=(25, 25), dst=canvas_rgba)
canvas_rgba[:,:,0:3] = canvas_rgba[:,:,0:3] * 255.0 / canvas_rgba[:,:,[3,3,3]]
pygame.surfarray.blit_array(newCanvas, canvas_color)
return newCanvas
请参阅以下演示差异的最小示例:
左:Bloom
;中心:Bloom
+ BLEND_PREMULTIPLIED
;右:BloomNoPremultipliedAlpha
import pygame, cv2
import numpy as np
def Bloom(canvas: pygame.Surface):
size = canvas.get_size()
canvas_color = pygame.surfarray.array2d(canvas)
canvas_rgba = canvas_color.view(dtype=np.uint8).reshape((*canvas_color.shape, 4))
newCanvas = pygame.Surface(size, pygame.SRCALPHA)
cv2.blur(canvas_rgba, ksize=(25, 25), dst=canvas_rgba)
pygame.surfarray.blit_array(newCanvas, canvas_color)
return newCanvas
def BloomNoPremultipliedAlpha(canvas: pygame.Surface):
size = canvas.get_size()
canvas_color = pygame.surfarray.array2d(canvas)
canvas_rgba = canvas_color.view(dtype=np.uint8).reshape((*canvas_color.shape, 4))
newCanvas = pygame.Surface(size, pygame.SRCALPHA)
cv2.blur(canvas_rgba, ksize=(25, 25), dst=canvas_rgba)
canvas_rgba[:,:,0:3] = canvas_rgba[:,:,0:3] * 255.0 / canvas_rgba[:,:,[3,3,3]]
pygame.surfarray.blit_array(newCanvas, canvas_color)
return newCanvas
pygame.init()
window = pygame.display.set_mode((800, 300))
clock = pygame.time.Clock()
background = pygame.Surface(window.get_size())
ts, w, h, c1, c2 = 100, *window.get_size(), (160, 160, 160), (96, 96, 96)
tiles = [((x*ts, y*ts, ts, ts), c1 if (x+y) % 2 == 0 else c2) for x in range((w+ts-1)//ts) for y in range((h+ts-1)//ts)]
[pygame.draw.rect(background, color, rect) for rect, color in tiles]
surface = pygame.Surface((250, 250), pygame.SRCALPHA)
pygame.draw.circle(surface, (255, 255, 255), surface.get_rect().center, 100)
surface1 = Bloom(surface)
surface2 = Bloom(surface)
surface3 = BloomNoPremultipliedAlpha(surface)
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window.blit(background, (0, 0))
window.blit(surface1, surface1.get_rect(center = (150, 150)))
window.blit(surface2, surface2.get_rect(center = (400, 150)), special_flags = pygame.BLEND_PREMULTIPLIED)
window.blit(surface3, surface1.get_rect(center = (650, 150)))
pygame.display.flip()
clock.tick(60)
pygame.quit()
exit()