C#图像处理OpenCV开发指南(CVStar,07)——通用滤波(Filter2D)的实例代码

1 函数定义


void Filter2D    (Mat src,
Mat dst,
int     ddepth,
InputArray     kernel,
Point     anchor = Point(-1,-1),
double     delta = 0,
int     borderType = BORDER_DEFAULT 
)        

1.1 原型

#include <opencv2/imgproc.hpp>

Convolves an image with the kernel.

使用内核对图像进行卷积。

The function applies an arbitrary linear filter to an image. In-place operation is supported. When the aperture is partially outside the image, the function interpolates outlier pixel values according to the specified border mode.

该函数将任意线性滤波器应用于图像。支持就地操作。当光圈部分位于图像之外时,该函数会根据指定的边界模式对异常像素值进行插值。

The function does actually compute correlation, not the convolution:

That is, the kernel is not mirrored around the anchor point. If you need a real convolution, flip the kernel using flip and set the new anchor to (kernel.cols - anchor.x - 1, kernel.rows - anchor.y - 1).

The function uses the DFT-based algorithm in case of sufficiently large kernels (~11 x 11 or larger) and the direct algorithm for small kernels.

1.2 参数说明 Parameters

  • src    input image. 输入图像。
  • dst    output image of the same size and the same number of channels as src. 输出与src具有相同大小和相同通道数的图像。
  • ddepth    desired depth of the destination image, see combinations 目标图像的所需深度,请参阅组合
  • kernel    convolution kernel (or rather a correlation kernel), a single-channel floating point matrix; if you want to apply different kernels to different channels, split the image into separate color planes using split and process them individually. 核卷积核(或者更确切地说是相关核)、单通道浮点矩阵;如果要将不同的内核应用于不同的通道,请使用split将图像拆分为单独的颜色平面,然后分别进行处理。
  • anchor    anchor of the kernel that indicates the relative position of a filtered point within the kernel; the anchor should lie within the kernel; default value (-1,-1) means that the anchor is at the kernel center. 所述内核的锚定锚,所述锚定锚指示所述内核内的滤波点的相对位置;锚应该位于内核内;默认值(-1,-1)表示锚点位于内核中心。
  • delta    optional value added to the filtered pixels before storing them in dst. 可选值,在将滤波像素存储在dst中之前添加到滤波像素。
  • borderType    pixel extrapolation method, see BorderTypes. BORDER_WRAP is not supported. 像素外推法,请参见BorderTypes。不支持BORDER_WRAP。


2 代码解释

2.1 核心代码


private void Filter2D(object? sender, EventArgs? e)
{
    Mat src = Cv2.ImRead(sourceImage);
    Mat dst = new Mat();
    // 自定义卷积核(通用过滤)
    InputArray arr = InputArray.Create<float>(new float[3, 3] {
        { 0, -1, 0 },
        { -1, 5, -1 },
        { 0, -1, 0 }
    });
    Cv2.Filter2D(
        src: src,
        dst: dst,
        ddepth: -1,
        kernel: arr,
        anchor: new OpenCvSharp.Point(-1, -1),
        delta: 0,
        borderType: BorderTypes.Default);

    picResult.Image = CVUtility.Mat2Bitmap(dst);
    PicAutosize(picResult);
}

通过修改 arr 卷积核矩阵,可获得不同的效果。 

2.2 Form1.cs 完整源程序

using OpenCvSharp;

#pragma warning disable CS8602

namespace Legal.Truffer.CVStar
{
    public partial class Form1 : Form
    {
        string[] ImgExtentions = {
            "*.*|*.*",
            "JPEG|*.jpg;*.jpeg",
            "GIF|*.gif",
            "PNG|*.png",
            "TIF|*.tif;*.tiff",
            "BMP|*.bmp"
        };
        private int original_width { get; set; } = 0;
        private int original_height { get; set; } = 0;
        private string sourceImage { get; set; } = "";

        Panel? panelTop { get; set; } = null;
        Panel? panelBotton { get; set; } = null;
        PictureBox? picSource { get; set; } = null;
        PictureBox? picResult { get; set; } = null;
        Button? btnLoad { get; set; } = null;
        Button? btnSave { get; set; } = null;
        Button? btnFunction { get; set; } = null;

        public Form1()
        {
            InitializeComponent();

            this.Text = "OPENCV C#编程入手教程 POWERED BY 深度混淆(CSDN.NET)";
            this.StartPosition = FormStartPosition.CenterScreen;

            GUI();
            this.Resize += FormResize;
        }

        private void FormResize(object? sender, EventArgs? e)
        {
            if (this.Width < 200) { this.Width = 320; return; }
            if (this.Height < 200) { this.Height = 320; return; }
            GUI();
        }

        private void GUI()
        {
            if (panelTop == null) panelTop = new Panel();
            panelTop.Parent = this;
            panelTop.Top = 5;
            panelTop.Left = 5;
            panelTop.Width = this.Width - 26;
            panelTop.Height = 85;
            panelTop.BorderStyle = BorderStyle.FixedSingle;
            panelTop.BackColor = Color.FromArgb(200, 200, 255);

            if (panelBotton == null) panelBotton = new Panel();
            panelBotton.Parent = this;
            panelBotton.Top = panelTop.Top + panelTop.Height + 3;
            panelBotton.Left = 5;
            panelBotton.Width = panelTop.Width;
            panelBotton.Height = this.Height - panelBotton.Top - 55;
            panelBotton.BorderStyle = BorderStyle.FixedSingle;

            if (picSource == null) picSource = new PictureBox();
            picSource.Parent = panelBotton;
            picSource.Left = 5;
            picSource.Top = 5;
            picSource.Width = (panelBotton.Width - 10) / 2;
            picSource.Height = (panelBotton.Height - 10);
            picSource.BorderStyle = BorderStyle.FixedSingle;

            if (picResult == null) picResult = new PictureBox();
            picResult.Parent = panelBotton;
            picResult.Left = picSource.Left + picSource.Width + 5;
            picResult.Top = picSource.Top;
            picResult.Width = picSource.Width;
            picResult.Height = picSource.Height;
            picResult.BorderStyle = BorderStyle.FixedSingle;

            original_width = picSource.Width;
            original_height = picSource.Height;

            if (btnLoad == null) btnLoad = new Button();
            btnLoad.Parent = panelTop;
            btnLoad.Left = 5;
            btnLoad.Top = 5;
            btnLoad.Width = 90;
            btnLoad.Height = 38;
            btnLoad.Cursor = Cursors.Hand;
            btnLoad.Text = "Load";
            btnLoad.Click += Load_Image;
            btnLoad.BackColor = Color.LightCoral;

            if (btnSave == null) btnSave = new Button();
            btnSave.Parent = panelTop;
            btnSave.Left = panelTop.Width - btnSave.Width - 25;
            btnSave.Top = btnLoad.Top;
            btnSave.Width = 90;
            btnSave.Height = 38;
            btnSave.Cursor = Cursors.Hand;
            btnSave.Text = "Save";
            btnSave.Click += Save;
            btnSave.BackColor = Color.LightCoral;

            if (btnFunction == null) btnFunction = new Button();
            btnFunction.Parent = panelTop;
            btnFunction.Left = btnLoad.Left + btnLoad.Width + 5;
            btnFunction.Top = btnLoad.Top;
            btnFunction.Width = 90;
            btnFunction.Height = 38;
            btnFunction.Cursor = Cursors.Hand;
            btnFunction.Text = "Filter2D";
            btnFunction.Click += Filter2D;
            btnFunction.BackColor = Color.LightCoral;

            PicAutosize(picSource);
            PicAutosize(picResult);
        }

        private void Load_Image(object? sender, EventArgs? e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = String.Join("|", ImgExtentions);
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                sourceImage = openFileDialog.FileName;
                picSource.Image = Image.FromFile(sourceImage);
                picResult.Image = picSource.Image;
                PicAutosize(picSource);
                PicAutosize(picResult);
            }
        }

        private void PicAutosize(PictureBox pb)
        {
            if (pb == null) return;
            if (pb.Image == null) return;
            Image img = pb.Image;
            int w = original_width;
            int h = w * img.Height / img.Width;
            if (h > original_height)
            {
                h = original_height;
                w = h * img.Width / img.Height;
            }
            pb.SizeMode = PictureBoxSizeMode.Zoom;
            pb.Width = w;
            pb.Height = h;
            pb.Image = img;
            pb.Refresh();
        }

        private void Save(object? sender, EventArgs? e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = String.Join("|", ImgExtentions);
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                picResult.Image.Save(saveFileDialog.FileName);
                MessageBox.Show("Image Save to " + saveFileDialog.FileName);
            }
        }


        private void Filter2D(object? sender, EventArgs? e)
        {
            Mat src = Cv2.ImRead(sourceImage);
            Mat dst = new Mat();
            // 自定义卷积核(通用过滤)
            InputArray arr = InputArray.Create<float>(new float[3, 3] {
                { 0, -1, 0 },
                { -1, 5, -1 },
                { 0, -1, 0 }
            });
            Cv2.Filter2D(
                src: src,
                dst: dst,
                ddepth: -1,
                kernel: arr,
                anchor: new OpenCvSharp.Point(-1, -1),
                delta: 0,
                borderType: BorderTypes.Default);

            picResult.Image = CVUtility.Mat2Bitmap(dst);
            PicAutosize(picResult);
        }

    }
}

3 运行效果

3x3的卷积核显然太小了,效果不明显。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

搜维尔科技:Varjo如何提高汽车设计和驾驶测试的生产力

增强和虚拟现实技术有助于提高汽车、航空航天、工业生产等各个领域的工人生产力。尽管这些应用程序的上下文通常相当具体&#xff0c;但其中许多用例的某些方面是通用的。 在本文中&#xff0c;我们将具体探讨基于LP-RESEARCH的LPVR操作系统的 Varjo头戴式显示器的姿态跟踪主题…

AI伦理专题报告:2023年全球人工智能伦理治理报告

今天分享的是人工智能系列深度研究报告&#xff1a;《AI伦理专题报告&#xff1a;2023年全球人工智能伦理治理报告》。 &#xff08;报告出品方&#xff1a;钛媒体&#xff09; 报告共计&#xff1a;239页 摘要 人工智能(ArtificialIntelligence)作为新一轮科技革命和产业变…

Linux(centos)学习笔记(初学)

[rootlocalhost~]#:[用户名主机名 当前所在目录]#超级管理员标识 $普通用户的标识 Ctrlshift放大终端字体 Ctrl缩小终端字体 Tab可以补全命令 Ctrlshiftc/V复制粘贴 / &#xff1a;根目录&#xff0c;Linux系统起点 ls&#xff1a; #list列出目录的内容&#xff0c;通常用户查看…

Python BeautifulSoup 选择器无法找到对应元素(异步加载导致)

文章目录 问题原因解决方案找到包含内容的 XHR 异步请求无头浏览器 个人简介 问题 使用 Python BeautifulSoup 爬取一个股吧帖子发现某个样式无法找到&#xff0c;但是在网页中确实存在这个元素&#xff1a;网页使用 document.querySelector 可以正常查找&#xff1a; 但是 Py…

Http请求(bug)——路径变量传参遇到特殊符号的问题 URL中的#,?,符号作用

前言 本篇博客分析路径变量传参遇到特殊符号的问题&#xff0c;阐述了URL中的#&#xff0c;&#xff1f;&#xff0c;&符号作用。 目录 前言引出路径变量传参遇到特殊符号的问题问题描述问题分析 URL中的 #&#xff0c;&#xff1f;&#xff0c;&符号的作用URL中# 的作…

基于深度学习yolov5行人社交安全距离监测系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介系统工作原理主要组成部分技术实现优势和特点应用场景和前景 二、功能三、系统四. 总结 一项目简介 基于深度学习 YOLOv5 的行人社交安全距离监测系统是一种…

2022年第十一届数学建模国际赛小美赛C题人类活动分类解题全过程文档及程序

2022年第十一届数学建模国际赛小美赛 C题 人类活动分类 原题再现&#xff1a; 人类行为理解的一个重要方面是对日常活动的识别和监控。可穿戴式活动识别系统可以改善许多关键领域的生活质量&#xff0c;如动态监测、家庭康复和跌倒检测。基于惯性传感器的活动识别系统用于通过…

学习记录---Kubernetes的资源指标管道-metrics api的安装部署

一、简介 Metrics API&#xff0c;为我们的k8s集群提供了一组基本的指标(资源的cpu和内存)&#xff0c;我们可以通过metrics api来对我们的pod开展HPA和VPA操作(主要通过在pod中对cpu和内存的限制实现动态扩展)&#xff0c;也可以通过kubectl top的方式&#xff0c;获取k8s中n…

近期复习三

目录 nginx.conf文件介绍 一.文件共享功能 1.清空html目录下文件并新建你要共享的文件 2.修改nginx.conf文件&#xff0c;开启autoindex功能 3.测试 二.状态模块 1.修改nginx.conf文件 2.测试 &#xff08;1&#xff09;使用刚才定义的IP/nginx_status进行访问 &#…

计算机图形图像技术(图像锐化处理与图像解析)

一、实验原理&#xff1a; 1、拓展Sobel算子锐化 void Sobel(Array src, Array dst, int ddepth, int dx, int dy, int ksize); ①参数&#xff1a;src为输入图像&#xff1b;dst为输出图像&#xff0c;大小和通道数与源图像一致&#xff0c;必要时重建&#xff1b;ddepth为目…

我把springboot项目从Java 8 升级 到了Java 17 的过程总结,愿为君提前踩坑!

项目从jdk8升级到jdk17&#xff0c;我不是为了追求java 17的新特性&#xff08;准确来说也还没有去了解有什么新特性&#xff09;&#xff0c;也不是为了准确与时俱进&#xff0c;永远走在java行列的最前端&#xff0c;纯粹因为项目需要&#xff0c;因为我们都知道&#xff0c;…

【华为数据之道学习笔记】3-1 基于数据特性的分类管理框架

华为根据数据特性及治理方法的不同对数据进行了分类定义&#xff1a;内部数据和外部数据、结构化数据和非结构化数据、元数据。其中&#xff0c;结构化数据又进一步划分为基础数据、主数据、事务数据、报告数据、观测数据和规则数据。 对上述数据分类的定义及特征描述。 分类维…

HarmonyOS学习--TypeScript语言学习(四)

注意&#xff1a;这只是我学习的笔记&#xff01;&#xff01;&#xff01; 注意&#xff1a;这只是我学习的笔记&#xff01;&#xff01;&#xff01; 注意&#xff1a;这只是我学习的笔记&#xff01;&#xff01;&#xff01; 本章目录如下&#xff1a; 一、对象 二、接口…

配置CentOS服务器以支持PHP

CentOS是一款优秀的开源服务器操作系统&#xff0c;为各种网络服务提供了强大的支持。为了使CentOS服务器能够支持PHP&#xff0c;我们需要进行一些必要的配置。下面将介绍配置CentOS服务器以支持PHP的关键步骤。 安装PHP 首先&#xff0c;需要安装PHP解释器。在CentOS上&…

[UIM]论文解读:subword Regularization: Multiple Subword Candidates

文章目录 一、完整代码二、论文解读2.1 介绍2.2 NMT2.3 Unigram language model2.4 subword 抽样2.5 效果 三、整体总结 论文&#xff1a;Subword Regularization: Improving Neural Network Translation Models with Multiple Subword Candidates 作者&#xff1a;Taku Kudo 时…

【分布式微服务专题】从单体到分布式(一、SpringCloud项目初步升级)

目录 前言阅读对象阅读导航前置知识笔记正文一、单体服务介绍二、服务拆分三、分布式微服务升级前的思考3.1 关于SpringBoot/SpringCloud的思考【有点门槛】 四、SpringCloud升级整合4.1 新建父子项目 学习总结感谢 前言 从本节课开始&#xff0c;我将自己手写一个基于SpringC…

智能优化算法应用:基于非洲秃鹫算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于非洲秃鹫算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于非洲秃鹫算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.非洲秃鹫算法4.实验参数设定5.算法结果6.参考…

docker安装及配置mysql

docker 安装mysql 下载镜像文件 下载mysql5.7版本 sudo docker pull mysql:5.7检查是否下载成功 sudo docker images2.创建实例并启动 切换到root下避免每次使用sudo 密码&#xff1a;vagrant docker run -p 3306:3306 --name mysql \ -v /mydata/mysql/log:/var/log/my…

PACS源码,医学影像传输系统源码,全院级应用,支持放射、超声、内窥镜、病理等影像科室,且具备多种图像处理及三维重建功能

​三维智能PACS系统源码&#xff0c;医学影像采集传输系统源码 PACS系统以大型关系型数据库作为数据和图像的存储管理工具&#xff0c;以医疗影像的采集、传输、存储和诊断为核心&#xff0c;集影像采集传输与存储管理、影像诊断查询与报告管理、综合信息管理等综合应用于一体的…

AI助力智慧农业,基于YOLOv4开发构建不同参数量级农田场景下庄稼作物、杂草智能检测识别系统

智慧农业随着数字化信息化浪潮的演变有了新的定义&#xff0c;在前面的系列博文中&#xff0c;我们从一些现实世界里面的所见所想所感进行了很多对应的实践&#xff0c;感兴趣的话可以自行移步阅读即可&#xff1a; 《自建数据集&#xff0c;基于YOLOv7开发构建农田场景下杂草…