使用opencv去除水印

removing watermark using opencv

我已经使用 opencv 和 c++ 使用下面的代码从图像中删除水印。

#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <Windows.h>
#include <string>
#include <filesystem>

namespace fs = std::filesystem;

using namespace std;
using namespace cv;

int main(int argc, char** argv)
{
bool debugFlag = true;
std::string path = "C:/test/";
for (const auto& entry : fs::directory_iterator(path))
{
    std::string  fileName = entry.path().string();
    Mat original = imread(fileName, cv::IMREAD_COLOR);
    if (debugFlag) { imshow("original", original); }
    Mat inverted;
    bitwise_not(original, inverted);
    std::vector<Mat> channels;
    split(inverted, channels);

    for (int i = 0; i < 3; i++)
    {
        if (debugFlag) { imshow("chan" + std::to_string(i), channels[i]); }
    }

    Mat bwImg;
    cv::threshold(channels[2], bwImg, 50, 255, cv::THRESH_BINARY);
    if (debugFlag) { imshow("thresh", bwImg); }

    Mat outputImg;
    inverted.copyTo(outputImg, bwImg);

    bitwise_not(outputImg, outputImg);
    if (debugFlag) { imshow("output", outputImg); }

    if (debugFlag) { waitKey(0); }
    else { imwrite(fileName, outputImg); }
}
}

这是去除水印后的原始结果。

现在在上一张图片中,您可以看到原始图片有 orange/red 水印。我创建了一个可以消除水印的蒙版,然后将其应用于原始图像(这也会拉出灰色文本边界)。另一个有用的技巧是使用红色通道,因为水印在红色上最饱和 ~245)。请注意,这需要 opencv 和 c++17

但现在我想去除新图像中的水印,该图像的水印颜色与下面给出的文本图像的水印颜色相似,因为您可以在中文图像的侧面看到一些水印与文本重叠。如何使用我当前的代码实现它,我们将不胜感激。

两个尝试的想法:

1:水印看起来比正文“淡”。因此,如果您创建图像的灰度版本,您可以应用一个阈值来保留主要文本并删除水印。在将它应用到原始图像之前,您可能需要在该蒙版上添加一次膨胀,因为灰色阈值可能会稍微剪掉您的非水印字符。 (虽然这可能会从水印中引入太多噪音,所以请测试一下)

2:尝试使用opencv opening function。您的主要文本似乎比水印厚,因此您应该能够将其隔离。同样,在您为保留文本创建遮罩后,扩大一次并遮罩原始图像。