c#實現高斯模糊

来源:https://www.cnblogs.com/zbjuke/archive/2019/01/22/10304863.html
-Advertisement-
Play Games

說說高斯模糊 高斯模糊的理論我這裡就不太多費話了,百度下太多,都是抄來抄去。 主要用到二個函數“高斯函數” 一維形式為: 二維形式為: X,Y對應的一維二維坐標,σ表示模糊半徑(半徑* 2 + 1) / 2) 根據這二個公式獲取對應的權重。 先看二維 假設我們現在圖片中的像素點位置為(0,0) 假設 ...


說說高斯模糊

高斯模糊的理論我這裡就不太多費話了,百度下太多,都是抄來抄去。

主要用到二個函數“高斯函數”

一維形式為:

二維形式為:

X,Y對應的一維二維坐標,σ表示模糊半徑(半徑* 2 + 1) / 2)

根據這二個公式獲取對應的權重。

 

先看二維

假設我們現在圖片中的像素點位置為(0,0)

假設我們設置的模糊半徑為1,那麼對應的坐標為如下圖

它是以(0,0)這個坐標為標記,向外擴展1個像素。

接下來就是計算各個坐標的權重值,我們採用二維的高斯函數來計算,計算的代碼如下:

        /// <summary>
        /// 獲取權重
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        private double GetWeighing(int x, int y) {
            double q = (this.BlurRadius * 2 + 1) / 2; 
            return 1 / (2 * Math.PI * Math.Pow(q, 2)) * Math.Exp(-(x * x + y * y) / (2 * q * q));
        }

  this.BlurRadius 為我們設置的模糊半徑

上圖是我們計算的結果,這9個值的結果的總和為:0.779483679709388,該值不能大於1。這個時候我們要將上面的9個值 除以0.779483679709388,使他們的和為1.

 除以0.779483679709388之後為:

假設這9個點上的RGB顏色值中的R值乘以上圖矩陣中的值,如下圖

 

計算之後的顏色值

 

求和為:112.14236039551

所以(0,0)坐標的RGB顏色值中的R為112.14236039551

然後我們獲取這9個點的坐標RGB值,讓後將RGB值分別乘以權重值,然和將這9個值相加得到最後的顏色值。

 

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;

namespace NetShadow {
    /// <summary>
    /// 高斯模糊
    /// </summary>
    public class GaussianBlur {
        /// <summary>
        /// 模糊半徑
        /// </summary>
        public int BlurRadius { get; private set; }
        private Bitmap SourceImage { get; set; }
        private List<double> BlurArray { get; set; }
        private int MaxWidth { get; set; }
        private int MaxHeight { get; set; }

        public GaussianBlur(int blurRadius) {
            BlurArray = new List<double>();
            this.BlurRadius = blurRadius;
            this.SetBlurArray();
        }

        /// <summary>
        /// 設置需要模糊的圖片
        /// </summary>
        /// <param name="img"></param>
        public void SetSourceImage(Image img) {
            this.SourceImage = (Bitmap)img;
            this.MaxWidth = this.SourceImage.Width - 1;
            this.MaxHeight = this.SourceImage.Height - 1;
        }

        /// <summary>
        /// 獲取模糊之後的圖片
        /// </summary>
        /// <returns></returns>
        public Bitmap GetBlurImage() {
            if (this.SourceImage == null) return null;
            Bitmap newImage = new Bitmap(SourceImage.Width, SourceImage.Height);
            for (int y = 0; y < this.SourceImage.Height; y++) {
                for (int x = 0; x < this.SourceImage.Width; x++) {
                    var nC = GetBlurColor(x, y);
                    //return null;
                    newImage.SetPixel(x, y, nC);
                }
            }
            return newImage;
        }

        /// <summary>
        /// 獲取高斯模糊的顏色值
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        private Color GetBlurColor(int x, int y) {
            double r = 0, g = 0 , b = 0;
            int index = 0;
            for (var t = y - this.BlurRadius; t <= y + this.BlurRadius; t++) {
                for (var l = x - this.BlurRadius; l <= x + this.BlurRadius; l++) {
                    var color = GetDefautColor(l, t);
                    var weighValue = BlurArray[index];
                    r += color.R * weighValue;
                    g += color.G * weighValue;
                    b += color.B * weighValue;
                    index++;
                }
            }
            return Color.FromArgb((byte)r, (byte)g, (byte)b);
        }

        private Color GetDefautColor(int x, int y) {
            if (x < 0 && y < 0)
                return this.SourceImage.GetPixel(0, 0);
            else if (x < 0)
                return this.SourceImage.GetPixel(0, Math.Min(MaxHeight, y));
            else if (y < 0)
                return this.SourceImage.GetPixel(Math.Min(MaxWidth, x), 0);
            else
                return this.SourceImage.GetPixel(Math.Min(MaxWidth, x), Math.Min(MaxHeight, y));
        }

        private void SetBlurArray() {
            int blur = this.BlurRadius;
            double sum = 0;
            for (var y = blur; y >= blur * -1; y--) {
                for (var x = blur * -1; x <= blur; x++) {                    
                    var d = GetWeighing(x, y);
                    this.BlurArray.Add(d);
                    sum += d;
                }
            }
            for (var i = 0; i < this.BlurArray.Count; i++)
                this.BlurArray[i] = this.BlurArray[i] / sum;

            //sum = 0;
            //foreach (var item in this.BlurArray)
            //    sum += item;
        }

        /// <summary>
        /// 獲取權重
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        private double GetWeighing(int x, int y) {
            double q = (this.BlurRadius * 2 + 1) / 2; 
            return 1 / (2 * Math.PI * Math.Pow(q, 2)) * Math.Exp(-(x * x + y * y) / (2 * q * q));
        }
    }
}

  

 這種效率其實很地下,所以網上的解決辦法是將二維高斯改為一維高斯來計算,也就是先橫向模糊,然後再縱向模糊。

另外獲取圖片的RGB顏色值採用的是GetPixel 和SetPixel,這二個函數的效率是很低下的,大家可以到網上找下相關的解決辦法。

 源碼下載


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一.編寫併發布WebService服務 1.新建空web應用程式 2.右鍵項目解決方案-添加-新建項-選擇web服務 添加完成如下: 3.可以看到實例代碼里有這一行註釋,請取消註釋,因為我們要使用ajax來調用webservice // [System.Web.Script.Services.Scr ...
  • 公司項目最近出現獲取訪問功能變數名稱、埠、IP錯誤現象,通過排查發現, 之前項目一直通過Nginx自定義Headers信息來獲取,但最近運維人員失誤操作造成自定義Header信息丟失,造成項目拿不到對應的數據。思前想後,想找找官方有沒有關於此類問題通用標準化的解決方案。 一、Nginx配置如下: 二、.N ...
  • 登錄界面的搭建還是比較簡單的,雖然有點簡陋,但能用的姑且當做好的吧,如下圖: 這裡使用的是DevExpress控制項,其中值得一看的就是使用LayoutControl控制項來進行TextEdit控制項的佈局。對於一般幾個TextEdit併排的佈局而言,使用這個控制項的效果還是不錯的。 既然涉及到了系統的登錄 ...
  • FileUpload在HTML中是個常用的基礎控制項,在涉及到上傳各種格式的文件時候都會用到;筆者前段時間正好用到它做上傳功能,記錄下來做一些累積, 前端到後臺用的是的Jquery中的Ajax進行數據傳輸,在後臺的邏輯處理中以HttpPostedFileBase的對象調用SaveAs(ServerSa ...
  • C# 實體類轉json數據過濾掉欄位為null的欄位 語法如下: var jsonSetting = new JsonSerializerSettings {NullValueHandling = NullValueHandling.Ignore}; var json = JsonConvert.S ...
  • 上一篇我們用jenkins做了一個簡單的自動化發佈,在shell中採用的是 BUILD_ID=dontKillMe nohup dotnet xxx.dll & 這種簡單的後臺承載,如果你的業務 量相對比較小,可以用這個方法玩一玩,但存在二個問題:1. 無法對進程進行批量或者可視化管理。 2. 單機 ...
  • 1、新建ASP.NET Core Web應用程式 2、從NuGet下載安裝以下工具包 Microsoft.EntityFrameworkCore Microsoft.EntityFrameworkCore.SqlServer Microsoft.EntityFrameworkCore.Tools M ...
  • 在講一致性Hash之前我們先來討論一個問題。 問題:現在有億級用戶,每日產生千萬級訂單,如何將訂單進行分片分表? 小A:我們可以按照手機號的尾數進行分片,同一個尾數的手機號寫入同一片/同一表中。 大佬:我希望通過會員ID來查詢這個會員的所有訂單信息,按照手機號分片/分表的話,前提是需要該用戶的手機號 ...
一周排行
    -Advertisement-
    Play Games
  • Timer是什麼 Timer 是一種用於創建定期粒度行為的機制。 與標準的 .NET System.Threading.Timer 類相似,Orleans 的 Timer 允許在一段時間後執行特定的操作,或者在特定的時間間隔內重覆執行操作。 它在分散式系統中具有重要作用,特別是在處理需要周期性執行的 ...
  • 前言 相信很多做WPF開發的小伙伴都遇到過表格類的需求,雖然現有的Grid控制項也能實現,但是使用起來的體驗感並不好,比如要實現一個Excel中的表格效果,估計你能想到的第一個方法就是套Border控制項,用這種方法你需要控制每個Border的邊框,並且在一堆Bordr中找到Grid.Row,Grid. ...
  • .NET C#程式啟動閃退,目錄導致的問題 這是第2次踩這個坑了,很小的編程細節,容易忽略,所以寫個博客,分享給大家。 1.第一次坑:是windows 系統把程式運行成服務,找不到配置文件,原因是以服務運行它的工作目錄是在C:\Windows\System32 2.本次坑:WPF桌面程式通過註冊表設 ...
  • 在分散式系統中,數據的持久化是至關重要的一環。 Orleans 7 引入了強大的持久化功能,使得在分散式環境下管理數據變得更加輕鬆和可靠。 本文將介紹什麼是 Orleans 7 的持久化,如何設置它以及相應的代碼示例。 什麼是 Orleans 7 的持久化? Orleans 7 的持久化是指將 Or ...
  • 前言 .NET Feature Management 是一個用於管理應用程式功能的庫,它可以幫助開發人員在應用程式中輕鬆地添加、移除和管理功能。使用 Feature Management,開發人員可以根據不同用戶、環境或其他條件來動態地控制應用程式中的功能。這使得開發人員可以更靈活地管理應用程式的功 ...
  • 在 WPF 應用程式中,拖放操作是實現用戶交互的重要組成部分。通過拖放操作,用戶可以輕鬆地將數據從一個位置移動到另一個位置,或者將控制項從一個容器移動到另一個容器。然而,WPF 中預設的拖放操作可能並不是那麼好用。為瞭解決這個問題,我們可以自定義一個 Panel 來實現更簡單的拖拽操作。 自定義 Pa ...
  • 在實際使用中,由於涉及到不同編程語言之間互相調用,導致C++ 中的OpenCV與C#中的OpenCvSharp 圖像數據在不同編程語言之間難以有效傳遞。在本文中我們將結合OpenCvSharp源碼實現原理,探究兩種數據之間的通信方式。 ...
  • 一、前言 這是一篇搭建許可權管理系統的系列文章。 隨著網路的發展,信息安全對應任何企業來說都越發的重要,而本系列文章將和大家一起一步一步搭建一個全新的許可權管理系統。 說明:由於搭建一個全新的項目過於繁瑣,所有作者將挑選核心代碼和核心思路進行分享。 二、技術選擇 三、開始設計 1、自主搭建vue前端和. ...
  • Csharper中的表達式樹 這節課來瞭解一下表示式樹是什麼? 在C#中,表達式樹是一種數據結構,它可以表示一些代碼塊,如Lambda表達式或查詢表達式。表達式樹使你能夠查看和操作數據,就像你可以查看和操作代碼一樣。它們通常用於創建動態查詢和解析表達式。 一、認識表達式樹 為什麼要這樣說?它和委托有 ...
  • 在使用Django等框架來操作MySQL時,實際上底層還是通過Python來操作的,首先需要安裝一個驅動程式,在Python3中,驅動程式有多種選擇,比如有pymysql以及mysqlclient等。使用pip命令安裝mysqlclient失敗應如何解決? 安裝的python版本說明 機器同時安裝了 ...