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.niftyadmin.cn/n/5253236.html

相关文章

docker配置连接harbor私有仓库

一、前言 以下分为两种情况说明docker对harbor私有仓库的访问配置&#xff0c;一种是harbor使用自建证书配置https&#xff0c;一种是使用公有证书配置https 二、docker配置 harbor使用自建证书的情况 使用自建证书对harbor进行https配置&#xff0c;docker会将该仓库识别成不…

【利用二手车数据进行可视化分析】

利用二手车数据进行可视化分析 查看原始数据去除重复数据需求分析1.统计全国总共有多少量二手车&#xff0c;用KPI图进行展示2.统计安徽总共有多少量二手车&#xff0c;用KPI图进行展示3.统计合肥总共有多少量二手车&#xff0c;用KPI图进行展示4.取最贵的10辆二手车信息&#…

vuepress-----22、其他评论方案

vuepress 支持评论 本文讲述 vuepress 站点如何集成评论系统&#xff0c;选型是 valineleancloud, 支持匿名评论&#xff0c;缺点是数据没有存储在自己手里。市面上也有其他的方案, 如 gitalk,vssue 等, 但需要用户登录 github 才能发表评论, 但 github 经常无法连接,导致体验…

Windows 安全基础——NetBIOS篇

Windows 安全基础——NetBIOS篇 1. NetBIOS简介 NetBIOS&#xff08;Network Basic Input/Output System, 网络基本输入输出系统&#xff09;是一种接入服务网络的接口标准。主机系统通过WINS服务、广播及lmhosts文件多种模式&#xff0c;把NetBIOS名解析对应的IP地址&#xf…

Linux 定时任务备份MySQL数据库

Linux 定时任务基本知识 crontab yum install crontabs &#xff08;安装 crontabs&#xff09; systemctl enable crond &#xff08;设为开机启动&#xff09; systemctl start crond&#xff08;启动crond服务&#xff09; systemctl status crond &#xff08;查看状态&a…

计算机 3.2光盘存储系统

第二节 光盘存储系统 一、认识光驱 1.组成&#xff1a;激光头组件&#xff08;核心&#xff09;、机械传动组件、数字信号处理系统及接口、面板控制系统等。 2.接口类型&#xff1a;IDE、SCSI。 3.读取方式&#xff1a; CLV恒定线速度&#xff08;纠错能力强&#xff0c;16…

Gitzip插件【Github免翻下载】

今天给大家推荐一个github下载的插件&#xff0c;平常大家下载应该无外乎就是以下两种&#xff1a; Download zip利用git clone 但是这两种各有各的弊端&#xff0c;前者一般需要科学上网才可以&#xff0c;后者下载不稳定经常中途断掉。 今天给推荐一个款浏览器插件-Gitzip.大…

Python开源项目月排行 2023年11月

#2023年11月2023年11月19日1TTS文本到语音的深度学习工具包&#xff0c;在研究和生产中经过了实战测试。TTS-Text To Speech的缩写&#xff0c;即“从文本到语音”。 它将计算机自己产生的、或外部输入的文字信息转变为可以听得懂的、流利的汉语口语&#xff08;或者其他语言语…