C# OpenCvSharp 去水印 图像修复

news2024/11/19 0:33:07

效果

项目

VS2010+.net4.0+OpenCvSharp3

 代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Drawing.Drawing2D;
using OpenCvSharp;
using OpenCvSharp.Extensions;

namespace OpenCvSharp_去水印
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        bool IsDraw;
        System.Drawing.Point StartPoint, EndPoint;
        Pen p = new Pen(Color.Red, 2);
        Bitmap originImg;
        Image finishImg;

        Pen pen = new Pen(Color.Red, 2);
        public System.Drawing.Point[] pt = new System.Drawing.Point[4];
        Font font = new Font("宋体", 12);
        SolidBrush solidBrush = new SolidBrush(Color.Red);

        Rectangle rect;

        Graphics g;

        Bitmap bmp;
        string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
        string img = "";

        Mat src;
        Mat maskROI;
        Mat mask;
        Mat dst = new Mat();
        Rect roiRect;

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = fileFilter;
            if (ofd.ShowDialog() != DialogResult.OK) return;
            img = ofd.FileName;
            var imagebyte = File.ReadAllBytes(img);
            bmp = new Bitmap(img);
            pictureBox1.Image = bmp;

            src = new Mat(img);

            g = pictureBox1.CreateGraphics();
            g.SmoothingMode = SmoothingMode.AntiAlias;  //使绘图质量最高,即消除锯齿
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.CompositingQuality = CompositingQuality.HighQuality;

            p.StartCap = LineCap.Square;
            p.EndCap = LineCap.Square;

            originImg = new Bitmap(img);
            finishImg = (Image)originImg.Clone();

        }

        private void button4_Click(object sender, EventArgs e)
        {
            pictureBox1.Image = bmp;
            originImg = new Bitmap(img);
            finishImg = (Image)originImg.Clone();
        }

        /// <summary>
        /// 鼠标左键按下
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                IsDraw = true;
                GetImagePixLocation(pictureBox1.Size, pictureBox1.Image.Size, e.Location, out StartPoint);
            }
        }

        /// <summary>
        /// 鼠标滑动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (IsDraw)
            {
                GetImagePixLocation(pictureBox1.Size, pictureBox1.Image.Size, e.Location, out EndPoint);
                finishImg = (Image)originImg.Clone();

                g = Graphics.FromImage(finishImg);
                g.SmoothingMode = SmoothingMode.AntiAlias;

                System.Drawing.Point leftTop = new System.Drawing.Point(StartPoint.X, StartPoint.Y);
                int width = Math.Abs(StartPoint.X - EndPoint.X), height = Math.Abs(StartPoint.Y - EndPoint.Y);
                if (EndPoint.X < StartPoint.X)
                    leftTop.X = EndPoint.X;
                if (EndPoint.Y < StartPoint.Y)
                    leftTop.Y = EndPoint.Y;
                rect = new Rectangle(leftTop, new System.Drawing.Size(width, height));
                g.DrawRectangle(p, rect);
                pictureBox1.Image = finishImg;
            }
        }


        private void GetImagePixLocation(System.Drawing.Size pictureBoxSize, System.Drawing.Size imageSize, System.Drawing.Point pictureBoxPoint, out System.Drawing.Point imagePoint)
        {

            imagePoint = new System.Drawing.Point(0, 0);

            double scale;

            int detalInHeight = 0;

            int detalInWidth = 0;

            if (Convert.ToDouble(pictureBoxSize.Width) / pictureBoxSize.Height > Convert.ToDouble(imageSize.Width) / imageSize.Height)
            {
                scale = 1.0 * imageSize.Height / pictureBoxSize.Height;
                detalInWidth = Convert.ToInt32((pictureBoxSize.Width * scale - imageSize.Width) / 2.0);
            }

            else
            {
                scale = 1.0 * imageSize.Width / pictureBoxSize.Width;
                detalInHeight = Convert.ToInt32((pictureBoxSize.Height * scale - imageSize.Height) / 2.0);
            }

            imagePoint.X = Convert.ToInt32(pictureBoxPoint.X * scale - detalInWidth);

            imagePoint.Y = Convert.ToInt32(pictureBoxPoint.Y * scale - detalInHeight);

        }

        /// <summary>
        /// 鼠标左键弹起
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            IsDraw = false;
            originImg = (Bitmap)finishImg;
            pictureBox1.Image = originImg;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
            this.UpdateStyles();

            //添加项:
            cBoxThresholdTypes.Items.Add(new ListItem("NS", InpaintMethod.NS));
            cBoxThresholdTypes.Items.Add(new ListItem("Telea", InpaintMethod.Telea));
      
            //设置选中项:
            cBoxThresholdTypes.SelectedIndex = 0;    //根据索引
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (pictureBox1.Image == null )
            {
                return;
            }

            if (rect == null || (rect.Width==0 && rect.Height==0))
            {
                return;
            }

            maskROI = new Mat(rect.Height, rect.Width, src.Type(), Scalar.White);
            mask = src * 0;
            roiRect = new Rect(rect.X, rect.Y, rect.Width, rect.Height);
            mask[roiRect] = maskROI;
            Cv2.CvtColor(mask, mask, ColorConversionCodes.BGR2GRAY);
            if (pictureBox2.Image != null)
            {
                pictureBox2.Image.Dispose();
            }
            pictureBox2.Image = BitmapConverter.ToBitmap(mask);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            Inpaint();
        }

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            Inpaint();
        }

        InpaintMethod inpaintMethod;
        String CommandText = "";

        void Inpaint()
        {
            if (pictureBox1.Image == null || pictureBox2.Image == null)
            {
                return;
            }

            if (rect == null || (rect.Width == 0 && rect.Height == 0))
            {
                return;
            }

            ListItem li = (ListItem)cBoxThresholdTypes.SelectedItem;
            inpaintMethod = (InpaintMethod)li.Value;

            CommandText = String.Format("Cv2.Inpaint(src, mask, dst,{0},{1})", trackBar1.Value, inpaintMethod.ToString());
            txtCommandText.Text = CommandText;

            Cv2.Inpaint(src, mask, dst, trackBar1.Value, inpaintMethod);
            if (pictureBox3.Image != null)
            {
                pictureBox2.Image.Dispose();
            }
            pictureBox3.Image = BitmapConverter.ToBitmap(dst);
        }

        private void cBoxThresholdTypes_SelectedIndexChanged(object sender, EventArgs e)
        {
            Inpaint();
        }

        
    }
}

Demo 下载​​​​​​​

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/830700.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

简单了解一下vue-router是什么

要学习vue-router就要先知道这里的路由是什么&#xff1f;为什么我们不能像原来一样直接用<a></a>标签编写链接哪&#xff1f;vue-router如何使用&#xff1f;常见路由操作有哪些&#xff1f;等等这些问题&#xff0c;就是本篇要探讨的主要问题。 vue-router是什么…

【二叉树进阶】二叉树的前中后序遍历(非递归迭代实现)

文章目录 1. 二叉树的前序遍历1.1 思路分析1.2 AC代码 2. 二叉树的中序遍历2.1 思路分析2.2 AC代码 3. 二叉树的后序遍历3.1 思路13.2 思路1AC3.3 思路23.4 思路2AC 1. 二叉树的前序遍历 题目链接: link 不用递归&#xff0c;用迭代算法如何实现对二叉树的前序遍历&#xff1f…

linux作业

1.简述静态网页和动态网页的区别 (1).程序是否在服务器端运行&#xff0c;是重要标志。 (2).编程技术不同。静态网页和动态网页主要根据网页制作的语言来区分。 (3).被搜索引擎收录情况不同。 (4).用户访问速度不同。 (5).制作和后期维护工作量不同。 2. 简述 Webl.0 和 …

嵌入式pc技术的特点有哪些?

嵌入式PC技术是将计算机硬件和软件嵌入到各种设备中的一种技术&#xff0c;它具有低功耗、高效率、小型化、易于集成等优点&#xff0c;广泛应用于工业自动化、医疗设备、电力、通信、家用电器、物联网等领域&#xff0c;成为新时代工业生产和社会生活必不可少的技术之一。 嵌入…

Python基本数据类型之散列类型详解

前言&#xff1a; python的基本数据类型可以分为三类&#xff1a;数值类型、序列类型、散列类型&#xff0c;本文主要介绍散列类型。 一、散列类型 散列类型&#xff1a;内部元素无序&#xff0c;不能通过下标取值 1&#xff09;字典&#xff08;dict&#xff09;&#xff…

SAP 特殊采购类型52简介

特殊采购类型52简介-52 直接生产/收集订单可以在物料主数据中进行设置或者在BOM中进行设置, 所谓“直接生产”,是相对于一般的“间接生产”模式而言的。在我们通常采用的计划模式下面,所有在BOM结构里面的半成品,都是在库存中作为一个整体, 可以用在任意的一个成品物料,或…

STM32 NOR_FLASH 学习

NOR FLASH FLASH是常用的&#xff0c;用于存储数据的半导体器件&#xff0c;它具有容量大&#xff0c;可重复擦写、按“扇区/块”擦除、掉电后数据可继续保存的特性。 NOR FLASH的单位是MB&#xff0c;EEPROM的单位是KB。 NM25Q128&#xff0c;是NOR FLASH的一种&#xff0c…

正则匹配img标签里面src

正则&#xff1a; (?<src\s*\s*\")\S(?\"{1})匹配效果&#xff1a;

SAP F4下拉值报错:【内部错误:表格格式】

报错截图如下&#xff1a; 解决办法&#xff1a; 事务码&#xff1a;SU3 在【参数】页签维护如下值&#xff1a; SET/GET参数标识参数值简短描述F4METHODNoActiveXActiveX/NoActiveX 维护好以上信息之后&#xff0c;就可以正常显示下拉值了

OpenHarmony ArkUI 如何调用相机

​ ArkUI调用相机和调用相册其实是一个思路&#xff0c;只用修改一个地方。 我们继续来说相机调用&#xff0c;ArkUI没办法自己获取相机&#xff0c;所以得依靠一下ohos.multimedia.camera 相机开发指导 介绍 本指导主要展示了调用相机的调用过程&#xff0c;以及调用相机的…

【Elasticsearch】学好Elasticsearch系列-Query DSL

本文已收录至Github&#xff0c;推荐阅读 &#x1f449; Java随想录 先看后赞&#xff0c;养成习惯。 点赞收藏&#xff0c;人生辉煌。 文章目录 查询上下文相关度评分&#xff1a;_score源数据&#xff1a;_source数据源过滤器全文检索match&#xff1a;匹配包含某个term的子句…

整个个人博客?想找纯html代码模板?来个手机版带菜单的首页模板“参考参考”

以前做毕业设计的时候老想找一些不掺杂后端代码的前端模板。 可是下载下来&#xff0c;不是php就是python后台的。看又看不懂&#xff0c;想换语言就必须先把里面的后台代码拿掉。 就很像买了个精装的二手房&#xff0c;白白多花了砸墙钱。 就比如&#xff0c;想做个带菜单的…

【go-zero】docker镜像直接部署API与RPC服务 如何实现注册发现?docker network 实现 go-zero 注册发现

一、场景&问题 使用docker直接部署go-zero微服务会发现API无法找到RPC服务 1、API无法发现RPC服务 用docker直接部署 我们会发现API无法注册发现RPC服务 原因是我们缺少了docker的network网桥 2、系统内查看 RPC服务运行正常API服务启动,通过docker logs 查看日志还是未…

数据库相关知识点

体系结构图&#xff1a; 体系介绍&#xff1a; Client Connectors 接入方。支持很多协议(JDBC、ODBC、.NET、PHP、Python、PERL、C 等) Management Serveices & Utilities 系统管理和控制工具&#xff0c;mysqldump、 mysql复制集群、分区管理等 Connection Pool 连接池…

【css】css位置布局position

position 属性规定应用于元素的定位方法的类型。元素其实是通过使用top、bottom、left 和 right 属性来定位的。但是&#xff0c;需要首先设置了 position 属性&#xff0c;否则这些属性将不起作用。根据不同的 position 值&#xff0c;它们的设置特点不同。 其有五个不同的位…

【禅道】禅道数据迁移,源码安装的禅道18.2迁移至docker安装的禅道18.2

docker安装禅道开源版18.2 sudo docker run --name chandao \ -p 9080:80 \ -p 3306:3306 \ --networkzentaonet \ -v /opt/docker/zentao/zentaopms:/www/zentaopms \ -v /opt/docker/zentao/mysql:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD数据库密码\ -d easysoft/zentao:1…

Reset复位电路的PCB布局布线要求

Reset复位电路的PCB布局布线要求 —来源&#xff1a;瑞芯微RK3588 PCB设计白皮书 Reset复位电路是一种用来使电路恢复到起始状态的电路设计&#xff0c;一般简单的复位电路由电容串阻电阻构成&#xff0c;再复杂点就有三级管等配合进行&#xff0c;RK3588内置复位电路&#xf…

react中hooks分享

一. HOOKS是什么 在计算机程序设计中&#xff0c;钩子一词涵盖了一系列技术&#xff0c;这些技术用来通过拦截函数调用、消息或在软件组件之间传递的事件来改变或增加操作系统、应用程序或其他软件组件的行为。处理这些被截获的函数调用、事件或消息的代码称为“hook”。 在r…

【iOS】锁

线程安全 当一个线程访问数据的时候&#xff0c;其他的线程不能对其进行访问&#xff0c;直到该线程访问完毕。简单来讲就是在同一时刻&#xff0c;对同一个数据操作的线程只有一个。而线程不安全&#xff0c;则是在同一时刻可以有多个线程对该数据进行访问&#xff0c;从而得…

LeetCode--剑指Offer75(1)

目录 题目描述&#xff1a;剑指 Offer 05. 替换空格&#xff08;简单&#xff09;题目接口解题思路1代码解题思路2代码 PS: 题目描述&#xff1a;剑指 Offer 05. 替换空格&#xff08;简单&#xff09; 请实现一个函数&#xff0c;把字符串 s 中的每个空格替换成"%20&quo…