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;
}
相关推荐
东坡肘子几秒前
参与学生移动应用大赛有感 -- 肘子的 Swift 周报 #161
人工智能·swiftui·swift
天天被压力2 分钟前
【A股分钟级高频数据完全手册 #11】券商实时行情数据接口:实时交易(券商源)接入与字段
java·人工智能·python
唐老板7 分钟前
agent 撑爆 Git 之后,两家改的不是同一层
人工智能·ai编程
天天被压力15 分钟前
【A股分钟级高频数据完全手册 #12】股票五档盘口数据接口:买卖五档实时盘口解析
java·人工智能·python
爱敲代码的小黄8 小时前
神经网络入门指南:从 CNN、RNN 到 Attention
人工智能·面试·程序员
一只爱撸猫的程序猿9 小时前
我看着一个 AI 引擎在 14 天里,从"记忆"走进了"搜索"
人工智能·后端·架构
我登哥MVP10 小时前
DeepSeek-Harness-Super-Agent-学习笔记
人工智能·深度学习·神经网络·机器学习·自然语言处理·agent
LucianaiB10 小时前
【元宝搜索开发者征文大赛】AI时代,学得慢就不用学?用元宝搜索打造一个教程保质期,确保每一个教程符合你的现状
前端·人工智能·ai编程
冬奇Lab11 小时前
一天一个开源项目(第256篇):Anatomy —— 让 Claude 为技术概念「发明一台机器」,画成可交互的等距插画
人工智能·开源
孟郎郎12 小时前
打造一切(Craft Anything)——克隆构造世间万物
人工智能·ai·github·软件构建·开源软件