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

opencv - replacing part of image with another using a binary mask but aliased line prevents good result

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

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

好吧,仔细检查并查看实际像素值后,我可以看到线条是由像素值的减少表示的,而不是 pixel(x,y)=255, pixel(x+1,y )=0 且像素(x+1,y+1)=255。在figure 3 (large image) you can see the decrease of value in pixels in one row. In figure 4 you can see what I would like as a result. I do understand that that is not realistically possible since the line doesn't have that angle, but there should be a better representation that in has in figure 1 right?. The reason I need it like that is because I'm replacing part of an image with another image, and the mask represents the replaced area. I use bitwise operations to get my result. Using bitwise operations with values other than 0 or 255 result in errors and different colors etc. So I need it to be 0 or 255. Result for now in figure 5中,蓝色区域被替换(以前是红色)。如您所见,结果不是很吸引人。如果那是 'straight' 行,结果看起来会好得多。 (之后在直边上应用模糊使它看起来不错顺便说一句,但是在模糊之后阶梯运动仍然可见)。

我尝试过的:

  1. 对像素值进行阈值处理。这导致没有 LINE_AA 的 fillconvexpoly,这是合乎逻辑的,因为 f.e 的水平像素值减少。 15 个像素然后达到 0,现在从下一行开始减少,这再次导致同一行中的 15 个像素的值减少,...因此,对任何值进行阈值处理都会导致具有不同偏移量的相同结果。
  2. 形态学操作,看起来像 opening/closing/dilation/erosion 等。不适用于这些类型的线条。当我阅读它们的工作原理和用途时,也有点不合逻辑。
  3. 之后模糊了蒙版和阈值,这导致了相同的 jagged/stairwise 边缘。
  4. 扫描了几天的Whosebug,求解决办法。

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

编辑:在最终结果上使用模糊对于其中有很多步骤的线条效果很好,f.e。每 2 或 3 个像素。来自:original. Applied blur on the edge: 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))