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核心代码

cs 复制代码
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函数的使用

cs 复制代码
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

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 运行效果

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

相关推荐
FL162386312916 小时前
[C#][winform]基于yolov8的水表读数检测与识别系统C#源码+onnx模型+评估指标曲线+精美GUI界面
开发语言·yolo·c#
weixin_4374977719 小时前
读书笔记:Context Engineering 2.0 (上)
人工智能·nlp
cnxy18819 小时前
围棋对弈Python程序开发完整指南:步骤1 - 棋盘基础框架搭建
开发语言·python
喝拿铁写前端19 小时前
前端开发者使用 AI 的能力层级——从表面使用到工程化能力的真正分水岭
前端·人工智能·程序员
goodfat19 小时前
Win11如何关闭自动更新 Win11暂停系统更新的设置方法【教程】
人工智能·禁止windows更新·win11优化工具
北京领雁科技19 小时前
领雁科技反洗钱案例白皮书暨人工智能在反洗钱系统中的深度应用
人工智能·科技·安全
落叶,听雪19 小时前
河南建站系统哪个好
大数据·人工智能·python
清月电子20 小时前
杰理AC109N系列AC1082 AC1074 AC1090 芯片停产替代及资料说明
人工智能·单片机·嵌入式硬件·物联网
Dev7z20 小时前
非线性MPC在自动驾驶路径跟踪与避障控制中的应用及Matlab实现
人工智能·matlab·自动驾驶
七月shi人20 小时前
AI浪潮下,前端路在何方
前端·人工智能·ai编程