功能简介:通过拖动鼠标实现指定区域水印或是斑点的去除。

实现原理:利用opencv鼠标操作setMouseCallback函数框选(左上到右下)需要处理的区域,按下鼠标开始选中,松开鼠标结束,对选中区域进行像素替换(根据不同图像,可选不同方式),再对选中区域周围高斯滤波,平滑处理,再对整体图像双边滤波(人像可美颜,增强立体感),对图像做进一步平滑处理。


oepncv实现:

Mat  img, tmp;
Mat org = imread("D:/opencv练习图片/去水印.jpg");
Mat src = org;
Mat dst = Mat(src.size(), src.type(), CV_8UC3);
static Point pre_pt;//初始坐标 (选中区域左上角)
static Point cur_pt;//实时坐标 (选中区域右下角)
void on_mouse(int event, int x, int y, int flags, void *ustc);
int main()
{
org.copyTo(img);
org.copyTo(tmp);
namedWindow("img", WINDOW_AUTOSIZE);//定义一个img窗口
setMouseCallback("img", on_mouse);//调用回调函数
waitKey(0);
return 0;
}
void on_mouse(int event, int x, int y, int flags, void *ustc)//event鼠标事件代号,x,y鼠标坐标,flags拖拽和键盘操作的代号
{
char temp[16];//定义坐标显示字符数组
if (event == EVENT_LBUTTONDOWN)//左键按下,读取初始坐标
{
//获取选中区域矩形左上角坐标
pre_pt = Point(x, y);
imshow("img", img);
}
else if (event == EVENT_MOUSEMOVE && !(flags & EVENT_FLAG_LBUTTON))//左键没有按下的情况下,鼠标移动
{
img.copyTo(tmp);//将img复制到临时图像tmp上,用于显示实时坐标
sprintf_s(temp, "(%d,%d)", x, y);//坐标
cur_pt = Point(x, y);//获取实时坐标
putText(tmp, temp, cur_pt, FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 0, 255));//实时显示鼠标移动的坐标
imshow("img", tmp);
}
else if (event == EVENT_MOUSEMOVE && (flags & EVENT_FLAG_LBUTTON))//左键按下时,鼠标移动,则在图像上划矩形
{
imshow("img", img);
}
else if (event == EVENT_LBUTTONUP)//左键松开,将在图像上划矩形
{
//获取实时坐标(选中区域矩形右下角)
cur_pt = Point(x, y);
//对选中区域进行像素替换,偏移2个像素,根据实际情况调节
for (int i = min(pre_pt.y, cur_pt.y); i < max(cur_pt.y, pre_pt.y); i++)
{
for (int j = min(pre_pt.x, cur_pt.x); j < max(cur_pt.x, pre_pt.x); j++)
{
src.at<Vec3b>(i, j)[0] = src.at<Vec3b>(i, j - 2)[0];
src.at<Vec3b>(i, j)[1] = src.at<Vec3b>(i, j - 2)[1];
src.at<Vec3b>(i, j)[2] = src.at<Vec3b>(i, j - 2)[2];
}
}
//对选中区域周围进行平滑处理
Mat imageroi = src(Range(pre_pt.y - 3, cur_pt.y + 3), Range(pre_pt.x - 3, cur_pt.x + 3));
GaussianBlur(imageroi, imageroi, Size(15, 15), 0, 0);
//对整体图像双边滤波(对人像有美颜效果)
bilateralFilter(src, dst, 15, 30, 9);
//保存处理后的图像(如有必要)
//imwrite("D:txa.jpg", dst);
//标记选中区域
circle(img, pre_pt, 2, Scalar(255, 0, 0, 0), -1, LINE_AA, 0);
rectangle(img, pre_pt, cur_pt, Scalar(0, 255, 0, 0), 1, 8, 0);
//显示结果
imshow("结果", dst);
}

GIF效果展示:

 几点要说:

sprintf_s是sprintf的安全版本,指定缓冲区长度来避免sprintf()存在的溢出风险,主要差在sprintf_s第二个参数,可以控制缓冲区大小。

int sprintf( char *buffer, const char *format, [ argument]  );
//buffer:char型指针,指向将要写入的字符串的缓冲区。
//format:格式化字符串。(%d 是格式化为整型 %s 是格式化为字符串 )
//[argument]:可选参数,可以是任何类型的数据。 int sprintf_s(char *buffer,size_t sizeOfBuffer,const char *format,[ argument] );
//buffer:char型指针,指向将要写入的字符串的缓冲区。
//sizeOfBuffer:缓冲区大小。
//format:格式化字符串。
//[argument]:可选参数,可以是任何类型的数据。

例如:(要把x,y坐标的位置转为字符串(x,y)在图上显示)

char Txt_Point[50] = { 0 };
sprintf(Txt_Point, "(%d,%d)", x, y);
putText(image, Txt_Point, p ,FONT_HERSHEY_PLAIN, 2, Scalar(255, 255, 255), 2);

oepncv实现——图像去水印的更多相关文章

  1. iOS 高级去水印,涂鸦去水印

    目前在研究一下图像的处理,看了一下相关的软件,比如:<去水印大师>,究竟去水印是怎么处理的呢?看图分析. 一共是三个功能:快速去水印.高级去水印.涂鸦去水印 快速去水印:暂时没找到好的处理 ...

  2. ubuntu ImageMagick 图像转换工具

    ImageMagick(简称 IM)是一个支持 GPL 协议的开源免费软件包.它由一组命令行工具组成的.它可以对超过 100 种的图像格式(包括 DPX, EXR, GIF, JPEG, JPEG-2 ...

  3. 图片去水印工具:Inpaint 7.2中文专业破解版下载及使用方法

    下载地址: 点我 Inpaint 是一款可以从图片上去除不必要的物体,让您轻松摆脱照片上的水印.划痕.污渍.标志等瑕疵的实用型软件:简单说来,Inpaint 就是一款强大实用的图片去水印软件,您的图片 ...

  4. Python批量图片去水印,提高工作效率

    ​平常工作中,有时为了采用网络的一些素材,但这些素材往往被打了水印,如果我们不懂PS就无法去掉水印,或者无法批量去掉水印.这些就很影响我们的工作效率. 今天我们就一起来,用Python + OpenC ...

  5. C#中如何调整图像大小

    在本篇文章中,我将介绍如何在C#中来调整你想要的图像大小.要实现这一目标,我们可以采取以下几个步骤: 1.首先要获取你想要调整大小的图像: string path = Server.MapPath(& ...

  6. 基于window7+caffe实现图像艺术风格转换style-transfer

    这个是在去年微博里面非常流行的,在git_hub上的代码是https://github.com/fzliu/style-transfer 比如这是梵高的画 这是你自己的照片 然后你想生成这样 怎么实现 ...

  7. 超全面的.NET GDI+图形图像编程教程

    本篇主题内容是.NET GDI+图形图像编程系列的教程,不要被这个滚动条吓到,为了查找方便,我没有分开写,上面加了目录了,而且很多都是源码和图片~ (*^_^*) 本人也为了学习深刻,另一方面也是为了 ...

  8. git图像化界面GUI的使用

    GIT学习笔记 一.        基础内容 1.git是一个版本控制软件,与svn类似,特点是分布式管理,不需要中间总的服务器,可以增加很多分支. 2.windows下的git叫msysgit,下载 ...

  9. CSharpGL(24)用ComputeShader实现一个简单的图像边缘检测功能

    CSharpGL(24)用ComputeShader实现一个简单的图像边缘检测功能 效果图 这是红宝书里的例子,在这个例子中,下述功能全部登场,因此这个例子可作为使用Compute Shader的典型 ...

随机推荐

  1. C语言-字符串函数的实现(二)之strcpy

    C语言中的字符串函数有如下这些 获取字符串长度 strlen 长度不受限制的字符串函数 strcpy strcat strcmp 长度受限制的字符串函数 strncpy strncat strncmp ...

  2. 记一次go中map并发引起的事故

    错误使用map引发的血案 前言 场景复原 原因 参考 错误使用map引发的血案 前言 最近业务中,同事使用map来接收返回的结果,使用waitGroup来并发的处理执行返回的结果,结果上线之后,直接崩 ...

  3. JAVAEE_Servlet_17_关于乱码问题

    关于乱码问题 * 数据传递过程中的乱码 解释:数据传递过程中的乱码是指: 将数据从浏览器发送给服务器的时候,服务器接收到的数据是乱码的. - ISO-8859-1 是国际标准码,不支持中文编码,它兼容 ...

  4. 一文完全掌握 Go math/rand

    Go 获取随机数是开发中经常会用到的功能, 不过这个里面还是有一些坑存在的, 本文将完全剖析 Go math/rand, 让你轻松使用 Go Rand. 开篇一问: 你觉得 rand 会 panic ...

  5. ingress controller 和ingress使用实例

    ingress controller安装 k8s集群版本:1.15+ 官方文档: https://kubernetes.github.io/ingress-nginx/ 创建基础配置 kubectl ...

  6. 计算机网络-已知IP地址和子网掩码,求广播地址

    首先说结论--广播地址=该IP所在的下一跳-1 例题: 已知IP地址是192.72.20.111,子网掩码是255.255.255.224,求广播地址 要知道下一跳就需要先求出网段间隔,网段间隔=25 ...

  7. jmeter响应时间与postman响应时间为什么不一样?

    postman响应时间 是一个线程或者一个用户再者说是发送一次请求的响应时间,一般都是200ms一下: 而jmeter属于并行,就是多个用户去访问这个功能点或者接口,多个用户同时访问,就会造成压力,自 ...

  8. RF-日期时间拼接(20191024_195355)

    *** Test Cases *** testGetTime @{time}= Get Time year month day hour min sec ${sDate}= Catenate SEPA ...

  9. hdu4846 最大子正方形(dp)

    题意:       给你一个图,让你找到最大的子矩形. 思路:       之前做过一个最大子矩阵,记得当时是用三种方法做的,两种都是瓶颈法,第三种是dp,结果今天的用瓶颈吧怎么都过不去,哎!不知道为 ...

  10. OD调试程序常用断点大全

    常用断点  拦截窗口:  bp CreateWindow 创建窗口  bp CreateWindowEx(A) 创建窗口  bp ShowWindow 显示窗口  bp UpdateWindow 更新 ...