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

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

相关推荐
记录成长java27 分钟前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
前端青山27 分钟前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
睡觉谁叫~~~31 分钟前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust
音徽编程32 分钟前
Rust异步运行时框架tokio保姆级教程
开发语言·网络·rust
观音山保我别报错33 分钟前
C语言扫雷小游戏
c语言·开发语言·算法
小屁孩大帅-杨一凡1 小时前
java后端请求想接收多个对象入参的数据
java·开发语言
孙同学要努力1 小时前
全连接神经网络案例——手写数字识别
人工智能·深度学习·神经网络
Eric.Lee20211 小时前
yolo v5 开源项目
人工智能·yolo·目标检测·计算机视觉
m0_656974742 小时前
C#中的集合类及其使用
开发语言·c#
java1234_小锋2 小时前
使用 RabbitMQ 有什么好处?
java·开发语言