C#图像处理OpenCV开发指南(CVStar,09)——边缘识别之Scharr算法的实例代码

1 边缘识别之Scharr算法

算法文章很多,不再论述。

1.1  函数原型

void Cv2.Scharr(src,dst,ddepth,dx,dy,scale,delta,borderType)
 

1.2 参数说明

  • src 代表原始图像。
  • dst 代表目标图像。
  • ddepth 代表输出图像的深度。CV_16S
  • dx 代表x方向上的求导阶数。
  • dy 代表y方向上的求导阶数。
  • scale 代表计算导数值时所采用的缩放因子,默认情况下该值是1,是没有缩放的。
  • delta 代表加在目标图像dst上的值,该值是可选的,默认为0。
  • borderType 代表边界样式。

2 核心代码

2.1 Scharr核心代码

public partial class CVUtility
{
    /// <summary>
    /// Scharr 边缘检测
    /// </summary>
    /// <param name="src"></param>
    /// <returns></returns>
    public static Mat Scharr(Mat src)
    {
        // void Cv2.Scharr(src,dst,ddepth,dx,dy,scale,delta,borderType)
        // src 代表原始图像。
        // dst 代表目标图像。
        // ddepth 代表输出图像的深度。CV_16S
        // dx 代表x方向上的求导阶数。
        // dy 代表y方向上的求导阶数。
        // scale 代表计算导数值时所采用的缩放因子,默认情况下该值是1,是没有缩放的。
        // delta 代表加在目标图像dst上的值,该值是可选的,默认为0。
        // borderType 代表边界样式。
        Mat scharrx = new Mat();
        Cv2.Scharr(
            src: src,
            dst: scharrx,
            ddepth: MatType.CV_64F,
            xorder: 1,
            yorder: 0,
            scale: 1,
            delta: 0,
            borderType: BorderTypes.Default);
        Mat scharry = src.Scharr(MatType.CV_64F, 0, 1);
        Cv2.Scharr(
            src: src,
            dst: scharry,
            ddepth: MatType.CV_64F,
            xorder: 0,
            yorder: 1,
            scale: 1,
            delta: 0,
            borderType: BorderTypes.Default);
        Cv2.ConvertScaleAbs(scharrx, scharrx);
        Cv2.ConvertScaleAbs(scharry, scharry);
        Mat scharrxy = new Mat(scharrx.Size(), scharrx.Type());
        Cv2.AddWeighted(
            src1: scharrx,
            alpha: 0.5,
            src2: scharry,
            beta: 0.5,
            gamma: 0.0,
            dst: scharrxy,
            dtype: -1);

        return scharrxy;
    }
}

2.2 Scharr函数的使用

private void Scharr(object? sender, EventArgs? e)
{
    if (txtKSize.Text.Trim().Length < 1) { MessageBox.Show("KSize Required!"); return; }
    if (!int.TryParse(txtKSize.Text.Trim(), out int ksize)) { MessageBox.Show("Invalid KSize number!"); return; }
    if (ksize < 3 || ksize > 100) { MessageBox.Show("Invalid KSize number!"); return; }
    if ((ksize % 2) != 1) { MessageBox.Show("Odd number required for ksize!"); return; }

    Mat src = Cv2.ImRead(sourceImage);
    Mat dst = CVUtility.Scharr(src);
    picResult.Image = CVUtility.Mat2Bitmap(dst);
    PicAutosize(picResult);
}

2.3 完整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;
        Label? abKSize { get; set; } = null;
        TextBox? txtKSize { 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 = 120;
            btnFunction.Height = 38;
            btnFunction.Cursor = Cursors.Hand;
            btnFunction.Text = "Scharr";
            btnFunction.Click += Scharr;
            btnFunction.BackColor = Color.LightCoral;

            if (abKSize == null) abKSize = new Label();
            abKSize.Parent = panelTop;
            abKSize.Left = btnFunction.Left;
            abKSize.Top = btnFunction.Top + btnFunction.Height + 5;
            abKSize.Text = "KSIZE: ";

            if (txtKSize == null) txtKSize = new TextBox();
            txtKSize.Parent = panelTop;
            txtKSize.Left = abKSize.Left + abKSize.Width + 5;
            txtKSize.Top = abKSize.Top;
            txtKSize.Text = "3";

            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 Scharr(object? sender, EventArgs? e)
        {
            if (txtKSize.Text.Trim().Length < 1) { MessageBox.Show("KSize Required!"); return; }
            if (!int.TryParse(txtKSize.Text.Trim(), out int ksize)) { MessageBox.Show("Invalid KSize number!"); return; }
            if (ksize < 3 || ksize > 100) { MessageBox.Show("Invalid KSize number!"); return; }
            if ((ksize % 2) != 1) { MessageBox.Show("Odd number required for ksize!"); return; }

            Mat src = Cv2.ImRead(sourceImage);
            Mat dst = CVUtility.Scharr(src);
            picResult.Image = CVUtility.Mat2Bitmap(dst);
            PicAutosize(picResult);
        }

    }
}

3 运行效果

实际上一般都用黑白照片。

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

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

相关文章

react.js源码二

三、调度Scheduler scheduling(调度)是fiber reconciliation的一个过程&#xff0c;主要决定应该在何时做什么?在stack reconciler中&#xff0c;reconciliation是“一气呵成”&#xff0c;对于函数来说&#xff0c;这没什么问题&#xff0c;因为我们只想要函数的运行结果&…

css未来:使用light-dark()切换主题色

css未来&#xff1a;使用light-dark()切换主题色 要根据使用的是浅色模式还是深色模式来更改颜色&#xff0c;我们通常会使用 prefers-color-scheme 媒体查询。为了让代码实现变得更容易&#xff0c;CSS 现在附带了一个名为 light-dark() 的实用函数。该函数接受两个颜色值作为…

2024年顶级的9个 Android 数据恢复工具(免费和付费)

不同的事情可能会损坏您的Android手机并导致您丢失数据。但大多数时候&#xff0c;您可以使用取证工具恢复部分或全部文件。 问题可能来自手机的物理损坏、磁盘的逻辑故障、完整的系统擦除&#xff0c;或者只是简单的粗心大意。 但是&#xff0c;无论数据丢失的原因是什么&am…

从零构建属于自己的GPT系列5:模型本地化部署(文本生成函数解读、模型本地化部署、文本生成文本网页展示、代码逐行解读)

&#x1f6a9;&#x1f6a9;&#x1f6a9;Hugging Face 实战系列 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在PyCharm中进行 本篇文章配套的代码资源已经上传 从零构建属于自己的GPT系列1&#xff1a;数据预处理 从零构建属于自己的GPT系列2&#xff1a;模型训…

基于Spring+Spring boot的SpringBoot在线电子商城管理系统

SSM毕设分享 基于SpringSpring boot的SpringBoot在线电子商城管理系统 1 项目简介 Hi&#xff0c;各位同学好&#xff0c;这里是郑师兄&#xff01; 今天向大家分享一个毕业设计项目作品【基于SpringSpring boot的SpringBoot在线电子商城管理系统】 师兄根据实现的难度和等级…

【K8S in Action】服务:让客户端发现pod 并与之通信(1)

服务是一种为一组功能相同的 pod 提供单一不变的接入点的资源。当服务存在时&#xff0c;它的 IP 地址和端口不会改变。 客户端通过 IP 地址和端口号建立连接&#xff0c; 这些连接会被路由到提供该服务的任意一个 pod 上。 pod 是短暂&#xff0c;会删除增加&#xff0c;调度…

基于JavaWeb+SSM+Vue微信小程序的科创微应用平台系统的设计和实现

基于JavaWebSSMVue微信小程序的科创微应用平台系统的设计和实现 源码获取入口Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 Lun文目录 1系统概述 1 1.1 研究背景 1 1.2研究目的 1 1.3系统设计思想 1 2相关技术…

Java基础课的中下基础课04

目录 二十三、集合相关 23.1 集合 &#xff08;1&#xff09;集合的分支 23.2 List有序可重复集合 &#xff08;1&#xff09;ArrayList类 &#xff08;2&#xff09;泛型 &#xff08;3&#xff09;ArrayList常用方法 &#xff08;4&#xff09;Vector类 &#xff08;…

排序算法之六:快速排序(非递归)

快速排序是非常适合使用递归的&#xff0c;但是同时我们也要掌握非递归的算法 因为操作系统的栈空间很小&#xff0c;如果递归的深度太深&#xff0c;容易造成栈溢出 递归改非递归一般有两种改法&#xff1a; 改循环借助栈&#xff08;数据结构&#xff09; 图示算法 不是…

Zookeeper系统性学习-应用场景以及单机、集群安装

Zookeeper 是什么&#xff1f; Zookeeper 为分布式应用提供高效且可靠的分布式协调服务&#xff0c;提供了诸如统一命名服务、配置管理和分布式锁等分布式的基础服务。在解决分布式数据一致性方面&#xff0c;ZooKeeper 并没有直接采用 Paxos 算法&#xff0c;而是采用了名为 …

漏刻有时百度地图API实战开发(8)关键词输入检索获取经纬度坐标和地址

在百度地图中进行关键词输入检索时&#xff1a; 在地图页面顶部的搜索框中输入关键词。点击搜索按钮或按下回车键进行搜索。地图将显示与关键词相关的地点、商家、景点等信息。可以使用筛选和排序功能来缩小搜索范围或更改搜索结果的排序方式。点击搜索结果中的地点或商家&…

办公word-从不是第一页添加页码

总结 实际需要注意的是&#xff0c;分隔符、分节符和分页符并不是一个含义 分隔符包含其他两个&#xff1b;分页符&#xff1a;是增加一页&#xff1b;分节符&#xff1a;指将文档分为几部分。 从不是第一页插入页码1步骤 1&#xff0c;插入默认页码 自己可以测试时通过**…

linux 14网站架构 编译安装mysql数据库

目录 LNMP网站架构下载源码包mysql 下载位置 mysql 安装1.1、清理安装环境&#xff1a;1.2、创建mysql用户1.3、从官网下载tar包1.4、安装编译工具1.5、解压1.6、编译安装编译安装三部曲1.7、初始化初始化,只需要初始化一次1.8、启动mysql1.9、登录mysql1.10、systemctl启动方式…

web 前端之标签练习+知识点

目录 实现过程&#xff1a; 结果显示 1、HTML语法 2、注释标签 3、常用标签 4、新标签 5、特殊标签 6、在网页中使用视频和音频、图片 7、表格标签 8、超链接标签 使用HTML语言来实现该页面 实现过程&#xff1a; <!DOCTYPE html> <html><head>…

nlkt中BigramAssocMeasures.pmi()方法的传参和使用

这个问题找遍全网没看到详细的介绍&#xff0c;最后用读代码数学公式的方法才理解怎么用。 BigramAssocMeasures.pmi 作用&#xff1a;计算x和y的互信息&#xff08;互信息是什么我就不科普啦&#xff09; 这里有个误区刚开始我以为是计算两个词之间的依赖程度&#xff0c;但…

【Spring教程25】Spring框架实战:从零开始学习SpringMVC 之 SpringMVC入门案例总结与SpringMVC工作流程分析

目录 1.入门案例总结2. 入门案例工作流程分析2.1 启动服务器初始化过程2.2 单次请求过程 欢迎大家回到《Java教程之Spring30天快速入门》&#xff0c;本教程所有示例均基于Maven实现&#xff0c;如果您对Maven还很陌生&#xff0c;请移步本人的博文《如何在windows11下安装Mave…

java resource ‘process/qingjia.png‘ not found

resource中的资源在target中没有&#xff0c;导致报错&#xff0c;如下图所示&#xff1a; 解决办法&#xff1a;在pom文件中添加如下代码&#xff1a; 重新执行代码&#xff0c;就能在target中看到png文件了。 类似的错误参考链接&#xff1a;mybatis-plus框架报错&#x…

探索HarmonyOS_开发软件安装

随着华为推出HarmonyOS NEXT 宣布将要全面启用鸿蒙原声应用&#xff0c;不在兼容安卓应用&#xff0c; 现在开始探索鸿蒙原生应用的开发。 HarmonyOS应用开发官网 - 华为HarmonyOS打造全场景新服务 鸿蒙官网 开发软件肯定要从这里下载 第一个为微软系统(windows)&#xff0c;第…

【Linux】使用Bash和GNU Parallel并行解压缩文件

介绍 在本教程中&#xff0c;我们将学习如何使用Bash脚本和GNU Parallel实现高效并行解压缩多个文件。这种方法在处理大量文件时可以显著加快提取过程。 先决条件 确保系统上已安装以下内容&#xff1a; BashGNU Parallel 你可以使用以下命令在不同Linux系统上安装它们&am…

RF射频干扰被动型红外传感器误判分析及整改事例

1.1 什么是红外传感 测量系统是以红外线为介质&#xff0c;探测可分成为光子和热探测器。 简洁原理就是利用产生的辐射与物质相互作用后呈现出来的物理效应就是它的基本原理。 1.2 红外按方式分类 &#xff08;1&#xff09;被动型红外&#xff1a;本身不会向外界辐射任何能量…
最新文章