圖像保邊濾波之BEEPS濾波算法

目錄

1 簡介

2 算法原理

3 代碼實現

4 演示Demo

4.1 開發環境

4.2 功能介紹

4.3 下載地址

參考


1 簡介

????????BEEPS(Bias Elimination in Edge-Preserving Smoothing) 是一種基于偏微分方程(PDE)的邊緣保留平滑濾波算法。它能夠在平滑圖像的同時有效消除偏差(Bias),從而更好地保留邊緣和細節。BEEPS 濾波算法廣泛應用于圖像去噪、圖像增強和醫學圖像處理等領域。

2 算法原理

????????BEEPS 濾波的核心思想是通過引入偏差消除項,改進傳統的邊緣保留平滑算法(如各向異性擴散)。其數學模型基于以下偏微分方程:

\frac{\vartheta{I}}{\vartheta{t}} = div(c(|\triangledown I|)* \triangledown I) - \lambda (I-I_0)

????????其中

  • I 是圖像。

  • ?I 是圖像的梯度。

  • c(∣?I∣) 是擴散系數,控制濾波的強度。

  • \lambda是偏差消除項的權重。

  • I_0是原始圖像

????????擴散系數c(∣?I∣) 通常定義為:

c(|\triangledown I|) = \frac{1}{1+(\frac{|\triangledown I|}{k})^2}

????????或

c(|\triangledown I|) = -exp(-(\frac{|\triangledown I|}{k})^2)

????????其中,k 是一個控制邊緣敏感度的參數。

????????算法步驟:

  1. 計算圖像的梯度 ?I

  2. 根據梯度計算擴散系數 c(∣?I∣)。

  3. 使用擴散系數更新圖像像素值。

  4. 重復上述步驟,直到達到指定的迭代次數。

3 代碼實現

????????Anisotropic濾波算法的的C語言實現代碼如下

double Gaussian(int u, int v, double sigma)
{int t = -(u - v) * (u - v);return exp((double)t / sigma);
}
int BEEPSHorizontal(unsigned char* srcPtr, int width, int height, unsigned char* outData, double sigma, int c)
{unsigned char* F = (unsigned char*)malloc(sizeof(unsigned char) * width * height);int *s = (int*)malloc(sizeof(int) * width);int *v = (int*)malloc(sizeof(int) * width);int pos = 0, X = 0, Y = 0;int p = 0;memset(F, 0, width * height);memset(outData, 0, width * height);memset(s, 0, width);memset(v, 0, width);unsigned char* D = outData;for (int y = 0; y < height; y++){for (int x = 0; x < width; x++){X = width - 1 - x;Y = height - 1 - y;if (x == 0){pos = x + y * width;F[pos] = srcPtr[pos];s[0] = srcPtr[pos];p = X;pos = p + Y * width;v[p] = srcPtr[pos];D[pos] = srcPtr[pos];}else{p = x;pos = p + y * width;s[p] = (int)(10.0 * Gaussian(srcPtr[pos], F[pos - 1], sigma));F[pos] = CLIP3((((100 - s[p] * c) * srcPtr[pos] + s[p] * c * F[pos - 1]) / 100), 0, 255);p = X;pos = p + Y * width;v[p] = (int)(10.0 * Gaussian(srcPtr[pos], D[pos + 1], sigma));D[pos] = CLIP3((((100 - v[p] * c) * srcPtr[pos] + v[p] * c * D[pos + 1]) / 100), 0, 255);}}}for (int i = 0; i < height * width; i++){D[i] = CLIP3(((10 * F[i] - (10 - c) * (srcPtr[i]) + 10 * D[i]) / (10 + c)), 0, 255);}free(F);free(s);free(v);return 0;
}int BEEPSVertical(unsigned char* srcPtr, int width, int height, unsigned char* outData, double sigma, int c)
{unsigned char* F = (unsigned char*)malloc(sizeof(unsigned char) * width * height);unsigned char* D = outData;int* s = (int*)malloc(sizeof(int) * height);int* v = (int*)malloc(sizeof(int) * height);int pos = 0, X = 0, Y = 0;memset(s, 0, height);memset(v, 0, height);for (int x = 0; x < width; x++){for (int y = 0; y < height; y++){X = width - 1 - x;Y = height - 1 - y;if (y == 0){pos = x + y * width;F[pos] = srcPtr[pos];s[y] = srcPtr[pos];pos = X + Y * width;D[pos] = srcPtr[pos];v[Y] = srcPtr[pos];}else{pos = x + y * width;s[y] = (int)(10.0 * Gaussian(srcPtr[pos], F[pos - width], sigma));F[pos] = CLIP3((((100 - s[y] * c) * srcPtr[pos] + s[y] * c * F[pos - width]) / 100), 0, 255);pos = X + Y * width;v[Y] = (int)(10.0 * Gaussian(srcPtr[pos], D[pos + width], sigma));D[pos] = CLIP3((((100 - v[Y] * c) * srcPtr[pos] + v[Y] * c * D[pos + width]) / 100), 0, 255);}}}for (int i = 0; i < height*width; i++){D[i] = CLIP3(((10 * F[i] - (10 - c) * (srcPtr[i]) + 10 * D[i]) / (10 + c)), 0, 255);}free(F);free(s);free(v);return 0;
}void BEEPSProcess(unsigned char* srcPtr, int width, int height, float sigma, float c)
{float* GMAP = (float*)malloc(sizeof(float) * 256 * 256);for (int j = 0; j < 256; j++){for (int i = 0; i < 256; i++){GMAP[i + j * 256] = Gaussian(i, j, sigma);}}sigma = sigma > 50 ? 50 : sigma;sigma = sigma * sigma * 2.0f;float Lamba = 10.0f * (float)(1 - (sqrt(2.0f * c * c + 1) - 1) / (c * c));unsigned char* pSrc = srcPtr;unsigned char* hValue = (unsigned char*)malloc(sizeof(unsigned char) * width * height);unsigned char* vValue = (unsigned char*)malloc(sizeof(unsigned char) * width * height);unsigned char* dstValue = (unsigned char*)malloc(sizeof(unsigned char) * width * height);BEEPSHorizontal(pSrc, width, height, hValue, sigma, Lamba);BEEPSVertical(hValue, width, height, vValue, sigma, Lamba);BEEPSVertical(pSrc, width, height, hValue, sigma, Lamba);BEEPSHorizontal(hValue, width, height, dstValue, sigma, Lamba);for (int i = 0; i < width * height; i++){*pSrc++ = CLIP3(((vValue[i] + dstValue[i]) / 2), 0, 255);}free(hValue);free(vValue);free(dstValue);
}int mxBeepsFilter(unsigned char* srcData, int nWidth, int nHeight, int nStride, float delta, float delta_s)
{if (srcData == NULL){return 0;}if (delta == 0 || delta_s == 0)return 0;unsigned char* yData = (unsigned char*)malloc(sizeof(unsigned char) * nWidth * nHeight);unsigned char* cbData = (unsigned char*)malloc(sizeof(unsigned char) * nWidth * nHeight);unsigned char* crData = (unsigned char*)malloc(sizeof(unsigned char) * nWidth * nHeight);unsigned char* pSrc = srcData;int Y, CB, CR;unsigned char* pY = yData;unsigned char* pCb = cbData;unsigned char* pCr = crData;for (int j = 0; j < nHeight; j++){for (int i = 0; i < nWidth; i++){RGBToYCbCr(pSrc[2], pSrc[1], pSrc[0], &Y, &CB, &CR);*pY = Y;*pCb = CB;*pCr = CR;pY++;pCb++;pCr++;pSrc += 4;}}BEEPSProcess(yData, nWidth, nHeight, delta, delta_s);pSrc = srcData;pY = yData;pCb = cbData;pCr = crData;int R, G, B;for (int j = 0; j < nHeight; j++){for (int i = 0; i < nWidth; i++){YCbCrToRGB(*pY, *pCb, *pCr, &R, &G, &B);pSrc[0] = B;pSrc[1] = G;pSrc[2] = R;pY++;pCb++;pCr++;pSrc += 4;}}free(yData);free(cbData);free(crData);return 0;
}

4 演示Demo

4.1 開發環境

  • Windows 10 Pro x64

  • Visual Studio 2015

4.2 功能介紹

????????演示程序主界面如下圖所示,具有圖像讀取、顯示、保存、雙邊濾波、表面模糊、導向濾波、局部均值方差濾波、各向異性擴散濾波、Smart Blur濾波、MeanShift濾波、BEEPS濾波、處理耗時等功能

原圖

濾波效果圖

4.3 下載地址

????????開發環境:

  • Windows 10 pro x64

  • Visual Studio 2015

????????下載地址:圖像保邊濾波之BEEPS濾波算法Demo

參考

????????圖像視頻濾鏡與人像美顏美妝算法詳解. 胡耀武、譚娟、李云夕. 電子工業出版社、2020-07

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/77613.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/77613.shtml
英文地址,請注明出處:http://en.pswp.cn/web/77613.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

怎樣給MP3音頻重命名?是時候管理下電腦中的音頻文件名了

在處理大量音頻文件時&#xff0c;給這些文件起一個有意義的名字可以幫助我們更高效地管理和查找所需的內容。通過使用專業的文件重命名工具如簡鹿文件批量重命名工具&#xff0c;可以極大地簡化這一過程。本文將詳細介紹如何利用該工具對 MP3 音頻文件進行重命名。 步驟一&am…

uniapp實現統一添加后端請求Header方法

uniapp把請求寫完了&#xff0c;發現需要給接口請求添加頭部&#xff0c;每個接口去添加又很麻煩&#xff0c;uniapp可以統一添加&#xff0c;并且還能給某些接口設置不添加頭部。 一般用于添加token登錄驗證信息。 在 main.js 文件中配置。 代碼如下&#xff1a; // 在…

Qt/C++面試【速通筆記四】—Qt中的MVC模式

在軟件開發中&#xff0c;設計模式是為了讓代碼結構更加清晰、可維護和擴展的工具。MVC&#xff08;Model-View-Controller&#xff0c;模型-視圖-控制器&#xff09;模式就是其中一種經典的設計模式&#xff0c;它被廣泛應用于圖形界面&#xff08;GUI&#xff09;應用程序中。…

機器學習-入門-線性模型(2)

機器學習-入門-線性模型(2) 3.4廣義線性回歸 一般形式&#xff1a; y g ? 1 ( w T x b ) y g^{-1} \left( w^T x b \right) yg?1(wTxb) 單調可微的聯系函數 (link function) 令 g ( ? ) ln ? ( ? ) g(\cdot) \ln (\cdot) g(?)ln(?) 則得到對數線性回歸 ln ?…

Scratch——第20課 輾轉相除法/繩子算法

輾轉相除法是用于求取最大公約數時需要用到的方法&#xff0c;它還有個名字稱為繩子算法&#xff0c;這類題目只要理解輾轉相處的原理即可拿下。 一、輾轉相除法的基本原理 兩個整數的最大公約數不變&#xff0c;當較大數減去較小數后&#xff0c;得到的差值與較小數的最大公…

【Keil5-開發指南】

Keil5-編程指南 ■ Keil5 介紹■ Keil5 生成bin文件■ 新建工程后debug在 BX R0 不動了■ J-Flash 使用■ Keil5-Debug調試工具 Jlink---STLink---DAP仿真器■ Keil5 使用 AStyle插件格式化代碼■ Keil5-編譯4個階段■ Keil5-Boot和APP配置■ Keil5-報錯■ 芯片手冊區別 ■ Kei…

HarmonyOS SDK助力鴻蒙版今日水印相機,真實地址防護再升級

今日水印相機是一款真實記錄"工作"和"生活"的水印拍照APP。作為專業的可信影像服務平臺&#xff0c;今日水印相機依托時間、地點、身份三重數字水印技術&#xff0c;為企業和個人提供考勤打卡、外勤巡檢、生活美好時刻記錄等場景的可信存證服務。 面對虛擬…

WSL釋放空間

在 WSL (Windows Subsystem for Linux) 中&#xff0c;Linux 發行版可能會占用越來越多的磁盤空間&#xff0c;即使刪除文件后&#xff0c;空間也可能不會自動釋放。這是因為 WSL 使用虛擬硬盤&#xff08;VHDX 文件&#xff09;來存儲 Linux 文件系統&#xff0c;而 Windows 不…

C#核心知識

委托 如何聲明一個委托&#xff1a;通過 【delegate 返回值類型 委托名稱】 的格式來定義 如何使用一個委托&#xff1a;使用new關鍵字&#xff0c;并傳入和聲明委托的構造相同的方法名&#xff0c;比如&#xff1a;new 委托名稱(與委托的參數和返回值相同的一個方法名) 如何…

免費LUT網站

FREE LUTs | Color Lookup Tables - Presetpro.com

力扣-160.相交鏈表

題目描述 給你兩個單鏈表的頭節點 headA 和 headB &#xff0c;請你找出并返回兩個單鏈表相交的起始節點。如果兩個鏈表不存在相交節點&#xff0c;返回 null 。 圖示兩個鏈表在節點 c1 開始相交&#xff1a; 題目數據 保證 整個鏈式結構中不存在環。 注意&#xff0c;函數返…

架構風格對比

架構風格深度對比&#xff1a;從管道-過濾器到微內核 &#x1f4dc; 引言 在軟件架構設計中&#xff0c;不同的架構風格適用于不同的業務場景。本文將深入解析 7種主流架構風格&#xff0c;包括它們的核心思想、優缺點、適用場景&#xff0c;并通過對比表格和示例幫助您選擇最…

「Mac暢玩AIGC與多模態05」部署篇03 - 在 Mac 上部署本地向量化模型(Embedding Models)

一、概述 本篇介紹如何在 macOS 環境下,為 Dify 平臺部署本地向量化模型(Embedding Models),支持知識庫文檔向量化、語義檢索與智能體上下文增強。向量化模型是實現知識庫問答與 RAG(檢索增強生成)應用的基礎組件。 二、部署流程 1. 環境準備 確認 Docker Desktop 正常…

shell(3)

1.介紹 定義變量的規則 1.變量名稱可以由字母,數字和下劃線組成,但是不能以數字開頭. 5A200() 2.等號兩側不能有空格. 3.變量名稱一般習慣為大寫,這是一個規范. 2.將命令的返回值只賦給變量 1、A&#xff40;date&#xff40;反引號,運行里面的命令,并把結果返回給變量A. 注&a…

人智交互中的AI世代

人智交互中的AI世代 一、研究背景與意義 1.1 技術演進背景 人工智能技術自1956年達特茅斯會議提出概念以來&#xff0c;經歷了多次技術迭代與產業周期。2020年后&#xff0c;以大語言模型&#xff08;LLMs&#xff09;和生成式AI&#xff08;AIGC&#xff09;為代表的突破性進…

4.環境變量

目錄 1.并行與并發 2. 環境變量 2.1 舉例子 2.2 命令行參數 2.3 環境變量 1.并行與并發 并行&#xff1a;多個進程在多個CPU下分別、同時運行&#xff0c;稱為并行 并發&#xff1a;多個進程在一個CPU下采用進程切換的方式&#xff0c;在一時間段內&#xff0c;多個進程同…

Spring Boot 中使用 Feign 調用內網 IP 接口并記錄入參與出參

在微服務架構中&#xff0c;服務間的通信是常見的需求。Spring Cloud 提供的 Feign 客戶端是一個聲明式的 Web 服務客戶端&#xff0c;它使得服務間的調用變得非常簡單。然而&#xff0c;在實際開發中&#xff0c;我們可能需要調用內網 IP 地址的接口&#xff0c;并且希望記錄請…

【Java】 使用 HTTP 響應狀態碼定義web系統返回碼

系統狀態碼定義 public interface GlobalErrorCodeConstants {ErrorCode SUCCESS new ErrorCode(0, "成功");// 客戶端錯誤段 ErrorCode BAD_REQUEST new ErrorCode(400, "請求參數不正確");ErrorCode UNAUTHORIZED new ErrorCode(401, "賬號未登…

如何搭建spark yarn模式的集群

一、基礎環境準備 ?安裝JDK 1.8? 所有節點需安裝JDK并配置環境變量&#xff0c;確保JAVA_HOME正確指向安裝路徑14。?部署Hadoop集群? 安裝Hadoop&#xff08;推薦3.x版本&#xff09;&#xff0c;配置YARN資源管理器4。在yarn-site.xml中啟用資源調度&#xff1a; <pro…

python22-元組、列表、字典、集合推導式

課程&#xff1a;B站大學 記錄python學習&#xff0c;直到學會基本的爬蟲&#xff0c;使用python搭建接口自動化測試就算學會了&#xff0c;在進階webui自動化&#xff0c;app自動化 循環語句小作業 元組推導式列表推導式字典推導式實踐是檢驗真理的唯一標準 推導式 簡介 Pytho…