去除文本边缘之字形效果(或找到图像区域的主色)

Text edge zigzag effect removal (OR finding the dominant color for a image region)

我的目标是为下图绘制文本边界框。由于这两个区域的颜色不同,所以这应该很容易。我只需要 select 匹配特定颜色值的像素来过滤掉其他文本区域和 运行 凸包检测。

但是,当我放大图像时,我注意到文本区域的边缘有锯齿形效果,所以我无法轻易找到两个颜色值(蓝色和绿色)从上图中。

我想知道有没有办法消除之字形效果以确保每个短语的颜色一致?或者有没有办法确定每个文本区域的主色?

anti-aliasing 会使颜色变亮(如果在黑色背景下则变暗),因此您可以将颜色视为受光影响。在这种情况下,我们可以使用 light-invariant 颜色空间来提取颜色。

因此首先转换为 hsv,因为它是光不变的颜色空间。由于背景可以是黑色或白色,我们将过滤掉它们(如果背景总是白色而文本可以是黑色,则您需要更改过滤以允许这样做)。

我将饱和度设为小于 80,因为这将包含白色、黑色和灰色,因为它们是唯一具有低饱和度的颜色。 (您的图像不是完全白色,它的 238 而不是 255 可能是由于 jpg 压缩)

因为我们找到了所有的黑色,白色和灰色,图像的其余部分是我们的主要颜色,所以我采取了滤镜的反面蒙版,然后为了使颜色均匀且不受光线影响,设置饱和度颜色值设为 255,这样所有颜色之间的唯一区别就是色调。我还将 bg 像素设置为 0,以便更容易找到轮廓,但这不是必需的

在此之后,你可以使用任何你想要的方法来获得不同的颜色组,我只是为色调值做了一个快速直方图,得到了 3 个峰值,但 2 个峰值靠得很近,所以它们可以作为 1 个捆绑在一起。您也许可以使用峰值查找来尝试找到峰值。可能有更好的方法来找到颜色组,但这是我很快想到的。

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask = hsv[:,:,1] < 80 # for white, gray & black
hsv[mask] = 0 # set bg pixels to 0
hsv[~mask,1:] = 255 # set fg pixels saturation and value to 255 for uniformity

colors = hsv[~mask]
z = np.bincount(colors[:,0])
print(z)

bgr = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
cv2.imshow('bgr', bgr)