【问题标题】:How to remove hidden marks from images using python opencv?如何使用 python opencv 从图像中删除隐藏标记?
【发布时间】:2020-11-18 05:49:57
【问题描述】:

我想做一个小项目来挑战我的计算机视觉和图像处理技能。我遇到了一个项目,我想从图像中删除隐藏的标记。此处隐藏是指在rgb空间中不易看到的水印,但是当您转换为hsv或其他一些空间时,标记变得可见。

这是一个例子:

BGR 空间:

HSV 空间:

我尝试了不同的方法,但能够实施一种解决方案,从图像中删除这些水印。我在这里发布这个问题是为了获得解决这个问题的不同想法。

我尝试过的:

我尝试了各种方法,但都没有奏效,共享代码可能无济于事。无需为其提供代码,我们将不胜感激伪代码、想法或任何线索。

  1. 我注意到隐藏的标记都是类似于 RGB(90,94,105) 的颜色。当我分别显示 R、G 和 B 时,我注意到水印仅在 B 通道中可见。我想如果调整/移除 B 通道中的标记并再次合并图像,可能会得到更好的结果。

代码

b,g,r = cv2.split(img)
b = b//2;
r = cv2.merge((r,g,b))
cv2.imshow("image",r)

问题:这并不能解决问题,它确实使颜色变暗了,但图像颜色也受到了干扰。

  1. 我试着在 B 频道上玩一下,看看能不能完成一些事情。

  2. 我还注意到,如果我们将图像转换为 LUV 空间,那么标记在 V 空间中是可见的。

【问题讨论】:

  • 您所说的“各种方法”是什么?这还不够。
  • 让我更新问题以详细说明。同时,您能否分享您对这个问题的看法
  • 有趣的问题。我很快就会看看这个。我目前无法。
  • 请编辑minimal reproducible example 到目前为止您的最佳解决方案。
  • 顺便说一句,如果您检查 RGB 通道,数字仅在蓝色通道上可见。我试图通过这个但无法实现

标签: python opencv image-processing watermark color-space


【解决方案1】:

这可能是一种可能的方法。基本思想是在 HSV 通道中存在可见的边缘,而这些边缘在原始图像中不存在。以下是 H、S 和 V 通道并排显示:

因此,如果我们找到原始图像中的边缘和 HSV 图像中的边缘并区分它们,水印应该会显示出来。然后可以将其用作掩码,使用 OpenCV inpaint 在原始图像中进行修复。

我只是在终端中使用 ImageMagick,但使用 OpenCVPILscikit-图片

# Detect edges visible in original image and auto-level
convert watermarked.png -colorspace gray -auto-level -canny 0x1+1%+3% -auto-level  RGB-edges.png

# Find visible edges in H, S and V colourspace, generate mean across all three and auto-level
convert watermarked.png -colorspace hsv -separate -canny 0x1+1%+3% -evaluate-sequence mean -auto-level HSV-edges.png

# Find changemask between the two sets of edges
convert RGB-edges.png HSV-edges.png -compose changemask -composite result.png

这个想法是水印现在被识别为黑色,所以在 OpenCV 中使用黑色区域(可能在形态上是封闭的)作为掩码进行修复 - 参见上面的链接。

【讨论】:

  • 我也尝试过使用这种方法,但是在寻找轮廓时的噪音不会让得到好的结果。在您的结果中也存在噪音
【解决方案2】:

我没有找到任何完全解决问题的答案。不过,我感谢大家的努力(谢谢)。 我自己做了一些事情,并想分享。它几乎没有质量损失(有点蓝色模糊),但成功地去除了水印。解决方案非常简单,但分析图像需要时间。

如果有人可以扩展这种方法并提出更好的方法,我会非常高兴

我观察到水印只在 B 空间可见(RGB 之外),在 R 和 G 空间没有水印的痕迹。

B 空间:

我还在某个地方发红,与 R 和 G 通道相比,蓝光对整体图像的贡献很小,所以这就是我决定做的事情。

充分模糊 B 通道以去除这些模式的痕迹。以下是 B 通道之后的显示方式:

最后,将图像与新的 B 通道、之前的 R 和之前的 G 通道合并。以下是 RGB 通道之后的显示方式:

使用方法的好处是痕迹消失了。

唯一的缺点是蓝色和紫色的颜色出现在黑色边缘,图像一般有点蓝色。

我的代码:

import cv2
from matplotlib import pyplot as plt
import numpy as np
img = cv2.imread("img.png")
b, g, r = cv2.split(img) # split into B,G,R spaces 
b = cv2.GaussianBlur(b, None, 8)
plt.imshow(cv2.merge((r,g,b)), cmap='gray')

【讨论】:

    【解决方案3】:

    这是您在 Python/OpenCV 中的处理的轻微变化和扩展。

    主要区别在于我使用中位数而不是模糊,并且我尝试提取黑线并将它们强加在中位数上,然后再重新组合。

    输入:

    import cv2
    import numpy as np
    
    # read image
    img = cv2.imread("cartoon_hidden_marks.png")
    
    # separate channels
    b,g,r = cv2.split(img)
    
    # median filter blue
    median = cv2.medianBlur(b, 21)
    
    # threshold blue image to extract black lines
    thresh = cv2.threshold(b, 20, 255, cv2.THRESH_BINARY)[1]
    
    # apply thresh to median
    b_new = cv2.bitwise_and(median, thresh)
    
    # combine b_new, g, b
    img_new = cv2.merge([b_new,g,r])
    
    # write results to disk
    cv2.imwrite("cartoon_hidden_marks_median.jpg", median)
    cv2.imwrite("cartoon_hidden_marks_thresh.jpg", thresh)
    cv2.imwrite("cartoon_hidden_marks_new_blue.jpg", b_new)
    cv2.imwrite("cartoon_hidden_marks_result.png", img_new)
    
    # display it
    cv2.imshow("median", median)
    cv2.imshow("thresh", thresh)
    cv2.imshow("b_new", b_new)
    cv2.imshow("img_new", img_new)
    cv2.waitKey(0)
    

    蓝色通道中位数:

    蓝色通道阈值(用于黑线):

    新的蓝色通道:

    结果:


    许多错误的蓝线现在是黑色的,但不是全部。增加阈值会得到更多的黑线,但隐藏的标记会再次出现部分。

    【讨论】:

    • 蓝色被移除,但大部分白色区域被转换为浅棕色。
    【解决方案4】:

    Python/OpenCV 中另一个简单的解决方案是简单地将绿色通道替换为蓝色通道,因为大部分绿色通道的强度分布与蓝色通道的强度分布大致相同。

    输入:

    import cv2
    import numpy as np
    
    # read image
    img = cv2.imread("cartoon_hidden_marks.png")
    
    # separate channels
    b,g,r = cv2.split(img)
    
    # combine replacing b with g
    img_new = cv2.merge([g,g,r])
    
    # write results to disk
    cv2.imwrite("cartoon_hidden_marks_result2.png", img_new)
    
    # display it
    cv2.imshow("result", img_new)
    cv2.waitKey(0)
    

    结果:

    问题是外套和绿树的颜色和质地略有不同。

    人们可能会尝试修改绿色通道图像的副本,以将均值和标准差作为蓝色通道来解决涂层问题。对于绿色树,它位于水印区域之外,因此可以使用 inRange 来掩盖绿色树的颜色,然后在绿色通道的副本中替换蓝色通道图像的树。然后重新组合修改后的绿色通道代替蓝色通道。

    【讨论】:

      【解决方案5】:

      如果您已设法隔离任何通道中的水印,您应该能够对其进行阈值化并创建二进制掩码。然后您可以使用修复来填补空白,例如:

          clean_image = cv2.inpaint(marked_image, mask_of_marks, 3, cv2.INPAINT_TELEA)
      

      【讨论】:

      • OP 没有将它们隔离出来。这就是问题的重点。
      猜你喜欢
      • 1970-01-01
      • 2020-03-07
      • 1970-01-01
      • 2018-04-23
      • 1970-01-01
      • 2020-12-05
      • 1970-01-01
      • 2018-11-16
      • 2023-03-02
      相关资源
      最近更新 更多