需要根据图像特征获取水印的位置。
如图所示,图像左下角、右下角有水印。第一步,我们首先得定位水印所在位置。
- 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;
- }