opencv - 使用二进制掩码将部分图像替换为另一个图像,但别名行会阻止良好的结果

问题描述

我正在 Python 中的 openCV 中处理二进制掩码,并使用 fillConvexpoly 创建了一个。第一个结果可以在 figure 1 中看到。如您所见,边缘并不光滑,而是看起来像楼梯。

所以我在fillconvexpoly中使用了抗锯齿标志,也就是cv2.LINE_AA。结果看起来很有希望,正如您在 figure 2 中看到的那样。问题是在按位运算中使用此掩码会导致错误。为什么?

好吧,经过仔细检查并查看实际像素值,我可以看到该线由像素值的减少而不是 pixel(x,y)=255,pixel(x+1,y)= 表示0 和像素 (x+1,y+1)=255。在 figure 3(大图)中,您可以看到一行中像素值的减少。在 figure 4 中,您可以看到我想要的结果。我确实理解这在现实中是不可能的,因为线没有那个角度,但应该有一个更好的表示,如图 1 所示,对吧?。我需要它的原因是因为我用另一个图像替换了图像的一部分,而蒙版代表了被替换的区域。我使用按位运算来得到我的结果。使用 0 或 255 以外的值的按位运算会导致错误和不同的颜色等。所以我需要它是 0 或 255。现在结果在 figure 5 中,蓝色区域被替换(曾经是红色) .如您所见,结果不是很有吸引力。如果那是一条“直线”,结果看起来会更好。 (之后在直边上应用模糊使其看起来不错顺便说一句,但模糊后楼梯运动仍然可见)。

我尝试过的:

  1. 阈值像素值。这导致没有 LINE_AA 的 fillconvexpoly,这是合乎逻辑的,因为 f.e. 的水平像素值会减少。 15 个像素然后达到 0,现在从下一行开始减少,这再次导致同一行中 15 个像素的值减少,......因此对任何值进行阈值处理都会导致具有不同偏移的相同结果。立>
  2. 形态学操作,看起来像开/关/膨胀/侵蚀等。不适用于这些类型的线。当我阅读它们的工作原理和用途时,也很合乎逻辑。
  3. 随后对蒙版和阈值进行模糊处理,从而产生相同的锯齿状/阶梯状边缘。
  4. 解决方案扫描了几天的 stackoverflow。

如果您对这个问题有其他建议,我很乐意听到。 提前致谢。

编辑:在最终结果上使用模糊效果对于包含很多步骤的线条效果很好,例如每 2 或 3 个像素。来自:original。在边缘应用模糊:result 但是在很长的一条线上应用这种技术,只需几个步骤:原始:参见图 5 和 result。如您所见,结果还不错,但仍然包含这种逐步模式。真的很想摆脱它。 (从下面发出的光是我以后要处理的)

解决方法

对于基于数组的权重,您可以使用等效的 addWeighted function 解决此问题。假设您有 8 位数组 imageoverlaymask,并且由于您的蒙版似乎适用于叠加层而不是基础图像,您可以执行类似的操作

import cv2
import numpy as np

... # get/read image and overlay,create mask

alpha = mask / 255 # convert to 0-1 range,could also use cv2.normalize
combined = np.uint8(overlay * alpha + image * (1 - alpha))