OpenCV实现图像去水印功能(inpaint)

水印定位

需要根据图像特征获取水印的位置。

如图所示,图像左下角、右下角有水印。第一步,我们首先得定位水印所在位置。

复制代码
	Mat gray;
	cvtColor(src, gray, COLOR_BGR2GRAY);

	//图像二值化,筛选出白色区域部分
	Mat thresh;
	threshold(gray, thresh, 220, 255, THRESH_BINARY);

如图为二值化后得到的效果图。接下来,我们需要提取水印区域的像素。

复制代码
//提取图片下方的水印,制作掩模图像
    Mat mask = Mat::zeros(src.size(), CV_8U);
    int height = src.rows;
    int width = src.cols;
    int start = 0.9*height;
    //遍历图像像素,提取出水印部分像素,制作掩模图像
    for (int i = start; i < height; i++)
    {
        uchar*data = thresh.ptr<uchar>(i);
        for (int j = 0; j < width; j++)
        {
            if (data[j] == 255)
            {
                mask.at<uchar>(i, j) = 255;            
            }            
        }
    }

如图所示,至此我们已经得到水印部分的二值掩模图像。接下来,使用OpenCV 内置inpaint API进行图像像素修复。

图像修复

复制代码
 //使用inpaint进行图像修复
    Mat result;
    inpaint(src, mask, result, 1, INPAINT_NS);

如图所示,这是直接使用提取出的二值掩模进行图像修复得到的结果,可以看出效果不是很好。原因是,提取出来的掩模未能覆盖完全待修复像素。故我们需要将掩模图像进行膨胀操作,扩大掩模范围。

复制代码
    //将掩模进行膨胀,使其能够覆盖图像更大区域
    Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5));
    dilate(mask, mask, kernel);

如图为进行膨胀过后的掩模图像。这时,我们使用这张掩模图像再进行图像修复工作,得到效果如图所示。

源码

复制代码
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;

/*
void inpaint(
        InputArray src,   原图
        InputArray inpaintMask, 二进制掩模,指示要修复的像素
        OutputArray dst,  目标图像
        double inpaintRadius, 像素周围的邻域补绘。通常,如果要修复的区域很小,则使用较小的值仅产生较少模糊
        int flags     INPAINT_NS  或 INPAINT_TELEA
        )
*/

/*
图像简单水印去除:定位到水印所在位置,将水印部分提取出来制作二进制掩模图像,使用inpaint API进行图像修复
*/

int main()
{
    Mat src = imread("test.jpg");
    if (src.empty())
    {
        cout << "No Image!" << endl;
        system("pause");
        return -1;
    }

    Mat gray;
    cvtColor(src, gray, COLOR_BGR2GRAY);

    //图像二值化,筛选出白色区域部分
    Mat thresh;
    threshold(gray, thresh, 220, 255, THRESH_BINARY);

    //提取图片下方的水印,制作掩模图像
    Mat mask = Mat::zeros(src.size(), CV_8U);
    int height = src.rows;
    int width = src.cols;
    int start = 0.9*height;
    //遍历图像像素,提取出水印部分像素,制作掩模图像
    for (int i = start; i < height; i++)
    {
        uchar*data = thresh.ptr<uchar>(i);
        for (int j = 0; j < width; j++)
        {
            if (data[j] == 255)
            {
                mask.at<uchar>(i, j) = 255;            
            }            
        }
    }

    //将掩模进行膨胀,使其能够覆盖图像更大区域
    Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5));
    dilate(mask, mask, kernel);

    //使用inpaint进行图像修复
    Mat result;
    inpaint(src, mask, result, 1, INPAINT_NS);

    imshow("mask", mask);
    imshow("test", result);
    waitKey(0);
    system("pause");
    return 0;
}
相关推荐
weixin_437497773 小时前
读书笔记:Context Engineering 2.0 (上)
人工智能·nlp
喝拿铁写前端3 小时前
前端开发者使用 AI 的能力层级——从表面使用到工程化能力的真正分水岭
前端·人工智能·程序员
goodfat3 小时前
Win11如何关闭自动更新 Win11暂停系统更新的设置方法【教程】
人工智能·禁止windows更新·win11优化工具
北京领雁科技3 小时前
领雁科技反洗钱案例白皮书暨人工智能在反洗钱系统中的深度应用
人工智能·科技·安全
落叶,听雪3 小时前
河南建站系统哪个好
大数据·人工智能·python
清月电子4 小时前
杰理AC109N系列AC1082 AC1074 AC1090 芯片停产替代及资料说明
人工智能·单片机·嵌入式硬件·物联网
Dev7z4 小时前
非线性MPC在自动驾驶路径跟踪与避障控制中的应用及Matlab实现
人工智能·matlab·自动驾驶
七月shi人4 小时前
AI浪潮下,前端路在何方
前端·人工智能·ai编程
橙汁味的风4 小时前
1隐马尔科夫模型HMM与条件随机场CRF
人工智能·深度学习·机器学习
itwangyang5204 小时前
AIDD-人工智能药物设计-AI 制药编码之战:预测癌症反应,选对方法是关键
人工智能